diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.yml b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml new file mode 100644 index 00000000..1f07155a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml @@ -0,0 +1,84 @@ +name: Report a Bug +description: File a bug report +title: "[Bug] " +labels: [ "bug" ] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to report a Bug in BetterEnd! + - type: textarea + id: what-happened + attributes: + label: What happened? + description: Also tell us, what did you expect to happen? + placeholder: Tell us what you see! + value: "A bug happened!" + validations: + required: true + - type: markdown + attributes: + value: | + ## Versions + - type: input + id: bn_version + attributes: + label: BetterEnd + description: What version of BetterEnd are you running? + placeholder: 2.0.x + validations: + required: true + - type: input + id: bclib_version + attributes: + label: BCLib + description: What version of BCLib are you running? + placeholder: 2.0.x + validations: + required: true + - type: input + id: fabric_api_version + attributes: + label: Fabric API + description: What version of Fabric API is installed + placeholder: 0.5x.x + validations: + required: false + - type: input + id: fabric_loader_version + attributes: + label: Fabric Loader + description: What version of Fabric Loader do you use + placeholder: 0.14.x + validations: + required: false + - type: dropdown + id: mc_version + attributes: + label: Minecraft + description: What version of Minecraft is installed? + options: + - 1.19.1 + - 1.19 + - 1.18.2 + - 1.18.1 + - 1.18 + - Older + validations: + required: true + - type: markdown + attributes: + value: | + ## Additional Information + - type: textarea + id: logs + attributes: + label: Relevant log output + description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. + render: shell + - type: textarea + id: other_mods + attributes: + label: Other Mods + description: If you can, please supply a list of installed Mods (besides BetterEnd and BCLib). This information may already be included in the log above. + render: shell diff --git a/.github/ISSUE_TEMPLATE/SUGGEST_FROM.yml b/.github/ISSUE_TEMPLATE/SUGGEST_FROM.yml new file mode 100644 index 00000000..8b40a8bb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/SUGGEST_FROM.yml @@ -0,0 +1,18 @@ +name: Suggest a Feature or Change +description: Have a new Idea, then suggest a Feature here. +title: "[Suggestion] " +labels: ["suggestion"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to suggest a new Feature for BCLib. We appreciate your time! + - type: textarea + id: describe + attributes: + label: Description + description: Tell us your idea + placeholder: + value: + validations: + required: true \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..a49eab2f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: true \ No newline at end of file diff --git a/.gitignore b/.gitignore index 514dd716..d6f2f3b9 100644 --- a/.gitignore +++ b/.gitignore @@ -27,5 +27,10 @@ bin/ # fabric run/ +run-client/ +run-server/ output/ -*.log +*.getBlock("log") +Convert.class +ModelPart.class +libs/ diff --git a/Convert.java b/Convert.java new file mode 100644 index 00000000..77a1705d --- /dev/null +++ b/Convert.java @@ -0,0 +1,161 @@ +class ModelPart { + static java.util.ArrayList parts = new java.util.ArrayList<>(20); + final String name; + ModelPart parent = null; + boolean mirror = false; + + float x = 0, y = 0, z = 0, rx = 0, ry = 0, rz = 0; + int u = 0, v = 0; + float bx = 0, by = 0, bz = 0, ba = 0, bb = 0, bc = 0; + float scale = 1; + static int wd = 64; + static int hg = 32; + + + boolean hadBox = false; + + ModelPart(Convert c, String name) { + this(c, 0, 0, name); + + } + + ModelPart(Convert c, int u, int v, String name) { + this.name = name; + this.u = u; + this.v = v; + parts.add(this); + } + + ModelPart(int wd, int hg, int u, int v, String name) { + this.name = name; + this.u = u; + this.v = v; + ModelPart.wd = wd; + ModelPart.hg = hg; + parts.add(this); + } + + ModelPart setPos(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + return this; + } + + ModelPart setRotationAngle(float x, float y, float z) { + this.rx = x; + this.ry = y; + this.rz = z; + return this; + } + + ModelPart addChild(ModelPart p) { + p.parent = this; + return this; + } + + ModelPart texOffs(int u, int v) { + this.u = u; + this.v = v; + return this; + } + + ModelPart addBox(float x, float y, float z, float a, float b, float c) { + return addBox(x, y, z, a, b, c, 1); + } + + ModelPart addBox(float x, float y, float z, float a, float b, float c, float _d) { + bx = x; + by = y; + bz = z; + ba = a; + bb = b; + bc = c; + scale = _d; + hadBox = true; + return this; + } + + ModelPart addBox(float x, float y, float z, float a, float b, float c, float _d, boolean mirror) { + this.mirror = mirror; + bx = x; + by = y; + bz = z; + ba = a; + bb = b; + bc = c; + hadBox = true; + return this; + } + + public String toString() { + String s = ""; + String pName = parent == null ? "modelPartData" : parent.name; + if (scale != 1) { + s += "CubeDeformation deformation_" + name + " = new CubeDeformation(" + scale + "f);\n"; + } + s += "PartDefinition " + name + " = "; + s += pName + ".addOrReplaceChild(\"" + name + "\", CubeListBuilder.create()\n"; + if (this.mirror) s += ".mirror()\n"; + s += ".texOffs(" + u + ", " + v + ")"; + if (this.hadBox) { + s += "\n"; + if (scale != 1) + s += ".addBox(" + bx + "f, " + by + "f, " + bz + "f, " + ba + "f, " + bb + "f, " + bc + "f, deformation_" + name + "),\n"; + else s += ".addBox(" + bx + "f, " + by + "f, " + bz + "f, " + ba + "f, " + bb + "f, " + bc + "f),\n"; + } + else { + s += ",\n"; + } + + if (x == 0 && y == 0 && z == 0 && rx == 0 && ry == 0 && rz == 0) { + s += "PartPose.ZERO"; + } + else if (rx == 0 && ry == 0 && rz == 0) { + s += "PartPose.offset(" + x + "f, " + y + "f, " + z + "f)"; + } + else { + s += "PartPose.offsetAndRotation(" + x + "f, " + y + "f, " + z + "f, \n" + rx + "f, " + ry + "f, " + rz + "f)"; + } + s += ");"; + + return s; + } + + public static void print() { + System.out.println("public static LayerDefinition getTexturedModelData() {"); + System.out.println(" MeshDefinition modelData = new MeshDefinition();"); + System.out.println(" PartDefinition modelPartData = modelData.getRoot();"); + for (ModelPart p : parts) { + System.out.println(p); + System.out.println(); + } + System.out.println("return LayerDefinition.create(modelData, " + wd + ", " + hg + ");"); + System.out.println("}"); + + System.out.println(); + System.out.println(); + + for (ModelPart p : parts) { + String pName = p.parent == null ? "modelPart" : p.parent.name; + System.out.println(p.name + " = " + pName + ".getChild(\"" + p.name + "\");"); + } + } +} + + ModelPart.print(); + } + void setRotationAngle(ModelPart p, float x, float y, float z){ + p.setRotationAngle(x, y, z); + } + public void c (){ + float scale = 1; + ModelPart[] SHARDS = new ModelPart[4]; + SHARDS[0] = new ModelPart(16, 16, 2, 4, "SHARDS[0]").addBox(-5.0F, 1.0F, -3.0F, 2.0F, 8.0F, 2.0F); + SHARDS[1] = new ModelPart(16, 16, 2, 4, "SHARDS[1]").addBox(3.0F, -1.0F, -1.0F, 2.0F, 8.0F, 2.0F); + SHARDS[2] = new ModelPart(16, 16, 2, 4, "SHARDS[2]").addBox(-1.0F, 0.0F, -5.0F, 2.0F, 4.0F, 2.0F); + SHARDS[3] = new ModelPart(16, 16, 2, 4, "SHARDS[3]").addBox(0.0F, 3.0F, 4.0F, 2.0F, 6.0F, 2.0F); + ModelPart CORE = new ModelPart(16, 16, 0, 0, "CORE"); + CORE.addBox(-2.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F); + } +} diff --git a/LICENSE b/LICENSE index 419a3b02..9caa064f 100644 --- a/LICENSE +++ b/LICENSE @@ -19,3 +19,7 @@ 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. + +___________________________ +Some of our Assets (see LICENSE.ASSETS for a Listing) is licensed under CC BY-NC-SA 4.0 +See https://creativecommons.org/licenses/by-nc-sa/4.0/ for Details. diff --git a/LICENSE.ASSETS b/LICENSE.ASSETS new file mode 100644 index 00000000..b5b1cdd7 --- /dev/null +++ b/LICENSE.ASSETS @@ -0,0 +1,9 @@ +Some of our Assets (see List below) is licensed under CC BY-NC-SA 4.0 +See https://creativecommons.org/licenses/by-nc-sa/4.0/ for Details. + +Please use the Attribution "Team BetterX". + +The following Files are distributed under this License: + * src/main/resources/assets/betterend/textures/gui/infusion.png + * src/main/resources/assets/betterend/icon_updater.png + * src/main/resources/assets/betterend/lang/de_de.json \ No newline at end of file diff --git a/README.md b/README.md index a3ff811f..1d65e7f2 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,19 @@ -[![](https://jitpack.io/v/paulevsGitch/BetterEnd.svg)](https://jitpack.io/#paulevsGitch/BetterEnd) +[![](https://jitpack.io/v/quiqueck/BetterEnd.svg)](https://jitpack.io/#quiqueck/BetterEnd) + # Better End -Better End Mod for Fabric, MC 1.16.4 + +Better End Mod for Fabric, MC 1.19 Importing: + * Clone repo * Edit gradle.properties if necessary -* Run command line in folder: gradlew genSources eclipse (or Another-IDE-Name) +* Run command line in folder: gradlew genSources idea (or eclipse) * Import project to IDE Building: + * Clone repo * Run command line in folder: gradlew build * Mod .jar will be in ./build/libs -Mappings: -* https://modmuss50.me/fabric.html?&version=1.16.4 diff --git a/build.gradle b/build.gradle index 83414897..a0d17eb8 100644 --- a/build.gradle +++ b/build.gradle @@ -1,114 +1,123 @@ buildscript { - dependencies { - classpath 'org.kohsuke:github-api:1.114' - } + dependencies { + classpath 'org.kohsuke:github-api:1.114' + } } plugins { - id 'idea' - id 'eclipse' - id 'fabric-loom' version '0.7-SNAPSHOT' - id 'maven-publish' + id 'fabric-loom' version "${loom_version}" + id 'maven-publish' } -sourceCompatibility = JavaVersion.VERSION_1_8 -targetCompatibility = JavaVersion.VERSION_1_8 +sourceCompatibility = JavaVersion.VERSION_17 +targetCompatibility = JavaVersion.VERSION_17 archivesBaseName = project.archives_base_name version = project.mod_version group = project.maven_group +def local_bclib = findProject(':BCLib') != null repositories { maven { url "https://maven.dblsaiko.net/" } - maven { url "https://server.bbkr.space:8081/artifactory/libs-release/" } - maven { url "https://maven.fabricmc.net/" } - maven { url 'https://maven.blamejared.com' } - maven { url "https://maven.shedaniel.me/" } - maven { url 'https://jitpack.io' } + maven { url "https://maven.fabricmc.net/" } + maven { url 'https://maven.blamejared.com' } + maven { url "https://maven.shedaniel.me/" } + maven { url 'https://jitpack.io' } + maven { url 'https://maven.terraformersmc.com/releases' } + maven { url = "https://maven.terraformersmc.com/" } + maven { url "https://ladysnake.jfrog.io/artifactory/mods" } + maven { url = "https://dvs1.progwml6.com/files/maven/" } + maven { url = "https://modmaven.dev" } + flatDir { + dirs 'libs' + } +} + +loom { + accessWidenerPath = file("src/main/resources/betterend.accesswidener") + interfaceInjection { + // When enabled injected interfaces from dependecies will be applied. + enableDependencyInterfaceInjection = false + } } dependencies { - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings minecraft.officialMojangMappings() - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - - useApi "vazkii.patchouli:Patchouli:1.16.4-${project.patchouli_version}" - useApi "com.github.paulevsGitch:BCLib:${project.bclib_version}" + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings loom.officialMojangMappings() + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - useOptional "me.shedaniel:RoughlyEnoughItems:${project.rei_version}" - useOptional "me.shedaniel:RoughlyEnoughItems-api:${project.rei_version}" - //useOptional "grondag:canvas-mc116:${project.canvas_version}" -} + modApi "vazkii.patchouli:Patchouli:${project.patchouli_version}" + println "Using local BCLib: ${local_bclib}" + if (local_bclib) { + implementation(project(path: ":BCLib", configuration: 'dev')) + } else { + modImplementation "com.github.quiqueck:BCLib:${project.bclib_version}" + } + modCompileOnly "me.shedaniel:RoughlyEnoughItems-fabric:${project.rei_version}" + modCompileOnly "me.shedaniel:RoughlyEnoughItems-api-fabric:${project.rei_version}" -def useOptional(String dep) { - dependencies.modRuntime (dep) { - exclude group: "net.fabricmc.fabric-api" - exclude group: "net.fabricmc" - if (!dep.contains("me.shedaniel")) { - exclude group: "me.shedaniel" - } - } - dependencies.modCompileOnly (dep) { - exclude group: "net.fabricmc.fabric-api" - exclude group: "net.fabricmc" - if (!dep.contains("me.shedaniel")) { - exclude group: "me.shedaniel" - } - } -} + // compile against the JEI API but do not include it at runtime + modCompileOnlyApi "mezz.jei:jei-1.19-common-api:${project.jei_version}" + modCompileOnlyApi "mezz.jei:jei-1.19-fabric-api:${project.jei_version}" + // at runtime, use the full JEI jar for Fabric + //modRuntimeOnly "mezz.jei:jei-${project.minecraft_version}-fabric:${project.jei_version}" -def useApi(String dep) { - dependencies.modApi (dep) { - exclude group: "net.fabricmc.fabric-api" - exclude group: "net.fabricmc" - if (!dep.contains("me.shedaniel")) { - exclude group: "me.shedaniel" - } - } + //needed for trinkets, otherwise BetterEnd would require users to install trinkets + modApi "dev.onyxstudios.cardinal-components-api:cardinal-components-base:${project.cca_version}" + modCompileOnly "dev.emi:trinkets:${project.trinkets_version}" + modCompileOnly "dev.emi:emi:${emi_version}" + //modRuntimeOnly "dev.emi:emi:${emi_version}" } processResources { - inputs.property "version", project.version - duplicatesStrategy = 'WARN' - - from(sourceSets.main.resources.srcDirs) { - include "fabric.mod.json" - expand "version": project.version - } + println "Version: ${project.version}" + inputs.property "version", project.version + filesMatching("fabric.mod.json") { + expand "version": project.version + } } // ensure that the encoding is set to UTF-8, no matter what the system default is // this fixes some edge cases with special characters not displaying correctly // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html tasks.withType(JavaCompile) { - options.encoding = "UTF-8" + options.encoding = "UTF-8" + it.options.release = 17 } javadoc { - options.tags = ["reason"] + options.tags = ["reason"] } task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir + classifier = 'javadoc' + from javadoc.destinationDir } // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task // if it is present. // If you remove this task, sources will not be generated. task sourcesJar(type: Jar, dependsOn: classes) { - classifier = 'sources' - from sourceSets.main.allSource + classifier = 'sources' + from sourceSets.main.allSource +} + +java { + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() } jar { - from "LICENSE" + from "LICENSE" + from "LICENSE.ASSETS" } artifacts { - archives sourcesJar - archives javadocJar + archives sourcesJar + archives javadocJar } def env = System.getenv() @@ -117,42 +126,42 @@ import org.kohsuke.github.GHReleaseBuilder import org.kohsuke.github.GitHub task release(dependsOn: [remapJar, sourcesJar, javadocJar]) { - onlyIf { - env.GITHUB_TOKEN - } + onlyIf { + env.GITHUB_TOKEN + } - doLast { - def github = GitHub.connectUsingOAuth(env.GITHUB_TOKEN as String) - def repository = github.getRepository("paulevsGitch/BetterEnd") + doLast { + def github = GitHub.connectUsingOAuth(env.GITHUB_TOKEN as String) + def repository = github.getRepository("quiqueck/BetterEnd") - def releaseBuilder = new GHReleaseBuilder(repository, version as String) - releaseBuilder.name("${archivesBaseName}-${version}") - releaseBuilder.body("A changelog can be found at https://github.com/paulevsGitch/BetterEnd/commits") - releaseBuilder.commitish("master") + def releaseBuilder = new GHReleaseBuilder(repository, version as String) + releaseBuilder.name("${archivesBaseName}-${version}") + releaseBuilder.body("A changelog can be found at https://github.com/quiqueck/BetterEnd/commits") + releaseBuilder.commitish("master") - def ghRelease = releaseBuilder.create() - ghRelease.uploadAsset(file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar"), "application/java-archive"); - ghRelease.uploadAsset(file("${project.buildDir}/libs/${archivesBaseName}-${version}-sources.jar"), "application/java-archive"); - ghRelease.uploadAsset(file("${project.buildDir}/libs/${archivesBaseName}-${version}-javadoc.jar"), "application/java-archive"); - } + def ghRelease = releaseBuilder.create() + ghRelease.uploadAsset(file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar"), "application/java-archive"); + ghRelease.uploadAsset(file("${project.buildDir}/libs/${archivesBaseName}-${version}-sources.jar"), "application/java-archive"); + ghRelease.uploadAsset(file("${project.buildDir}/libs/${archivesBaseName}-${version}-javadoc.jar"), "application/java-archive"); + } } // configure the maven publication -//publishing { -// publications { -// mavenJava(MavenPublication) { -// artifact(remapJar) { -// builtBy remapJar -// } -// artifact(sourcesJar) { -// builtBy remapSourcesJar -// } -// } -// } -// -// // select the repositories you want to publish to -// repositories { -// // uncomment to publish to the local maven -// // mavenLocal() -// } -//} +publishing { + publications { + mavenJava(MavenPublication) { + artifact(remapJar) { + builtBy remapJar + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + + // select the repositories you want to publish to + repositories { + // uncomment to publish to the local maven + // mavenLocal() + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index f902a279..06f3eb4c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,21 +1,22 @@ -# Done to increase the memory available to gradle. -org.gradle.jvmargs=-Xmx2G - -# Fabric Properties -# check these on https://fabricmc.net/use -minecraft_version=1.16.5 -yarn_mappings=6 -loader_version=0.11.3 - -# Mod Properties -mod_version = 0.9.8-pre -maven_group = ru.betterend -archives_base_name = better-end - -# Dependencies -# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api -patchouli_version = 50-FABRIC -fabric_version = 0.32.9+1.16 -canvas_version = 1.0.+ -bclib_version = 0.1.38 -rei_version = 5.8.10 \ No newline at end of file +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx2G +# Fabric Properties +# check these on https://fabricmc.net/versions.html +minecraft_version=1.19 +loader_version=0.14.8 +fabric_version=0.58.0+1.19 +#Loom +loom_version=0.12-SNAPSHOT +# Mod Properties +mod_version=2.0.12 +maven_group=org.betterx.betterend +archives_base_name=better-end +# Dependencies +# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api +patchouli_version=1.19-73-FABRIC +bclib_version=2.0.20 +rei_version=9.1.500 +jei_version=11.1.0.235 +emi_version=0.3.0+1.19 +trinkets_version=3.4.0 +cca_version=5.0.0-beta.1 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 490fda85..7454180f 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 f371643e..e750102e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 2fe81a7d..1b6c7873 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,78 +17,113 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -97,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -105,79 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 9109989e..ac1b06f9 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -54,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -64,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 00000000..e8af8cfd --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,6 @@ +# From https://github.com/jitpack/jitpack.io/issues/4506#issuecomment-864562270 +before_install: + - source "$HOME/.sdkman/bin/sdkman-init.sh" + - sdk update + - sdk install java 17.0.1-tem + - sdk use java 17.0.1-tem \ No newline at end of file diff --git a/json/block/%name%.json b/json/block/%name%.json index 10f7880a..d129f585 100644 --- a/json/block/%name%.json +++ b/json/block/%name%.json @@ -1,6 +1,6 @@ { - "parent": "block/cube_all", - "textures": { - "all": "betterend:block/%name%" - } + "parent": "block/cube_all", + "textures": { + "all": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/block/%name%_brick_half_slab.json b/json/block/%name%_brick_half_slab.json index 4a5be990..0db32a8f 100644 --- a/json/block/%name%_brick_half_slab.json +++ b/json/block/%name%_brick_half_slab.json @@ -1,8 +1,8 @@ { - "parent": "block/slab", - "textures": { - "bottom": "betterend:block/%name%_bricks", - "side": "betterend:block/%name%_bricks", - "top": "betterend:block/%name%_bricks" - } + "parent": "block/slab", + "textures": { + "bottom": "betterend:block/%name%_bricks", + "side": "betterend:block/%name%_bricks", + "top": "betterend:block/%name%_bricks" + } } \ No newline at end of file diff --git a/json/block/%name%_brick_inner_stairs.json b/json/block/%name%_brick_inner_stairs.json index 98c27d1f..6f04c892 100644 --- a/json/block/%name%_brick_inner_stairs.json +++ b/json/block/%name%_brick_inner_stairs.json @@ -1,8 +1,8 @@ { - "parent": "block/inner_stairs", - "textures": { - "bottom": "betterend:block/%name%_bricks", - "side": "betterend:block/%name%_bricks", - "top": "betterend:block/%name%_bricks" - } + "parent": "block/inner_stairs", + "textures": { + "bottom": "betterend:block/%name%_bricks", + "side": "betterend:block/%name%_bricks", + "top": "betterend:block/%name%_bricks" + } } \ No newline at end of file diff --git a/json/block/%name%_brick_outer_stairs.json b/json/block/%name%_brick_outer_stairs.json index 5fe881ad..481b896d 100644 --- a/json/block/%name%_brick_outer_stairs.json +++ b/json/block/%name%_brick_outer_stairs.json @@ -1,8 +1,8 @@ { - "parent": "block/outer_stairs", - "textures": { - "bottom": "betterend:block/%name%_bricks", - "side": "betterend:block/%name%_bricks", - "top": "betterend:block/%name%_bricks" - } + "parent": "block/outer_stairs", + "textures": { + "bottom": "betterend:block/%name%_bricks", + "side": "betterend:block/%name%_bricks", + "top": "betterend:block/%name%_bricks" + } } \ No newline at end of file diff --git a/json/block/%name%_brick_stairs.json b/json/block/%name%_brick_stairs.json index ee695265..94e5512c 100644 --- a/json/block/%name%_brick_stairs.json +++ b/json/block/%name%_brick_stairs.json @@ -1,8 +1,8 @@ { - "parent": "block/stairs", - "textures": { - "bottom": "betterend:block/%name%_bricks", - "side": "betterend:block/%name%_bricks", - "top": "betterend:block/%name%_bricks" - } + "parent": "block/stairs", + "textures": { + "bottom": "betterend:block/%name%_bricks", + "side": "betterend:block/%name%_bricks", + "top": "betterend:block/%name%_bricks" + } } \ No newline at end of file diff --git a/json/block/%name%_brick_wall_inventory.json b/json/block/%name%_brick_wall_inventory.json index f5616dc9..7f16d3b4 100644 --- a/json/block/%name%_brick_wall_inventory.json +++ b/json/block/%name%_brick_wall_inventory.json @@ -1,6 +1,6 @@ { - "parent": "minecraft:block/wall_inventory", - "textures": { - "wall": "betterend:block/%name%_bricks" - } + "parent": "minecraft:block/wall_inventory", + "textures": { + "wall": "betterend:block/%name%_bricks" + } } \ No newline at end of file diff --git a/json/block/%name%_brick_wall_post.json b/json/block/%name%_brick_wall_post.json index 3e23f8a3..a7fdb47e 100644 --- a/json/block/%name%_brick_wall_post.json +++ b/json/block/%name%_brick_wall_post.json @@ -1,6 +1,6 @@ { - "parent": "minecraft:block/template_wall_post", - "textures": { - "wall": "betterend:block/%name%_bricks" - } + "parent": "minecraft:block/template_wall_post", + "textures": { + "wall": "betterend:block/%name%_bricks" + } } \ No newline at end of file diff --git a/json/block/%name%_brick_wall_side.json b/json/block/%name%_brick_wall_side.json index e95d0502..bf16dc33 100644 --- a/json/block/%name%_brick_wall_side.json +++ b/json/block/%name%_brick_wall_side.json @@ -1,6 +1,6 @@ { - "parent": "minecraft:block/template_wall_side", - "textures": { - "wall": "betterend:block/%name%_bricks" - } + "parent": "minecraft:block/template_wall_side", + "textures": { + "wall": "betterend:block/%name%_bricks" + } } \ No newline at end of file diff --git a/json/block/%name%_brick_wall_side_tall.json b/json/block/%name%_brick_wall_side_tall.json index 7323cbfb..d0f4d3fc 100644 --- a/json/block/%name%_brick_wall_side_tall.json +++ b/json/block/%name%_brick_wall_side_tall.json @@ -1,6 +1,6 @@ { - "parent": "minecraft:block/template_wall_side_tall", - "textures": { - "wall": "betterend:block/%name%_bricks" - } + "parent": "minecraft:block/template_wall_side_tall", + "textures": { + "wall": "betterend:block/%name%_bricks" + } } \ No newline at end of file diff --git a/json/block/%name%_bricks.json b/json/block/%name%_bricks.json index 5f68cf77..3566742f 100644 --- a/json/block/%name%_bricks.json +++ b/json/block/%name%_bricks.json @@ -1,6 +1,6 @@ { - "parent": "block/cube_all", - "textures": { - "all": "betterend:block/%name%_bricks" - } + "parent": "block/cube_all", + "textures": { + "all": "betterend:block/%name%_bricks" + } } \ No newline at end of file diff --git a/json/block/%name%_button.json b/json/block/%name%_button.json index 4a465cf5..bc35f8cb 100644 --- a/json/block/%name%_button.json +++ b/json/block/%name%_button.json @@ -1,6 +1,6 @@ { - "parent": "block/button", - "textures": { - "texture": "betterend:block/%name%" - } + "parent": "block/button", + "textures": { + "texture": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/block/%name%_button_inventory.json b/json/block/%name%_button_inventory.json index e04a286b..a16f6271 100644 --- a/json/block/%name%_button_inventory.json +++ b/json/block/%name%_button_inventory.json @@ -1,6 +1,6 @@ { - "parent": "block/button_inventory", - "textures": { - "texture": "betterend:block/%name%" - } + "parent": "block/button_inventory", + "textures": { + "texture": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/block/%name%_button_pressed.json b/json/block/%name%_button_pressed.json index 5afc1c34..ad08effa 100644 --- a/json/block/%name%_button_pressed.json +++ b/json/block/%name%_button_pressed.json @@ -1,6 +1,6 @@ { - "parent": "block/button_pressed", - "textures": { - "texture": "betterend:block/%name%" - } + "parent": "block/button_pressed", + "textures": { + "texture": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/block/%name%_half_slab.json b/json/block/%name%_half_slab.json index afe17edd..365ca375 100644 --- a/json/block/%name%_half_slab.json +++ b/json/block/%name%_half_slab.json @@ -1,8 +1,8 @@ { - "parent": "block/slab", - "textures": { - "bottom": "betterend:block/%name%", - "side": "betterend:block/%name%", - "top": "betterend:block/%name%" - } + "parent": "block/slab", + "textures": { + "bottom": "betterend:block/%name%", + "side": "betterend:block/%name%", + "top": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/block/%name%_inner_stairs.json b/json/block/%name%_inner_stairs.json index f7f22430..5fbdd28b 100644 --- a/json/block/%name%_inner_stairs.json +++ b/json/block/%name%_inner_stairs.json @@ -1,8 +1,8 @@ { - "parent": "block/inner_stairs", - "textures": { - "bottom": "betterend:block/%name%", - "side": "betterend:block/%name%", - "top": "betterend:block/%name%" - } + "parent": "block/inner_stairs", + "textures": { + "bottom": "betterend:block/%name%", + "side": "betterend:block/%name%", + "top": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/block/%name%_outer_stairs.json b/json/block/%name%_outer_stairs.json index 2c6740d1..6e0a7437 100644 --- a/json/block/%name%_outer_stairs.json +++ b/json/block/%name%_outer_stairs.json @@ -1,8 +1,8 @@ { - "parent": "block/outer_stairs", - "textures": { - "bottom": "betterend:block/%name%", - "side": "betterend:block/%name%", - "top": "betterend:block/%name%" - } + "parent": "block/outer_stairs", + "textures": { + "bottom": "betterend:block/%name%", + "side": "betterend:block/%name%", + "top": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/block/%name%_pressure_plate_down.json b/json/block/%name%_pressure_plate_down.json index 0836b6f5..32039660 100644 --- a/json/block/%name%_pressure_plate_down.json +++ b/json/block/%name%_pressure_plate_down.json @@ -1,6 +1,6 @@ { - "parent": "block/pressure_plate_down", - "textures": { - "texture": "betterend:block/%name%" - } + "parent": "block/pressure_plate_down", + "textures": { + "texture": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/block/%name%_pressure_plate_up.json b/json/block/%name%_pressure_plate_up.json index 655f909b..65ff46e0 100644 --- a/json/block/%name%_pressure_plate_up.json +++ b/json/block/%name%_pressure_plate_up.json @@ -1,6 +1,6 @@ { - "parent": "block/pressure_plate_up", - "textures": { - "texture": "betterend:block/%name%" - } + "parent": "block/pressure_plate_up", + "textures": { + "texture": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/block/%name%_small_tiles.json b/json/block/%name%_small_tiles.json index b81bf3b0..4f31a369 100644 --- a/json/block/%name%_small_tiles.json +++ b/json/block/%name%_small_tiles.json @@ -1,6 +1,6 @@ { - "parent": "block/cube_all", - "textures": { - "all": "betterend:block/%name%_small_tiles" - } + "parent": "block/cube_all", + "textures": { + "all": "betterend:block/%name%_small_tiles" + } } \ No newline at end of file diff --git a/json/block/%name%_stairs.json b/json/block/%name%_stairs.json index 1aee442b..1e4dd106 100644 --- a/json/block/%name%_stairs.json +++ b/json/block/%name%_stairs.json @@ -1,8 +1,8 @@ { - "parent": "block/stairs", - "textures": { - "bottom": "betterend:block/%name%", - "side": "betterend:block/%name%", - "top": "betterend:block/%name%" - } + "parent": "block/stairs", + "textures": { + "bottom": "betterend:block/%name%", + "side": "betterend:block/%name%", + "top": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/block/%name%_tile.json b/json/block/%name%_tile.json index 211afd9d..de0b467d 100644 --- a/json/block/%name%_tile.json +++ b/json/block/%name%_tile.json @@ -1,6 +1,6 @@ { - "parent": "block/cube_all", - "textures": { - "all": "betterend:block/%name%_tile" - } + "parent": "block/cube_all", + "textures": { + "all": "betterend:block/%name%_tile" + } } \ No newline at end of file diff --git a/json/block/%name%_wall_inventory.json b/json/block/%name%_wall_inventory.json index 35d05c72..27cd062b 100644 --- a/json/block/%name%_wall_inventory.json +++ b/json/block/%name%_wall_inventory.json @@ -1,6 +1,6 @@ { - "parent": "minecraft:block/wall_inventory", - "textures": { - "wall": "betterend:block/%name%" - } + "parent": "minecraft:block/wall_inventory", + "textures": { + "wall": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/block/%name%_wall_post.json b/json/block/%name%_wall_post.json index f668ca4b..dd01a06a 100644 --- a/json/block/%name%_wall_post.json +++ b/json/block/%name%_wall_post.json @@ -1,6 +1,6 @@ { - "parent": "minecraft:block/template_wall_post", - "textures": { - "wall": "betterend:block/%name%" - } + "parent": "minecraft:block/template_wall_post", + "textures": { + "wall": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/block/%name%_wall_side.json b/json/block/%name%_wall_side.json index 6fc8de4b..e997817b 100644 --- a/json/block/%name%_wall_side.json +++ b/json/block/%name%_wall_side.json @@ -1,6 +1,6 @@ { - "parent": "minecraft:block/template_wall_side", - "textures": { - "wall": "betterend:block/%name%" - } + "parent": "minecraft:block/template_wall_side", + "textures": { + "wall": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/block/%name%_wall_side_tall.json b/json/block/%name%_wall_side_tall.json index 9570ac1a..fe040d22 100644 --- a/json/block/%name%_wall_side_tall.json +++ b/json/block/%name%_wall_side_tall.json @@ -1,6 +1,6 @@ { - "parent": "minecraft:block/template_wall_side_tall", - "textures": { - "wall": "betterend:block/%name%" - } + "parent": "minecraft:block/template_wall_side_tall", + "textures": { + "wall": "betterend:block/%name%" + } } \ No newline at end of file diff --git a/json/blockstates/%name%.json b/json/blockstates/%name%.json index ef978798..f230067b 100644 --- a/json/blockstates/%name%.json +++ b/json/blockstates/%name%.json @@ -1,7 +1,7 @@ { - "variants": { - "": { - "model": "betterend:block/%name%" - } - } + "variants": { + "": { + "model": "betterend:block/%name%" + } + } } \ No newline at end of file diff --git a/json/blockstates/%name%_brick_slab.json b/json/blockstates/%name%_brick_slab.json index d5a6bf3e..f548c186 100644 --- a/json/blockstates/%name%_brick_slab.json +++ b/json/blockstates/%name%_brick_slab.json @@ -1,15 +1,15 @@ { - "variants": { - "type=bottom": { - "model": "betterend:block/%name%_brick_half_slab" - }, - "type=double": { - "model": "betterend:block/%name%_bricks" - }, - "type=top": { - "model": "betterend:block/%name%_brick_half_slab", - "uvlock": true, - "x": 180 - } - } + "variants": { + "type=bottom": { + "model": "betterend:block/%name%_brick_half_slab" + }, + "type=double": { + "model": "betterend:block/%name%_bricks" + }, + "type=top": { + "model": "betterend:block/%name%_brick_half_slab", + "uvlock": true, + "x": 180 + } + } } \ No newline at end of file diff --git a/json/blockstates/%name%_brick_stairs.json b/json/blockstates/%name%_brick_stairs.json index 97fbabb4..16dbadc5 100644 --- a/json/blockstates/%name%_brick_stairs.json +++ b/json/blockstates/%name%_brick_stairs.json @@ -1,209 +1,209 @@ { - "variants": { - "facing=east,half=bottom,shape=inner_left": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "y": 270 - }, - "facing=east,half=bottom,shape=inner_right": { - "model": "betterend:block/%name%_brick_inner_stairs" - }, - "facing=east,half=bottom,shape=outer_left": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "y": 270 - }, - "facing=east,half=bottom,shape=outer_right": { - "model": "betterend:block/%name%_brick_outer_stairs" - }, - "facing=east,half=bottom,shape=straight": { - "model": "betterend:block/%name%_brick_stairs" - }, - "facing=east,half=top,shape=inner_left": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "x": 180 - }, - "facing=east,half=top,shape=inner_right": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "x": 180, - "y": 90 - }, - "facing=east,half=top,shape=outer_left": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "x": 180 - }, - "facing=east,half=top,shape=outer_right": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "x": 180, - "y": 90 - }, - "facing=east,half=top,shape=straight": { - "model": "betterend:block/%name%_brick_stairs", - "uvlock": true, - "x": 180 - }, - "facing=north,half=bottom,shape=inner_left": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "y": 180 - }, - "facing=north,half=bottom,shape=inner_right": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "y": 270 - }, - "facing=north,half=bottom,shape=outer_left": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "y": 180 - }, - "facing=north,half=bottom,shape=outer_right": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "y": 270 - }, - "facing=north,half=bottom,shape=straight": { - "model": "betterend:block/%name%_brick_stairs", - "uvlock": true, - "y": 270 - }, - "facing=north,half=top,shape=inner_left": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "x": 180, - "y": 270 - }, - "facing=north,half=top,shape=inner_right": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "x": 180 - }, - "facing=north,half=top,shape=outer_left": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "x": 180, - "y": 270 - }, - "facing=north,half=top,shape=outer_right": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "x": 180 - }, - "facing=north,half=top,shape=straight": { - "model": "betterend:block/%name%_brick_stairs", - "uvlock": true, - "x": 180, - "y": 270 - }, - "facing=south,half=bottom,shape=inner_left": { - "model": "betterend:block/%name%_brick_inner_stairs" - }, - "facing=south,half=bottom,shape=inner_right": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "y": 90 - }, - "facing=south,half=bottom,shape=outer_left": { - "model": "betterend:block/%name%_brick_outer_stairs" - }, - "facing=south,half=bottom,shape=outer_right": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "y": 90 - }, - "facing=south,half=bottom,shape=straight": { - "model": "betterend:block/%name%_brick_stairs", - "uvlock": true, - "y": 90 - }, - "facing=south,half=top,shape=inner_left": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "x": 180, - "y": 90 - }, - "facing=south,half=top,shape=inner_right": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "x": 180, - "y": 180 - }, - "facing=south,half=top,shape=outer_left": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "x": 180, - "y": 90 - }, - "facing=south,half=top,shape=outer_right": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "x": 180, - "y": 180 - }, - "facing=south,half=top,shape=straight": { - "model": "betterend:block/%name%_brick_stairs", - "uvlock": true, - "x": 180, - "y": 90 - }, - "facing=west,half=bottom,shape=inner_left": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "y": 90 - }, - "facing=west,half=bottom,shape=inner_right": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "y": 180 - }, - "facing=west,half=bottom,shape=outer_left": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "y": 90 - }, - "facing=west,half=bottom,shape=outer_right": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "y": 180 - }, - "facing=west,half=bottom,shape=straight": { - "model": "betterend:block/%name%_brick_stairs", - "uvlock": true, - "y": 180 - }, - "facing=west,half=top,shape=inner_left": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "x": 180, - "y": 180 - }, - "facing=west,half=top,shape=inner_right": { - "model": "betterend:block/%name%_brick_inner_stairs", - "uvlock": true, - "x": 180, - "y": 270 - }, - "facing=west,half=top,shape=outer_left": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "x": 180, - "y": 180 - }, - "facing=west,half=top,shape=outer_right": { - "model": "betterend:block/%name%_brick_outer_stairs", - "uvlock": true, - "x": 180, - "y": 270 - }, - "facing=west,half=top,shape=straight": { - "model": "betterend:block/%name%_brick_stairs", - "uvlock": true, - "x": 180, - "y": 180 - } - } + "variants": { + "facing=east,half=bottom,shape=inner_left": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "y": 270 + }, + "facing=east,half=bottom,shape=inner_right": { + "model": "betterend:block/%name%_brick_inner_stairs" + }, + "facing=east,half=bottom,shape=outer_left": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "y": 270 + }, + "facing=east,half=bottom,shape=outer_right": { + "model": "betterend:block/%name%_brick_outer_stairs" + }, + "facing=east,half=bottom,shape=straight": { + "model": "betterend:block/%name%_brick_stairs" + }, + "facing=east,half=top,shape=inner_left": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "x": 180 + }, + "facing=east,half=top,shape=inner_right": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=east,half=top,shape=outer_left": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "x": 180 + }, + "facing=east,half=top,shape=outer_right": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=east,half=top,shape=straight": { + "model": "betterend:block/%name%_brick_stairs", + "uvlock": true, + "x": 180 + }, + "facing=north,half=bottom,shape=inner_left": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "y": 180 + }, + "facing=north,half=bottom,shape=inner_right": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "y": 270 + }, + "facing=north,half=bottom,shape=outer_left": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "y": 180 + }, + "facing=north,half=bottom,shape=outer_right": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "y": 270 + }, + "facing=north,half=bottom,shape=straight": { + "model": "betterend:block/%name%_brick_stairs", + "uvlock": true, + "y": 270 + }, + "facing=north,half=top,shape=inner_left": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=north,half=top,shape=inner_right": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "x": 180 + }, + "facing=north,half=top,shape=outer_left": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=north,half=top,shape=outer_right": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "x": 180 + }, + "facing=north,half=top,shape=straight": { + "model": "betterend:block/%name%_brick_stairs", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=south,half=bottom,shape=inner_left": { + "model": "betterend:block/%name%_brick_inner_stairs" + }, + "facing=south,half=bottom,shape=inner_right": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "y": 90 + }, + "facing=south,half=bottom,shape=outer_left": { + "model": "betterend:block/%name%_brick_outer_stairs" + }, + "facing=south,half=bottom,shape=outer_right": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "y": 90 + }, + "facing=south,half=bottom,shape=straight": { + "model": "betterend:block/%name%_brick_stairs", + "uvlock": true, + "y": 90 + }, + "facing=south,half=top,shape=inner_left": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=south,half=top,shape=inner_right": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=south,half=top,shape=outer_left": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=south,half=top,shape=outer_right": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=south,half=top,shape=straight": { + "model": "betterend:block/%name%_brick_stairs", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=west,half=bottom,shape=inner_left": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "y": 90 + }, + "facing=west,half=bottom,shape=inner_right": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "y": 180 + }, + "facing=west,half=bottom,shape=outer_left": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "y": 90 + }, + "facing=west,half=bottom,shape=outer_right": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "y": 180 + }, + "facing=west,half=bottom,shape=straight": { + "model": "betterend:block/%name%_brick_stairs", + "uvlock": true, + "y": 180 + }, + "facing=west,half=top,shape=inner_left": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=west,half=top,shape=inner_right": { + "model": "betterend:block/%name%_brick_inner_stairs", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=west,half=top,shape=outer_left": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=west,half=top,shape=outer_right": { + "model": "betterend:block/%name%_brick_outer_stairs", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=west,half=top,shape=straight": { + "model": "betterend:block/%name%_brick_stairs", + "uvlock": true, + "x": 180, + "y": 180 + } + } } \ No newline at end of file diff --git a/json/blockstates/%name%_brick_wall.json b/json/blockstates/%name%_brick_wall.json index 17f3910d..346ac2f1 100644 --- a/json/blockstates/%name%_brick_wall.json +++ b/json/blockstates/%name%_brick_wall.json @@ -1,90 +1,90 @@ { - "multipart": [ - { - "when": { - "up": "true" - }, - "apply": { - "model": "betterend:block/%name%_brick_wall_post" - } - }, - { - "when": { - "north": "low" - }, - "apply": { - "model": "betterend:block/%name%_brick_wall_side", - "uvlock": true - } - }, - { - "when": { - "east": "low" - }, - "apply": { - "model": "betterend:block/%name%_brick_wall_side", - "y": 90, - "uvlock": true - } - }, - { - "when": { - "south": "low" - }, - "apply": { - "model": "betterend:block/%name%_brick_wall_side", - "y": 180, - "uvlock": true - } - }, - { - "when": { - "west": "low" - }, - "apply": { - "model": "betterend:block/%name%_brick_wall_side", - "y": 270, - "uvlock": true - } - }, - { - "when": { - "north": "tall" - }, - "apply": { - "model": "betterend:block/%name%_brick_wall_side_tall", - "uvlock": true - } - }, - { - "when": { - "east": "tall" - }, - "apply": { - "model": "betterend:block/%name%_brick_wall_side_tall", - "y": 90, - "uvlock": true - } - }, - { - "when": { - "south": "tall" - }, - "apply": { - "model": "betterend:block/%name%_brick_wall_side_tall", - "y": 180, - "uvlock": true - } - }, - { - "when": { - "west": "tall" - }, - "apply": { - "model": "betterend:block/%name%_brick_wall_side_tall", - "y": 270, - "uvlock": true - } - } - ] + "multipart": [ + { + "when": { + "up": "true" + }, + "apply": { + "model": "betterend:block/%name%_brick_wall_post" + } + }, + { + "when": { + "north": "low" + }, + "apply": { + "model": "betterend:block/%name%_brick_wall_side", + "uvlock": true + } + }, + { + "when": { + "east": "low" + }, + "apply": { + "model": "betterend:block/%name%_brick_wall_side", + "y": 90, + "uvlock": true + } + }, + { + "when": { + "south": "low" + }, + "apply": { + "model": "betterend:block/%name%_brick_wall_side", + "y": 180, + "uvlock": true + } + }, + { + "when": { + "west": "low" + }, + "apply": { + "model": "betterend:block/%name%_brick_wall_side", + "y": 270, + "uvlock": true + } + }, + { + "when": { + "north": "tall" + }, + "apply": { + "model": "betterend:block/%name%_brick_wall_side_tall", + "uvlock": true + } + }, + { + "when": { + "east": "tall" + }, + "apply": { + "model": "betterend:block/%name%_brick_wall_side_tall", + "y": 90, + "uvlock": true + } + }, + { + "when": { + "south": "tall" + }, + "apply": { + "model": "betterend:block/%name%_brick_wall_side_tall", + "y": 180, + "uvlock": true + } + }, + { + "when": { + "west": "tall" + }, + "apply": { + "model": "betterend:block/%name%_brick_wall_side_tall", + "y": 270, + "uvlock": true + } + } + ] } \ No newline at end of file diff --git a/json/blockstates/%name%_bricks.json b/json/blockstates/%name%_bricks.json index d55de86c..1851167f 100644 --- a/json/blockstates/%name%_bricks.json +++ b/json/blockstates/%name%_bricks.json @@ -1,7 +1,7 @@ { - "variants": { - "": { - "model": "betterend:block/%name%_bricks" - } - } + "variants": { + "": { + "model": "betterend:block/%name%_bricks" + } + } } \ No newline at end of file diff --git a/json/blockstates/%name%_button.json b/json/blockstates/%name%_button.json index f0a946f9..60701fd4 100644 --- a/json/blockstates/%name%_button.json +++ b/json/blockstates/%name%_button.json @@ -1,118 +1,118 @@ { - "variants": { - "face=ceiling,facing=east,powered=false": { - "model": "betterend:block/%name%_button", - "x": 180, - "y": 270 - }, - "face=ceiling,facing=east,powered=true": { - "model": "betterend:block/%name%_button_pressed", - "x": 180, - "y": 270 - }, - "face=ceiling,facing=north,powered=false": { - "model": "betterend:block/%name%_button", - "x": 180, - "y": 180 - }, - "face=ceiling,facing=north,powered=true": { - "model": "betterend:block/%name%_button_pressed", - "x": 180, - "y": 180 - }, - "face=ceiling,facing=south,powered=false": { - "model": "betterend:block/%name%_button", - "x": 180 - }, - "face=ceiling,facing=south,powered=true": { - "model": "betterend:block/%name%_button_pressed", - "x": 180 - }, - "face=ceiling,facing=west,powered=false": { - "model": "betterend:block/%name%_button", - "x": 180, - "y": 90 - }, - "face=ceiling,facing=west,powered=true": { - "model": "betterend:block/%name%_button_pressed", - "x": 180, - "y": 90 - }, - "face=floor,facing=east,powered=false": { - "model": "betterend:block/%name%_button", - "y": 90 - }, - "face=floor,facing=east,powered=true": { - "model": "betterend:block/%name%_button_pressed", - "y": 90 - }, - "face=floor,facing=north,powered=false": { - "model": "betterend:block/%name%_button" - }, - "face=floor,facing=north,powered=true": { - "model": "betterend:block/%name%_button_pressed" - }, - "face=floor,facing=south,powered=false": { - "model": "betterend:block/%name%_button", - "y": 180 - }, - "face=floor,facing=south,powered=true": { - "model": "betterend:block/%name%_button_pressed", - "y": 180 - }, - "face=floor,facing=west,powered=false": { - "model": "betterend:block/%name%_button", - "y": 270 - }, - "face=floor,facing=west,powered=true": { - "model": "betterend:block/%name%_button_pressed", - "y": 270 - }, - "face=wall,facing=east,powered=false": { - "model": "betterend:block/%name%_button", - "uvlock": true, - "x": 90, - "y": 90 - }, - "face=wall,facing=east,powered=true": { - "model": "betterend:block/%name%_button_pressed", - "uvlock": true, - "x": 90, - "y": 90 - }, - "face=wall,facing=north,powered=false": { - "model": "betterend:block/%name%_button", - "uvlock": true, - "x": 90 - }, - "face=wall,facing=north,powered=true": { - "model": "betterend:block/%name%_button_pressed", - "uvlock": true, - "x": 90 - }, - "face=wall,facing=south,powered=false": { - "model": "betterend:block/%name%_button", - "uvlock": true, - "x": 90, - "y": 180 - }, - "face=wall,facing=south,powered=true": { - "model": "betterend:block/%name%_button_pressed", - "uvlock": true, - "x": 90, - "y": 180 - }, - "face=wall,facing=west,powered=false": { - "model": "betterend:block/%name%_button", - "uvlock": true, - "x": 90, - "y": 270 - }, - "face=wall,facing=west,powered=true": { - "model": "betterend:block/%name%_button_pressed", - "uvlock": true, - "x": 90, - "y": 270 - } - } + "variants": { + "face=ceiling,facing=east,powered=false": { + "model": "betterend:block/%name%_button", + "x": 180, + "y": 270 + }, + "face=ceiling,facing=east,powered=true": { + "model": "betterend:block/%name%_button_pressed", + "x": 180, + "y": 270 + }, + "face=ceiling,facing=north,powered=false": { + "model": "betterend:block/%name%_button", + "x": 180, + "y": 180 + }, + "face=ceiling,facing=north,powered=true": { + "model": "betterend:block/%name%_button_pressed", + "x": 180, + "y": 180 + }, + "face=ceiling,facing=south,powered=false": { + "model": "betterend:block/%name%_button", + "x": 180 + }, + "face=ceiling,facing=south,powered=true": { + "model": "betterend:block/%name%_button_pressed", + "x": 180 + }, + "face=ceiling,facing=west,powered=false": { + "model": "betterend:block/%name%_button", + "x": 180, + "y": 90 + }, + "face=ceiling,facing=west,powered=true": { + "model": "betterend:block/%name%_button_pressed", + "x": 180, + "y": 90 + }, + "face=floor,facing=east,powered=false": { + "model": "betterend:block/%name%_button", + "y": 90 + }, + "face=floor,facing=east,powered=true": { + "model": "betterend:block/%name%_button_pressed", + "y": 90 + }, + "face=floor,facing=north,powered=false": { + "model": "betterend:block/%name%_button" + }, + "face=floor,facing=north,powered=true": { + "model": "betterend:block/%name%_button_pressed" + }, + "face=floor,facing=south,powered=false": { + "model": "betterend:block/%name%_button", + "y": 180 + }, + "face=floor,facing=south,powered=true": { + "model": "betterend:block/%name%_button_pressed", + "y": 180 + }, + "face=floor,facing=west,powered=false": { + "model": "betterend:block/%name%_button", + "y": 270 + }, + "face=floor,facing=west,powered=true": { + "model": "betterend:block/%name%_button_pressed", + "y": 270 + }, + "face=wall,facing=east,powered=false": { + "model": "betterend:block/%name%_button", + "uvlock": true, + "x": 90, + "y": 90 + }, + "face=wall,facing=east,powered=true": { + "model": "betterend:block/%name%_button_pressed", + "uvlock": true, + "x": 90, + "y": 90 + }, + "face=wall,facing=north,powered=false": { + "model": "betterend:block/%name%_button", + "uvlock": true, + "x": 90 + }, + "face=wall,facing=north,powered=true": { + "model": "betterend:block/%name%_button_pressed", + "uvlock": true, + "x": 90 + }, + "face=wall,facing=south,powered=false": { + "model": "betterend:block/%name%_button", + "uvlock": true, + "x": 90, + "y": 180 + }, + "face=wall,facing=south,powered=true": { + "model": "betterend:block/%name%_button_pressed", + "uvlock": true, + "x": 90, + "y": 180 + }, + "face=wall,facing=west,powered=false": { + "model": "betterend:block/%name%_button", + "uvlock": true, + "x": 90, + "y": 270 + }, + "face=wall,facing=west,powered=true": { + "model": "betterend:block/%name%_button_pressed", + "uvlock": true, + "x": 90, + "y": 270 + } + } } \ No newline at end of file diff --git a/json/blockstates/%name%_pillar.json b/json/blockstates/%name%_pillar.json index 27ec0347..5ff8dab2 100644 --- a/json/blockstates/%name%_pillar.json +++ b/json/blockstates/%name%_pillar.json @@ -1,7 +1,16 @@ { - "variants": { - "axis=x": { "model": "betterend:block/%name%_pillar", "x": 90, "y": 90 }, - "axis=y": { "model": "betterend:block/%name%_pillar" }, - "axis=z": { "model": "betterend:block/%name%_pillar", "x": 90 } - } + "variants": { + "axis=x": { + "model": "betterend:block/%name%_pillar", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "betterend:block/%name%_pillar" + }, + "axis=z": { + "model": "betterend:block/%name%_pillar", + "x": 90 + } + } } \ No newline at end of file diff --git a/json/blockstates/%name%_plate.json b/json/blockstates/%name%_plate.json index 4060f8da..f7c1e4bd 100644 --- a/json/blockstates/%name%_plate.json +++ b/json/blockstates/%name%_plate.json @@ -1,10 +1,10 @@ { - "variants": { - "powered=false": { - "model": "betterend:block/%name%_pressure_plate_up" - }, - "powered=true": { - "model": "betterend:block/%name%_pressure_plate_down" - } - } + "variants": { + "powered=false": { + "model": "betterend:block/%name%_pressure_plate_up" + }, + "powered=true": { + "model": "betterend:block/%name%_pressure_plate_down" + } + } } \ No newline at end of file diff --git a/json/blockstates/%name%_slab.json b/json/blockstates/%name%_slab.json index 17875e4c..e99a19da 100644 --- a/json/blockstates/%name%_slab.json +++ b/json/blockstates/%name%_slab.json @@ -1,15 +1,15 @@ { - "variants": { - "type=bottom": { - "model": "betterend:block/%name%_half_slab" - }, - "type=double": { - "model": "betterend:block/%name%" - }, - "type=top": { - "model": "betterend:block/%name%_half_slab", - "uvlock": true, - "x": 180 - } - } + "variants": { + "type=bottom": { + "model": "betterend:block/%name%_half_slab" + }, + "type=double": { + "model": "betterend:block/%name%" + }, + "type=top": { + "model": "betterend:block/%name%_half_slab", + "uvlock": true, + "x": 180 + } + } } \ No newline at end of file diff --git a/json/blockstates/%name%_small_tiles.json b/json/blockstates/%name%_small_tiles.json index 5a84411b..f4f1f62a 100644 --- a/json/blockstates/%name%_small_tiles.json +++ b/json/blockstates/%name%_small_tiles.json @@ -1,7 +1,7 @@ { - "variants": { - "": { - "model": "betterend:block/%name%_small_tiles" - } - } + "variants": { + "": { + "model": "betterend:block/%name%_small_tiles" + } + } } \ No newline at end of file diff --git a/json/blockstates/%name%_stairs.json b/json/blockstates/%name%_stairs.json index 685e1861..54b129ce 100644 --- a/json/blockstates/%name%_stairs.json +++ b/json/blockstates/%name%_stairs.json @@ -1,209 +1,209 @@ { - "variants": { - "facing=east,half=bottom,shape=inner_left": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "y": 270 - }, - "facing=east,half=bottom,shape=inner_right": { - "model": "betterend:block/%name%_inner_stairs" - }, - "facing=east,half=bottom,shape=outer_left": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "y": 270 - }, - "facing=east,half=bottom,shape=outer_right": { - "model": "betterend:block/%name%_outer_stairs" - }, - "facing=east,half=bottom,shape=straight": { - "model": "betterend:block/%name%_stairs" - }, - "facing=east,half=top,shape=inner_left": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "x": 180 - }, - "facing=east,half=top,shape=inner_right": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "x": 180, - "y": 90 - }, - "facing=east,half=top,shape=outer_left": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "x": 180 - }, - "facing=east,half=top,shape=outer_right": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "x": 180, - "y": 90 - }, - "facing=east,half=top,shape=straight": { - "model": "betterend:block/%name%_stairs", - "uvlock": true, - "x": 180 - }, - "facing=north,half=bottom,shape=inner_left": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "y": 180 - }, - "facing=north,half=bottom,shape=inner_right": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "y": 270 - }, - "facing=north,half=bottom,shape=outer_left": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "y": 180 - }, - "facing=north,half=bottom,shape=outer_right": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "y": 270 - }, - "facing=north,half=bottom,shape=straight": { - "model": "betterend:block/%name%_stairs", - "uvlock": true, - "y": 270 - }, - "facing=north,half=top,shape=inner_left": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "x": 180, - "y": 270 - }, - "facing=north,half=top,shape=inner_right": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "x": 180 - }, - "facing=north,half=top,shape=outer_left": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "x": 180, - "y": 270 - }, - "facing=north,half=top,shape=outer_right": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "x": 180 - }, - "facing=north,half=top,shape=straight": { - "model": "betterend:block/%name%_stairs", - "uvlock": true, - "x": 180, - "y": 270 - }, - "facing=south,half=bottom,shape=inner_left": { - "model": "betterend:block/%name%_inner_stairs" - }, - "facing=south,half=bottom,shape=inner_right": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "y": 90 - }, - "facing=south,half=bottom,shape=outer_left": { - "model": "betterend:block/%name%_outer_stairs" - }, - "facing=south,half=bottom,shape=outer_right": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "y": 90 - }, - "facing=south,half=bottom,shape=straight": { - "model": "betterend:block/%name%_stairs", - "uvlock": true, - "y": 90 - }, - "facing=south,half=top,shape=inner_left": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "x": 180, - "y": 90 - }, - "facing=south,half=top,shape=inner_right": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "x": 180, - "y": 180 - }, - "facing=south,half=top,shape=outer_left": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "x": 180, - "y": 90 - }, - "facing=south,half=top,shape=outer_right": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "x": 180, - "y": 180 - }, - "facing=south,half=top,shape=straight": { - "model": "betterend:block/%name%_stairs", - "uvlock": true, - "x": 180, - "y": 90 - }, - "facing=west,half=bottom,shape=inner_left": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "y": 90 - }, - "facing=west,half=bottom,shape=inner_right": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "y": 180 - }, - "facing=west,half=bottom,shape=outer_left": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "y": 90 - }, - "facing=west,half=bottom,shape=outer_right": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "y": 180 - }, - "facing=west,half=bottom,shape=straight": { - "model": "betterend:block/%name%_stairs", - "uvlock": true, - "y": 180 - }, - "facing=west,half=top,shape=inner_left": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "x": 180, - "y": 180 - }, - "facing=west,half=top,shape=inner_right": { - "model": "betterend:block/%name%_inner_stairs", - "uvlock": true, - "x": 180, - "y": 270 - }, - "facing=west,half=top,shape=outer_left": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "x": 180, - "y": 180 - }, - "facing=west,half=top,shape=outer_right": { - "model": "betterend:block/%name%_outer_stairs", - "uvlock": true, - "x": 180, - "y": 270 - }, - "facing=west,half=top,shape=straight": { - "model": "betterend:block/%name%_stairs", - "uvlock": true, - "x": 180, - "y": 180 - } - } + "variants": { + "facing=east,half=bottom,shape=inner_left": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "y": 270 + }, + "facing=east,half=bottom,shape=inner_right": { + "model": "betterend:block/%name%_inner_stairs" + }, + "facing=east,half=bottom,shape=outer_left": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "y": 270 + }, + "facing=east,half=bottom,shape=outer_right": { + "model": "betterend:block/%name%_outer_stairs" + }, + "facing=east,half=bottom,shape=straight": { + "model": "betterend:block/%name%_stairs" + }, + "facing=east,half=top,shape=inner_left": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "x": 180 + }, + "facing=east,half=top,shape=inner_right": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=east,half=top,shape=outer_left": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "x": 180 + }, + "facing=east,half=top,shape=outer_right": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=east,half=top,shape=straight": { + "model": "betterend:block/%name%_stairs", + "uvlock": true, + "x": 180 + }, + "facing=north,half=bottom,shape=inner_left": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "y": 180 + }, + "facing=north,half=bottom,shape=inner_right": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "y": 270 + }, + "facing=north,half=bottom,shape=outer_left": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "y": 180 + }, + "facing=north,half=bottom,shape=outer_right": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "y": 270 + }, + "facing=north,half=bottom,shape=straight": { + "model": "betterend:block/%name%_stairs", + "uvlock": true, + "y": 270 + }, + "facing=north,half=top,shape=inner_left": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=north,half=top,shape=inner_right": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "x": 180 + }, + "facing=north,half=top,shape=outer_left": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=north,half=top,shape=outer_right": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "x": 180 + }, + "facing=north,half=top,shape=straight": { + "model": "betterend:block/%name%_stairs", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=south,half=bottom,shape=inner_left": { + "model": "betterend:block/%name%_inner_stairs" + }, + "facing=south,half=bottom,shape=inner_right": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "y": 90 + }, + "facing=south,half=bottom,shape=outer_left": { + "model": "betterend:block/%name%_outer_stairs" + }, + "facing=south,half=bottom,shape=outer_right": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "y": 90 + }, + "facing=south,half=bottom,shape=straight": { + "model": "betterend:block/%name%_stairs", + "uvlock": true, + "y": 90 + }, + "facing=south,half=top,shape=inner_left": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=south,half=top,shape=inner_right": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=south,half=top,shape=outer_left": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=south,half=top,shape=outer_right": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=south,half=top,shape=straight": { + "model": "betterend:block/%name%_stairs", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=west,half=bottom,shape=inner_left": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "y": 90 + }, + "facing=west,half=bottom,shape=inner_right": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "y": 180 + }, + "facing=west,half=bottom,shape=outer_left": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "y": 90 + }, + "facing=west,half=bottom,shape=outer_right": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "y": 180 + }, + "facing=west,half=bottom,shape=straight": { + "model": "betterend:block/%name%_stairs", + "uvlock": true, + "y": 180 + }, + "facing=west,half=top,shape=inner_left": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=west,half=top,shape=inner_right": { + "model": "betterend:block/%name%_inner_stairs", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=west,half=top,shape=outer_left": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=west,half=top,shape=outer_right": { + "model": "betterend:block/%name%_outer_stairs", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=west,half=top,shape=straight": { + "model": "betterend:block/%name%_stairs", + "uvlock": true, + "x": 180, + "y": 180 + } + } } \ No newline at end of file diff --git a/json/blockstates/%name%_tile.json b/json/blockstates/%name%_tile.json index b9f56911..7608ad47 100644 --- a/json/blockstates/%name%_tile.json +++ b/json/blockstates/%name%_tile.json @@ -1,7 +1,7 @@ { - "variants": { - "": { - "model": "betterend:block/%name%_tile" - } - } + "variants": { + "": { + "model": "betterend:block/%name%_tile" + } + } } \ No newline at end of file diff --git a/json/blockstates/%name%_wall.json b/json/blockstates/%name%_wall.json index 3d81eb45..e2107bcd 100644 --- a/json/blockstates/%name%_wall.json +++ b/json/blockstates/%name%_wall.json @@ -1,90 +1,90 @@ { - "multipart": [ - { - "when": { - "up": "true" - }, - "apply": { - "model": "betterend:block/%name%_wall_post" - } - }, - { - "when": { - "north": "low" - }, - "apply": { - "model": "betterend:block/%name%_wall_side", - "uvlock": true - } - }, - { - "when": { - "east": "low" - }, - "apply": { - "model": "betterend:block/%name%_wall_side", - "y": 90, - "uvlock": true - } - }, - { - "when": { - "south": "low" - }, - "apply": { - "model": "betterend:block/%name%_wall_side", - "y": 180, - "uvlock": true - } - }, - { - "when": { - "west": "low" - }, - "apply": { - "model": "betterend:block/%name%_wall_side", - "y": 270, - "uvlock": true - } - }, - { - "when": { - "north": "tall" - }, - "apply": { - "model": "betterend:block/%name%_wall_side_tall", - "uvlock": true - } - }, - { - "when": { - "east": "tall" - }, - "apply": { - "model": "betterend:block/%name%_wall_side_tall", - "y": 90, - "uvlock": true - } - }, - { - "when": { - "south": "tall" - }, - "apply": { - "model": "betterend:block/%name%_wall_side_tall", - "y": 180, - "uvlock": true - } - }, - { - "when": { - "west": "tall" - }, - "apply": { - "model": "betterend:block/%name%_wall_side_tall", - "y": 270, - "uvlock": true - } - } - ] + "multipart": [ + { + "when": { + "up": "true" + }, + "apply": { + "model": "betterend:block/%name%_wall_post" + } + }, + { + "when": { + "north": "low" + }, + "apply": { + "model": "betterend:block/%name%_wall_side", + "uvlock": true + } + }, + { + "when": { + "east": "low" + }, + "apply": { + "model": "betterend:block/%name%_wall_side", + "y": 90, + "uvlock": true + } + }, + { + "when": { + "south": "low" + }, + "apply": { + "model": "betterend:block/%name%_wall_side", + "y": 180, + "uvlock": true + } + }, + { + "when": { + "west": "low" + }, + "apply": { + "model": "betterend:block/%name%_wall_side", + "y": 270, + "uvlock": true + } + }, + { + "when": { + "north": "tall" + }, + "apply": { + "model": "betterend:block/%name%_wall_side_tall", + "uvlock": true + } + }, + { + "when": { + "east": "tall" + }, + "apply": { + "model": "betterend:block/%name%_wall_side_tall", + "y": 90, + "uvlock": true + } + }, + { + "when": { + "south": "tall" + }, + "apply": { + "model": "betterend:block/%name%_wall_side_tall", + "y": 180, + "uvlock": true + } + }, + { + "when": { + "west": "tall" + }, + "apply": { + "model": "betterend:block/%name%_wall_side_tall", + "y": 270, + "uvlock": true + } + } + ] } \ No newline at end of file diff --git a/json/item/%name%.json b/json/item/%name%.json index 82508cd3..fa3a6fe2 100644 --- a/json/item/%name%.json +++ b/json/item/%name%.json @@ -1,3 +1,3 @@ { - "parent": "betterend:block/%name%" + "parent": "betterend:block/%name%" } \ No newline at end of file diff --git a/json/item/%name%_brick_slab.json b/json/item/%name%_brick_slab.json index c148cf65..99e58c89 100644 --- a/json/item/%name%_brick_slab.json +++ b/json/item/%name%_brick_slab.json @@ -1,3 +1,3 @@ { - "parent": "betterend:block/%name%_brick_half_slab" + "parent": "betterend:block/%name%_brick_half_slab" } \ No newline at end of file diff --git a/json/item/%name%_brick_stairs.json b/json/item/%name%_brick_stairs.json index 24b61896..532344a8 100644 --- a/json/item/%name%_brick_stairs.json +++ b/json/item/%name%_brick_stairs.json @@ -1,3 +1,3 @@ { - "parent": "betterend:block/%name%_brick_stairs" + "parent": "betterend:block/%name%_brick_stairs" } \ No newline at end of file diff --git a/json/item/%name%_brick_wall.json b/json/item/%name%_brick_wall.json index 1e902ec4..fb1bd7a9 100644 --- a/json/item/%name%_brick_wall.json +++ b/json/item/%name%_brick_wall.json @@ -1,3 +1,3 @@ { - "parent": "betterend:block/%name%_brick_wall_inventory" + "parent": "betterend:block/%name%_brick_wall_inventory" } \ No newline at end of file diff --git a/json/item/%name%_bricks.json b/json/item/%name%_bricks.json index 56ce6003..aaa903bd 100644 --- a/json/item/%name%_bricks.json +++ b/json/item/%name%_bricks.json @@ -1,3 +1,3 @@ { - "parent": "betterend:block/%name%_bricks" + "parent": "betterend:block/%name%_bricks" } \ No newline at end of file diff --git a/json/item/%name%_button.json b/json/item/%name%_button.json index 240fb2d7..83518a8e 100644 --- a/json/item/%name%_button.json +++ b/json/item/%name%_button.json @@ -1,3 +1,3 @@ { - "parent": "betterend:block/%name%_button_inventory" + "parent": "betterend:block/%name%_button_inventory" } \ No newline at end of file diff --git a/json/item/%name%_pillar.json b/json/item/%name%_pillar.json index a6257b38..a05144eb 100644 --- a/json/item/%name%_pillar.json +++ b/json/item/%name%_pillar.json @@ -1,3 +1,3 @@ { - "parent": "betterend:block/%name%_pillar" + "parent": "betterend:block/%name%_pillar" } \ No newline at end of file diff --git a/json/item/%name%_plate.json b/json/item/%name%_plate.json index d774f9bc..e0815368 100644 --- a/json/item/%name%_plate.json +++ b/json/item/%name%_plate.json @@ -1,3 +1,3 @@ { - "parent": "betterend:block/%name%_pressure_plate_up" + "parent": "betterend:block/%name%_pressure_plate_up" } \ No newline at end of file diff --git a/json/item/%name%_slab.json b/json/item/%name%_slab.json index 1c83dcd9..f6f23abc 100644 --- a/json/item/%name%_slab.json +++ b/json/item/%name%_slab.json @@ -1,3 +1,3 @@ { - "parent": "betterend:block/%name%_half_slab" + "parent": "betterend:block/%name%_half_slab" } \ No newline at end of file diff --git a/json/item/%name%_small_tiles.json b/json/item/%name%_small_tiles.json index 46e284e5..21315991 100644 --- a/json/item/%name%_small_tiles.json +++ b/json/item/%name%_small_tiles.json @@ -1,3 +1,3 @@ { - "parent": "betterend:block/%name%_small_tiles" + "parent": "betterend:block/%name%_small_tiles" } \ No newline at end of file diff --git a/json/item/%name%_stairs.json b/json/item/%name%_stairs.json index c4871532..2de302c2 100644 --- a/json/item/%name%_stairs.json +++ b/json/item/%name%_stairs.json @@ -1,3 +1,3 @@ { - "parent": "betterend:block/%name%_stairs" + "parent": "betterend:block/%name%_stairs" } \ No newline at end of file diff --git a/json/item/%name%_tile.json b/json/item/%name%_tile.json index ad863533..bb10a897 100644 --- a/json/item/%name%_tile.json +++ b/json/item/%name%_tile.json @@ -1,3 +1,3 @@ { - "parent": "betterend:block/%name%_tile" + "parent": "betterend:block/%name%_tile" } \ No newline at end of file diff --git a/json/item/%name%_wall.json b/json/item/%name%_wall.json index 59b31173..a6cf400d 100644 --- a/json/item/%name%_wall.json +++ b/json/item/%name%_wall.json @@ -1,3 +1,3 @@ { - "parent": "betterend:block/%name%_wall_inventory" + "parent": "betterend:block/%name%_wall_inventory" } \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index f91a4fe7..030f897f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,6 @@ pluginManagement { repositories { + jcenter() maven { name = 'Fabric' url = 'https://maven.fabricmc.net/' @@ -7,3 +8,39 @@ pluginManagement { gradlePluginPortal() } } +// #### Custom Settings #### + +//Change the next line to disable local BCLib loading +def allowLocalLibUse = true + +//When true, the local BCLib is also used in commandline builds +def allowLocalLibInConsoleMode = false + +//The path were to look for the local BCLib +def BCLibPath = '../BCLib' + + +// #### Logic #### +def isIDE = properties.containsKey('android.injected.invoked.from.ide') + || (System.getenv("XPC_SERVICE_NAME") ?: "").contains("intellij") + || (System.getenv("XPC_SERVICE_NAME") ?: "").contains(".idea") + || System.getenv("IDEA_INITIAL_DIRECTORY") != null + +println "IntelliJ: ${isIDE}" + +def BCLibFolder = new File( BCLibPath ) +if( allowLocalLibUse && (isIDE || allowLocalLibInConsoleMode) && BCLibFolder.exists() ) { + println "Using local BCLib from '${BCLibFolder}' in IntelliJ" + println "If you do not want to load the local version of BClib" + println "either rename the Folder containing BCLib to something" + println "else, or set 'allowLocalLibUse' in settings.gradle" + println "to false." + println "" + println "If you receive version-errors when launching minecraft" + println "in IntelliJ, make sure you have set up gradle instead" + println "of IntelliJ to compile and run." + + include ':BCLib' + project(":BCLib").projectDir = BCLibFolder + project(':BCLib').buildFileName = './bclib-composit.gradle' +} diff --git a/src/main/java/org/betterx/betterend/BetterEnd.java b/src/main/java/org/betterx/betterend/BetterEnd.java new file mode 100644 index 00000000..d3419dd2 --- /dev/null +++ b/src/main/java/org/betterx/betterend/BetterEnd.java @@ -0,0 +1,91 @@ +package org.betterx.betterend; + +import org.betterx.bclib.api.v2.generator.BiomeDecider; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.betterend.advancements.BECriteria; +import org.betterx.betterend.api.BetterEndPlugin; +import org.betterx.betterend.commands.CommandRegistry; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.effects.EndPotions; +import org.betterx.betterend.integration.Integrations; +import org.betterx.betterend.recipe.*; +import org.betterx.betterend.registry.*; +import org.betterx.betterend.util.BonemealPlants; +import org.betterx.betterend.util.LootTableUtil; +import org.betterx.betterend.world.generator.EndLandBiomeDecider; +import org.betterx.betterend.world.generator.GeneratorOptions; +import org.betterx.worlds.together.util.Logger; +import org.betterx.worlds.together.world.WorldConfig; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.biome.Biomes; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.loader.api.FabricLoader; + +public class BetterEnd implements ModInitializer { + public static final String MOD_ID = "betterend"; + public static final Logger LOGGER = new Logger(MOD_ID); + public static final boolean RUNS_TRINKETS = FabricLoader.getInstance() + .getModContainer("trinkets") + .isPresent(); + + @Override + public void onInitialize() { + WorldConfig.registerModCache(MOD_ID); + EndPortals.loadPortals(); + EndSounds.register(); + EndMenuTypes.ensureStaticallyLoaded(); + EndBlockEntities.register(); + EndPoiTypes.register(); + EndFeatures.register(); + EndEntities.register(); + EndBiomes.register(); + EndTags.register(); + EndBlocks.ensureStaticallyLoaded(); + EndItems.ensureStaticallyLoaded(); + EndEnchantments.register(); + EndPotions.register(); + CraftingRecipes.register(); + FurnaceRecipes.register(); + AlloyingRecipes.register(); + AnvilRecipes.register(); + SmithingRecipes.register(); + InfusionRecipes.register(); + EndStructures.register(); + BonemealPlants.init(); + GeneratorOptions.init(); + LootTableUtil.init(); + CommandRegistry.register(); + BECriteria.register(); + EndAdvancements.register(); + FabricLoader.getInstance() + .getEntrypoints("betterend", BetterEndPlugin.class) + .forEach(BetterEndPlugin::register); + Integrations.init(); + Configs.saveConfigs(); + + if (GeneratorOptions.useNewGenerator()) { + BiomeDecider.registerHighPriorityDecider(makeID("end_land"), new EndLandBiomeDecider()); + } + + BiomeAPI.registerEndBiomeModification((biomeID, biome) -> { + if (!biomeID.equals(Biomes.THE_VOID.location())) { + EndFeatures.addBiomeFeatures(biomeID, biome); + } + }); + + BiomeAPI.onFinishingEndBiomeTags((biomeID, biome) -> { + if (!biomeID.equals(Biomes.THE_VOID.location())) { + EndStructures.addBiomeStructures(biomeID, biome); + } + }); + if (RUNS_TRINKETS) { + org.betterx.betterend.integration.trinkets.Elytra.register(); + } + } + + public static ResourceLocation makeID(String path) { + return new ResourceLocation(MOD_ID, path); + } +} diff --git a/src/main/java/org/betterx/betterend/advancements/BECriteria.java b/src/main/java/org/betterx/betterend/advancements/BECriteria.java new file mode 100644 index 00000000..7213271a --- /dev/null +++ b/src/main/java/org/betterx/betterend/advancements/BECriteria.java @@ -0,0 +1,37 @@ +package org.betterx.betterend.advancements; + +import org.betterx.betterend.BetterEnd; + +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.advancements.critereon.EntityPredicate; +import net.minecraft.advancements.critereon.PlayerTrigger; + +public class BECriteria { + public static PlayerTrigger PORTAL_ON; + public static PlayerTrigger PORTAL_TRAVEL; + public static PlayerTrigger INFUSION_FINISHED; + + public static PlayerTrigger.TriggerInstance PORTAL_ON_TRIGGER; + public static PlayerTrigger.TriggerInstance PORTAL_TRAVEL_TRIGGER; + public static PlayerTrigger.TriggerInstance INFUSION_FINISHED_TRIGGER; + + + public static void register() { + PORTAL_ON = CriteriaTriggers.register(new PlayerTrigger(BetterEnd.makeID("portal_on"))); + PORTAL_TRAVEL = CriteriaTriggers.register(new PlayerTrigger(BetterEnd.makeID("portal_travel"))); + INFUSION_FINISHED = CriteriaTriggers.register(new PlayerTrigger(BetterEnd.makeID("infusion_finished"))); + + PORTAL_ON_TRIGGER = new PlayerTrigger.TriggerInstance( + PORTAL_ON.getId(), + EntityPredicate.Composite.ANY + ); + PORTAL_TRAVEL_TRIGGER = new PlayerTrigger.TriggerInstance( + PORTAL_TRAVEL.getId(), + EntityPredicate.Composite.ANY + ); + INFUSION_FINISHED_TRIGGER = new PlayerTrigger.TriggerInstance( + INFUSION_FINISHED.getId(), + EntityPredicate.Composite.ANY + ); + } +} diff --git a/src/main/java/org/betterx/betterend/api/BetterEndPlugin.java b/src/main/java/org/betterx/betterend/api/BetterEndPlugin.java new file mode 100644 index 00000000..9c361d3d --- /dev/null +++ b/src/main/java/org/betterx/betterend/api/BetterEndPlugin.java @@ -0,0 +1,38 @@ +package org.betterx.betterend.api; + +public interface BetterEndPlugin { + /** + * Alloying recipes registration. + * See AlloyingRecipe.Builder for details. + */ + default void registerAlloyingRecipes() { + } + + /** + * Smithing recipes registration. + * See AnvilSmithingRecipe.Builder for details. + */ + default void registerSmithingRecipes() { + } + + /** + * Additional biomes registration. + * See BiomeRegistry.registerBiome for details. + */ + default void registerEndBiomes() { + } + + /** + * Register other mod stuff, for example, EndITEM_HAMMERS. + */ + default void registerOthers() { + } + + + static void register(BetterEndPlugin plugin) { + plugin.registerAlloyingRecipes(); + plugin.registerSmithingRecipes(); + plugin.registerEndBiomes(); + plugin.registerOthers(); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/AeterniumAnvil.java b/src/main/java/org/betterx/betterend/blocks/AeterniumAnvil.java new file mode 100644 index 00000000..a4b8118a --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/AeterniumAnvil.java @@ -0,0 +1,27 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.items.BaseAnvilItem; +import org.betterx.betterend.blocks.basis.EndAnvilBlock; +import org.betterx.betterend.item.material.EndToolMaterial; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.BlockItem; + +import net.fabricmc.fabric.api.item.v1.FabricItemSettings; + +public class AeterniumAnvil extends EndAnvilBlock { + public AeterniumAnvil() { + super(EndBlocks.AETERNIUM_BLOCK.defaultMaterialColor(), EndToolMaterial.AETERNIUM.getLevel()); + } + + @Override + public int getMaxDurability() { + return 8; + } + + @Override + public BlockItem getCustomItem(ResourceLocation blockID, FabricItemSettings settings) { + return new BaseAnvilItem(this, settings.fireproof()); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/AeterniumBlock.java b/src/main/java/org/betterx/betterend/blocks/AeterniumBlock.java new file mode 100644 index 00000000..78332bbb --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/AeterniumBlock.java @@ -0,0 +1,30 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.interfaces.CustomItemProvider; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.fabric.api.item.v1.FabricItemSettings; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class AeterniumBlock extends BaseBlock implements CustomItemProvider { + public AeterniumBlock() { + super(FabricBlockSettings + .of(Material.METAL, MaterialColor.COLOR_GRAY) + .hardness(65F) + .resistance(1200F) + .requiresCorrectToolForDrops() + .sound(SoundType.NETHERITE_BLOCK) + ); + } + + @Override + public BlockItem getCustomItem(ResourceLocation blockID, FabricItemSettings settings) { + return new BlockItem(this, settings.fireproof()); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/AmaranitaCapBlock.java b/src/main/java/org/betterx/betterend/blocks/AmaranitaCapBlock.java new file mode 100644 index 00000000..8bbe7b01 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/AmaranitaCapBlock.java @@ -0,0 +1,15 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.interfaces.tools.AddMineableAxe; + +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.material.Material; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class AmaranitaCapBlock extends BaseBlock implements AddMineableAxe { + public AmaranitaCapBlock() { + super(FabricBlockSettings.of(Material.WOOD).sound(SoundType.WOOD)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/AmaranitaHymenophoreBlock.java b/src/main/java/org/betterx/betterend/blocks/AmaranitaHymenophoreBlock.java new file mode 100644 index 00000000..54b24236 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/AmaranitaHymenophoreBlock.java @@ -0,0 +1,22 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.interfaces.tools.AddMineableAxe; + +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.material.Material; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class AmaranitaHymenophoreBlock extends BaseBlock implements RenderLayerProvider, AddMineableAxe { + public AmaranitaHymenophoreBlock() { + super(FabricBlockSettings.of(Material.WOOD).sound(SoundType.WOOD)); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } +} diff --git a/src/main/java/ru/betterend/blocks/AmaranitaStemBlock.java b/src/main/java/org/betterx/betterend/blocks/AmaranitaStemBlock.java similarity index 50% rename from src/main/java/ru/betterend/blocks/AmaranitaStemBlock.java rename to src/main/java/org/betterx/betterend/blocks/AmaranitaStemBlock.java index 47885625..bc49e67b 100644 --- a/src/main/java/ru/betterend/blocks/AmaranitaStemBlock.java +++ b/src/main/java/org/betterx/betterend/blocks/AmaranitaStemBlock.java @@ -1,12 +1,14 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.blocks.BaseRotatedPillarBlock; - -public class AmaranitaStemBlock extends BaseRotatedPillarBlock { - public AmaranitaStemBlock() { - super(FabricBlockSettings.copyOf(Blocks.OAK_PLANKS).materialColor(MaterialColor.COLOR_LIGHT_GREEN)); - } -} +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseRotatedPillarBlock; + +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class AmaranitaStemBlock extends BaseRotatedPillarBlock { + public AmaranitaStemBlock() { + super(FabricBlockSettings.copyOf(Blocks.OAK_PLANKS).mapColor(MaterialColor.COLOR_LIGHT_GREEN)); + } +} diff --git a/src/main/java/ru/betterend/blocks/AmberBlock.java b/src/main/java/org/betterx/betterend/blocks/AmberBlock.java similarity index 51% rename from src/main/java/ru/betterend/blocks/AmberBlock.java rename to src/main/java/org/betterx/betterend/blocks/AmberBlock.java index feedaea8..140be91b 100644 --- a/src/main/java/ru/betterend/blocks/AmberBlock.java +++ b/src/main/java/org/betterx/betterend/blocks/AmberBlock.java @@ -1,12 +1,14 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.blocks.BaseBlock; - -public class AmberBlock extends BaseBlock { - public AmberBlock() { - super(FabricBlockSettings.copyOf(Blocks.DIAMOND_BLOCK).materialColor(MaterialColor.COLOR_YELLOW)); - } -} +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; + +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class AmberBlock extends BaseBlock { + public AmberBlock() { + super(FabricBlockSettings.copyOf(Blocks.DIAMOND_BLOCK).mapColor(MaterialColor.COLOR_YELLOW)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/AncientEmeraldIceBlock.java b/src/main/java/org/betterx/betterend/blocks/AncientEmeraldIceBlock.java new file mode 100644 index 00000000..7ba5ff0f --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/AncientEmeraldIceBlock.java @@ -0,0 +1,89 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndParticles; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Collections; +import java.util.List; + +public class AncientEmeraldIceBlock extends BaseBlock { + public AncientEmeraldIceBlock() { + super(FabricBlockSettings.copyOf(Blocks.BLUE_ICE).randomTicks()); + } + + @Override + @SuppressWarnings("deprecation") + public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + Direction dir = BlocksHelper.randomDirection(random); + + if (random.nextBoolean()) { + int x = MHelper.randRange(-2, 2, random); + int y = MHelper.randRange(-2, 2, random); + int z = MHelper.randRange(-2, 2, random); + BlockPos p = pos.offset(x, y, z); + if (world.getBlockState(p).is(Blocks.WATER)) { + world.setBlockAndUpdate(p, EndBlocks.EMERALD_ICE.defaultBlockState()); + makeParticles(world, p, random); + } + } + + pos = pos.relative(dir); + state = world.getBlockState(pos); + if (state.is(Blocks.WATER)) { + world.setBlockAndUpdate(pos, EndBlocks.EMERALD_ICE.defaultBlockState()); + makeParticles(world, pos, random); + } else if (state.is(EndBlocks.EMERALD_ICE)) { + world.setBlockAndUpdate(pos, EndBlocks.DENSE_EMERALD_ICE.defaultBlockState()); + makeParticles(world, pos, random); + } + } + + private void makeParticles(ServerLevel world, BlockPos pos, RandomSource random) { + world.sendParticles( + EndParticles.SNOWFLAKE, + pos.getX() + 0.5, + pos.getY() + 0.5, + pos.getZ() + 0.5, + 20, + 0.5, + 0.5, + 0.5, + 0 + ); + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + ItemStack tool = builder.getOptionalParameter(LootContextParams.TOOL); + if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) != 0) { + return Collections.singletonList(new ItemStack(this)); + } else { + return Collections.emptyList(); + } + } + + @Override + public void stepOn(Level level, BlockPos blockPos, BlockState blockState, Entity entity) { + super.stepOn(level, blockPos, blockState, entity); + entity.setIsInPowderSnow(true); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/AuroraCrystalBlock.java b/src/main/java/org/betterx/betterend/blocks/AuroraCrystalBlock.java new file mode 100644 index 00000000..bec8657b --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/AuroraCrystalBlock.java @@ -0,0 +1,134 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.CustomColorProvider; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.interfaces.tools.AddMineableHammer; +import org.betterx.bclib.interfaces.tools.AddMineablePickaxe; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndItems; +import org.betterx.ui.ColorUtil; + +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.item.ItemColor; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; +import net.minecraft.util.Mth; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.AbstractGlassBlock; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Lists; + +import java.util.List; + +public class AuroraCrystalBlock extends AbstractGlassBlock implements RenderLayerProvider, CustomColorProvider, AddMineablePickaxe, AddMineableHammer { + public static final Vec3i[] COLORS; + private static final int MIN_DROP = 1; + private static final int MAX_DROP = 4; + + public AuroraCrystalBlock() { + super(FabricBlockSettings + .of(Material.GLASS) + .hardness(1F) + .resistance(1F) + .luminance(15) + .noOcclusion() + .isSuffocating((state, world, pos) -> false) + .sound(SoundType.GLASS)); + } + + @Override + @Deprecated + public VoxelShape getVisualShape( + BlockState blockState, + BlockGetter blockGetter, + BlockPos blockPos, + CollisionContext collisionContext + ) { + return this.getCollisionShape(blockState, blockGetter, blockPos, collisionContext); + } + + @Override + public BlockColor getProvider() { + return (state, world, pos, tintIndex) -> { + if (pos == null) { + pos = BlockPos.ZERO; + } + + long i = (long) pos.getX() + (long) pos.getY() + (long) pos.getZ(); + double delta = i * 0.1; + int index = MHelper.floor(delta); + int index2 = (index + 1) & 3; + delta -= index; + index &= 3; + + Vec3i color1 = COLORS[index]; + Vec3i color2 = COLORS[index2]; + + int r = MHelper.floor(Mth.lerp(delta, color1.getX(), color2.getX())); + int g = MHelper.floor(Mth.lerp(delta, color1.getY(), color2.getY())); + int b = MHelper.floor(Mth.lerp(delta, color1.getZ(), color2.getZ())); + + return ColorUtil.color(r, g, b); + }; + } + + @Override + public ItemColor getItemProvider() { + return (stack, tintIndex) -> { + return ColorUtil.color(COLORS[3].getX(), COLORS[3].getY(), COLORS[3].getZ()); + }; + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.TRANSLUCENT; + } + + @Override + @SuppressWarnings("deprecation") + public List getDrops(BlockState state, LootContext.Builder builder) { + ItemStack tool = builder.getParameter(LootContextParams.TOOL); + if (tool != null && tool.isCorrectToolForDrops(state)) { + int count = 0; + int enchant = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool); + if (enchant > 0) { + return Lists.newArrayList(new ItemStack(this)); + } + enchant = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, tool); + if (enchant > 0) { + int min = Mth.clamp(MIN_DROP + enchant, MIN_DROP, MAX_DROP); + int max = MAX_DROP + (enchant / Enchantments.BLOCK_FORTUNE.getMaxLevel()); + if (min == max) { + return Lists.newArrayList(new ItemStack(EndItems.CRYSTAL_SHARDS, max)); + } + count = MHelper.randRange(min, max, MHelper.RANDOM_SOURCE); + } else { + count = MHelper.randRange(MIN_DROP, MAX_DROP, MHelper.RANDOM_SOURCE); + } + return Lists.newArrayList(new ItemStack(EndItems.CRYSTAL_SHARDS, count)); + } + return Lists.newArrayList(); + } + + static { + COLORS = new Vec3i[]{ + new Vec3i(247, 77, 161), + new Vec3i(120, 184, 255), + new Vec3i(120, 255, 168), + new Vec3i(243, 58, 255) + }; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/BlueVineBlock.java b/src/main/java/org/betterx/betterend/blocks/BlueVineBlock.java new file mode 100644 index 00000000..d901c913 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/BlueVineBlock.java @@ -0,0 +1,24 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.UpDownPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.EnumProperty; + +public class BlueVineBlock extends UpDownPlantBlock { + public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(SHAPE); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.getBlock() == EndBlocks.END_MOSS || state.getBlock() == EndBlocks.END_MYCELIUM; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/BlueVineLanternBlock.java b/src/main/java/org/betterx/betterend/blocks/BlueVineLanternBlock.java new file mode 100644 index 00000000..a9275dee --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/BlueVineLanternBlock.java @@ -0,0 +1,59 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.interfaces.tools.AddMineableAxe; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.Material; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class BlueVineLanternBlock extends BaseBlock implements AddMineableAxe { + public static final BooleanProperty NATURAL = BlockProperties.NATURAL; + + public BlueVineLanternBlock() { + super(FabricBlockSettings.of(Material.WOOD) + .luminance(15) + .sound(SoundType.WART_BLOCK)); + this.registerDefaultState(this.stateDefinition.any().setValue(NATURAL, false)); + } + + @Override + @SuppressWarnings("deprecation") + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + return !state.getValue(NATURAL) || world.getBlockState(pos.below()).getBlock() == EndBlocks.BLUE_VINE; + } + + @Override + @SuppressWarnings("deprecation") + public BlockState updateShape( + BlockState state, + Direction facing, + BlockState neighborState, + LevelAccessor world, + BlockPos pos, + BlockPos neighborPos + ) { + if (!canSurvive(state, world, pos)) { + return Blocks.AIR.defaultBlockState(); + } else { + return state; + } + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(NATURAL); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/BlueVineSeedBlock.java b/src/main/java/org/betterx/betterend/blocks/BlueVineSeedBlock.java new file mode 100644 index 00000000..e564f016 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/BlueVineSeedBlock.java @@ -0,0 +1,81 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; +import org.betterx.betterend.blocks.basis.FurBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; + +public class BlueVineSeedBlock extends EndPlantWithAgeBlock { + public BlueVineSeedBlock() { + super(basePlantSettings().offsetType(BlockBehaviour.OffsetType.NONE)); + } + + @Override + public void growAdult(WorldGenLevel world, RandomSource random, BlockPos pos) { + int height = MHelper.randRange(2, 5, random); + int h = BlocksHelper.upRay(world, pos, height + 2); + if (h < height + 1) { + return; + } + BlocksHelper.setWithoutUpdate( + world, + pos, + EndBlocks.BLUE_VINE.defaultBlockState() + .setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.BOTTOM) + ); + for (int i = 1; i < height; i++) { + BlocksHelper.setWithoutUpdate( + world, + pos.above(i), + EndBlocks.BLUE_VINE.defaultBlockState() + .setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.MIDDLE) + ); + } + BlocksHelper.setWithoutUpdate( + world, + pos.above(height), + EndBlocks.BLUE_VINE.defaultBlockState() + .setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.TOP) + ); + placeLantern(world, pos.above(height + 1)); + } + + private void placeLantern(WorldGenLevel world, BlockPos pos) { + BlocksHelper.setWithoutUpdate( + world, + pos, + EndBlocks.BLUE_VINE_LANTERN.defaultBlockState().setValue(BlueVineLanternBlock.NATURAL, true) + ); + for (Direction dir : BlocksHelper.HORIZONTAL) { + BlockPos p = pos.relative(dir); + if (world.isEmptyBlock(p)) { + BlocksHelper.setWithoutUpdate( + world, + p, + EndBlocks.BLUE_VINE_FUR.defaultBlockState().setValue(FurBlock.FACING, dir) + ); + } + } + if (world.isEmptyBlock(pos.above())) { + BlocksHelper.setWithoutUpdate( + world, + pos.above(), + EndBlocks.BLUE_VINE_FUR.defaultBlockState().setValue(FurBlock.FACING, Direction.UP) + ); + } + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.END_MOSS) || state.is(EndBlocks.END_MYCELIUM); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/BoluxMushroomBlock.java b/src/main/java/org/betterx/betterend/blocks/BoluxMushroomBlock.java new file mode 100644 index 00000000..d66249c4 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/BoluxMushroomBlock.java @@ -0,0 +1,54 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.EndPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import com.google.common.collect.Lists; + +import java.util.List; + +public class BoluxMushroomBlock extends EndPlantBlock { + private static final VoxelShape SHAPE = Block.box(1, 0, 1, 15, 9, 15); + + public BoluxMushroomBlock() { + super(basePlantSettings(10).offsetType(BlockBehaviour.OffsetType.NONE)); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.RUTISCUS); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return SHAPE; + } + + + @Override + public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { + return false; + } + + @Override + public boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state) { + return false; + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + return Lists.newArrayList(new ItemStack(this)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/BrimstoneBlock.java b/src/main/java/org/betterx/betterend/blocks/BrimstoneBlock.java new file mode 100644 index 00000000..b326e484 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/BrimstoneBlock.java @@ -0,0 +1,108 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import org.jetbrains.annotations.Nullable; + +public class BrimstoneBlock extends BaseBlock { + public static final BooleanProperty ACTIVATED = BlockProperties.ACTIVE; + + public BrimstoneBlock() { + super(FabricBlockSettings.copyOf(Blocks.END_STONE).mapColor(MaterialColor.COLOR_BROWN).randomTicks()); + registerDefaultState(stateDefinition.any().setValue(ACTIVATED, false)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(ACTIVATED); + } + + @Override + public void setPlacedBy( + Level world, + BlockPos pos, + BlockState state, + @Nullable LivingEntity placer, + ItemStack itemStack + ) { + if (world.isClientSide()) { + updateChunks((ClientLevel) world, pos); + } + } + + public void destroy(LevelAccessor world, BlockPos pos, BlockState state) { + if (world.isClientSide()) { + updateChunks((ClientLevel) world, pos); + } + } + + private void updateChunks(ClientLevel world, BlockPos pos) { + int y = pos.getY() >> 4; + int x1 = (pos.getX() - 2) >> 4; + int z1 = (pos.getZ() - 2) >> 4; + int x2 = (pos.getX() + 2) >> 4; + int z2 = (pos.getZ() + 2) >> 4; + for (int x = x1; x <= x2; x++) { + for (int z = z1; z <= z2; z++) { + world.setSectionDirtyWithNeighbors(x, y, z); + } + } + } + + @Override + @SuppressWarnings("deprecation") + public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + boolean deactivate = true; + for (Direction dir : BlocksHelper.DIRECTIONS) { + if (world.getFluidState(pos.relative(dir)).getType().equals(Fluids.WATER)) { + deactivate = false; + break; + } + } + if (state.getValue(ACTIVATED)) { + if (deactivate) { + world.setBlockAndUpdate(pos, defaultBlockState().setValue(ACTIVATED, false)); + } else if (state.getValue(ACTIVATED) && random.nextInt(16) == 0) { + Direction dir = BlocksHelper.randomDirection(random); + BlockPos side = pos.relative(dir); + BlockState sideState = world.getBlockState(side); + if (sideState.getBlock() instanceof SulphurCrystalBlock) { + if (sideState.getValue(SulphurCrystalBlock.AGE) < 2 && sideState.getValue(SulphurCrystalBlock.WATERLOGGED)) { + int age = sideState.getValue(SulphurCrystalBlock.AGE) + 1; + world.setBlockAndUpdate(side, sideState.setValue(SulphurCrystalBlock.AGE, age)); + } + } else if (sideState.getFluidState().getType() == Fluids.WATER) { + BlockState crystal = EndBlocks.SULPHUR_CRYSTAL.defaultBlockState() + .setValue(SulphurCrystalBlock.FACING, dir) + .setValue(SulphurCrystalBlock.WATERLOGGED, true) + .setValue(SulphurCrystalBlock.AGE, 0); + world.setBlockAndUpdate(side, crystal); + } + } + } else if (!deactivate && !state.getValue(ACTIVATED)) { + world.setBlockAndUpdate(pos, defaultBlockState().setValue(ACTIVATED, true)); + } + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/BubbleCoralBlock.java b/src/main/java/org/betterx/betterend/blocks/BubbleCoralBlock.java new file mode 100644 index 00000000..183b0320 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/BubbleCoralBlock.java @@ -0,0 +1,54 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.interfaces.tools.AddMineableShears; +import org.betterx.betterend.blocks.basis.EndUnderwaterPlantBlock; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class BubbleCoralBlock extends EndUnderwaterPlantBlock implements AddMineableShears { + + private static final VoxelShape SHAPE = Block.box(0, 0, 0, 16, 14, 16); + + public BubbleCoralBlock() { + super(baseUnderwaterPlantSettings() + .sound(SoundType.CORAL_BLOCK) + .offsetType(BlockBehaviour.OffsetType.NONE) + ); + } + + @Environment(EnvType.CLIENT) + public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) { + double x = pos.getX() + random.nextDouble(); + double y = pos.getY() + random.nextDouble() * 0.5F + 0.5F; + double z = pos.getZ() + random.nextDouble(); + world.addParticle(ParticleTypes.BUBBLE, x, y, z, 0.0D, 0.0D, 0.0D); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return SHAPE; + } + + @Override + public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { + return false; + } + + @Override + public boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state) { + return false; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/BulbVineBlock.java b/src/main/java/org/betterx/betterend/blocks/BulbVineBlock.java new file mode 100644 index 00000000..e81b773a --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/BulbVineBlock.java @@ -0,0 +1,49 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseVineBlock; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.loot.LootContext; + +import com.google.common.collect.Lists; + +import java.util.List; + +public class BulbVineBlock extends BaseVineBlock { + public BulbVineBlock() { + super(15, true); + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + if (state.getValue(SHAPE) == TripleShape.BOTTOM) { + return Lists.newArrayList(new ItemStack(EndItems.GLOWING_BULB)); + } else if (MHelper.RANDOM.nextInt(8) == 0) { + return Lists.newArrayList(new ItemStack(EndBlocks.BULB_VINE_SEED)); + } else { + return Lists.newArrayList(); + } + } + + @Override + public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { + return false; + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + boolean canPlace = super.canSurvive(state, world, pos); + return (state.is(this) && state.getValue(SHAPE) == TripleShape.BOTTOM) + ? canPlace + : canPlace && world.getBlockState( + pos.below()).is(this); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/BulbVineLanternBlock.java b/src/main/java/org/betterx/betterend/blocks/BulbVineLanternBlock.java new file mode 100644 index 00000000..adac7fdf --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/BulbVineLanternBlock.java @@ -0,0 +1,87 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.client.models.ModelsHelper; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.BlockModelProvider; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.interfaces.tools.AddMineablePickaxe; +import org.betterx.betterend.blocks.basis.EndLanternBlock; +import org.betterx.betterend.client.models.Patterns; + +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.material.MaterialColor; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Maps; + +import java.util.Map; +import java.util.Optional; +import org.jetbrains.annotations.Nullable; + +public class BulbVineLanternBlock extends EndLanternBlock implements RenderLayerProvider, BlockModelProvider, AddMineablePickaxe { + private static final VoxelShape SHAPE_CEIL = Block.box(4, 4, 4, 12, 16, 12); + private static final VoxelShape SHAPE_FLOOR = Block.box(4, 0, 4, 12, 12, 12); + + public BulbVineLanternBlock() { + this(FabricBlockSettings.of(Material.METAL) + .hardness(1) + .resistance(1) + .mapColor(MaterialColor.COLOR_LIGHT_GRAY) + .luminance(15) + .requiresCorrectToolForDrops() + .sound(SoundType.LANTERN)); + } + + public BulbVineLanternBlock(Properties settings) { + super(settings); + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return state.getValue(IS_FLOOR) ? SHAPE_FLOOR : SHAPE_CEIL; + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + @Override + @Environment(EnvType.CLIENT) + public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { + Map textures = Maps.newHashMap(); + textures.put("%glow%", getGlowTexture()); + textures.put("%metal%", getMetalTexture(resourceLocation)); + Optional pattern = blockState.getValue(IS_FLOOR) + ? Patterns.createJson( + Patterns.BLOCK_BULB_LANTERN_FLOOR, + textures + ) + : Patterns.createJson(Patterns.BLOCK_BULB_LANTERN_CEIL, textures); + return ModelsHelper.fromPattern(pattern); + } + + protected String getMetalTexture(ResourceLocation blockId) { + String name = blockId.getPath(); + name = name.substring(0, name.indexOf('_')); + return name + "_bulb_vine_lantern_metal"; + } + + protected String getGlowTexture() { + return "bulb_vine_lantern_bulb"; + } + +} diff --git a/src/main/java/org/betterx/betterend/blocks/BulbVineLanternColoredBlock.java b/src/main/java/org/betterx/betterend/blocks/BulbVineLanternColoredBlock.java new file mode 100644 index 00000000..a613733f --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/BulbVineLanternColoredBlock.java @@ -0,0 +1,40 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.interfaces.CustomColorProvider; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.ui.ColorUtil; + +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.item.ItemColor; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class BulbVineLanternColoredBlock extends BulbVineLanternBlock implements CustomColorProvider { + public BulbVineLanternColoredBlock(FabricBlockSettings settings) { + super(settings); + } + + @Override + public BlockColor getProvider() { + return (state, world, pos, tintIndex) -> getColor(); + } + + @Override + public ItemColor getItemProvider() { + return (stack, tintIndex) -> getColor(); + } + + private int getColor() { + int color = BlocksHelper.getBlockColor(this); + int b = (color & 255); + int g = ((color >> 8) & 255); + int r = ((color >> 16) & 255); + float[] hsv = ColorUtil.RGBtoHSB(r, g, b, new float[3]); + return ColorUtil.HSBtoRGB(hsv[0], hsv[1], hsv[1] > 0.2 ? 1 : hsv[2]); + } + + @Override + protected String getGlowTexture() { + return "bulb_vine_lantern_overlay"; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/BulbVineSeedBlock.java b/src/main/java/org/betterx/betterend/blocks/BulbVineSeedBlock.java new file mode 100644 index 00000000..3278d930 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/BulbVineSeedBlock.java @@ -0,0 +1,49 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; + +public class BulbVineSeedBlock extends EndPlantWithAgeBlock { + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + BlockState up = world.getBlockState(pos.above()); + return up.is(CommonBlockTags.GEN_END_STONES) || up.is(BlockTags.LOGS) || up.is(BlockTags.LEAVES); + } + + @Override + public void growAdult(WorldGenLevel world, RandomSource random, BlockPos pos) { + int h = BlocksHelper.downRay(world, pos, random.nextInt(24)) - 1; + if (h > 2) { + BlocksHelper.setWithoutUpdate( + world, + pos, + EndBlocks.BULB_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP) + ); + for (int i = 1; i < h; i++) { + BlocksHelper.setWithoutUpdate( + world, + pos.below(i), + EndBlocks.BULB_VINE.defaultBlockState() + .setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE) + ); + } + BlocksHelper.setWithoutUpdate( + world, + pos.below(h), + EndBlocks.BULB_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM) + ); + } + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/CavePumpkinBlock.java b/src/main/java/org/betterx/betterend/blocks/CavePumpkinBlock.java new file mode 100644 index 00000000..cbb741f9 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/CavePumpkinBlock.java @@ -0,0 +1,72 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlockNotFull; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Collections; +import java.util.List; + +public class CavePumpkinBlock extends BaseBlockNotFull implements RenderLayerProvider { + public static final BooleanProperty SMALL = BlockProperties.SMALL; + private static final VoxelShape SHAPE_SMALL; + private static final VoxelShape SHAPE_BIG; + + public CavePumpkinBlock() { + super(FabricBlockSettings.copyOf(Blocks.PUMPKIN).luminance((state) -> state.getValue(SMALL) ? 10 : 15)); + registerDefaultState(defaultBlockState().setValue(SMALL, false)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(SMALL); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + return state.getValue(SMALL) ? SHAPE_SMALL : SHAPE_BIG; + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + return state.getValue(SMALL) + ? Collections.singletonList(new ItemStack(EndBlocks.CAVE_PUMPKIN_SEED)) + : Collections + .singletonList(new ItemStack(this)); + } + + static { + VoxelShape lantern = Block.box(1, 0, 1, 15, 13, 15); + VoxelShape cap = Block.box(0, 12, 0, 16, 15, 16); + VoxelShape top = Block.box(5, 15, 5, 11, 16, 11); + SHAPE_BIG = Shapes.or(lantern, cap, top); + + lantern = Block.box(5, 7, 5, 11, 13, 11); + cap = Block.box(4, 12, 4, 12, 15, 12); + top = Block.box(6, 15, 6, 10, 16, 10); + SHAPE_SMALL = Shapes.or(lantern, cap, top); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/CavePumpkinVineBlock.java b/src/main/java/org/betterx/betterend/blocks/CavePumpkinVineBlock.java new file mode 100644 index 00000000..caf690c5 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/CavePumpkinVineBlock.java @@ -0,0 +1,81 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +public class CavePumpkinVineBlock extends EndPlantWithAgeBlock { + public CavePumpkinVineBlock() { + super(basePlantSettings().offsetType(BlockBehaviour.OffsetType.NONE)); + } + + private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 16, 12); + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + BlockState down = world.getBlockState(pos.above()); + return isTerrain(down); + } + + @Override + public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { + int age = state.getValue(AGE); + BlockState down = world.getBlockState(pos.below()); + if (down.getMaterial() + .isReplaceable() || (down.is(EndBlocks.CAVE_PUMPKIN) && down.getValue(BlockProperties.SMALL))) { + if (age < 3) { + world.setBlockAndUpdate(pos, state.setValue(AGE, age + 1)); + } + if (age == 2) { + world.setBlockAndUpdate( + pos.below(), + EndBlocks.CAVE_PUMPKIN.defaultBlockState().setValue(BlockProperties.SMALL, true) + ); + } else if (age == 3) { + world.setBlockAndUpdate(pos.below(), EndBlocks.CAVE_PUMPKIN.defaultBlockState()); + } + } + } + + @Override + public void growAdult(WorldGenLevel world, RandomSource random, BlockPos pos) { + } + + @Override + public BlockState updateShape( + BlockState state, + Direction facing, + BlockState neighborState, + LevelAccessor world, + BlockPos pos, + BlockPos neighborPos + ) { + state = super.updateShape(state, facing, neighborState, world, pos, neighborPos); + if (state.is(this) && state.getValue(BlockProperties.AGE) > 1) { + BlockState down = world.getBlockState(pos.below()); + if (!down.is(EndBlocks.CAVE_PUMPKIN)) { + state = state.setValue(BlockProperties.AGE, 1); + } + } + return state; + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return SHAPE; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/ChandelierBlock.java b/src/main/java/org/betterx/betterend/blocks/ChandelierBlock.java new file mode 100644 index 00000000..1ed3bebd --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/ChandelierBlock.java @@ -0,0 +1,120 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseAttachedBlock; +import org.betterx.bclib.client.models.ModelsHelper; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.BlockModelProvider; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.betterend.client.models.Patterns; + +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.resources.model.BlockModelRotation; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Maps; + +import java.util.EnumMap; +import java.util.Map; +import java.util.Optional; +import org.jetbrains.annotations.Nullable; + +public class ChandelierBlock extends BaseAttachedBlock implements RenderLayerProvider, BlockModelProvider { + private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(Direction.class); + + public ChandelierBlock(Block source) { + super(FabricBlockSettings.copyOf(source) + .luminance(15) + .noCollission() + .noOcclusion() + .requiresCorrectToolForDrops()); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return BOUNDING_SHAPES.get(state.getValue(FACING)); + } + + @Override + @Environment(EnvType.CLIENT) + public BlockModel getItemModel(ResourceLocation blockId) { + return ModelsHelper.createItemModel(blockId); + } + + @Override + @Environment(EnvType.CLIENT) + public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { + Optional pattern; + switch (blockState.getValue(FACING)) { + case UP: + pattern = Patterns.createJson(Patterns.BLOCK_CHANDELIER_FLOOR, resourceLocation.getPath()); + break; + case DOWN: + pattern = Patterns.createJson(Patterns.BLOCK_CHANDELIER_CEIL, resourceLocation.getPath()); + break; + default: + pattern = Patterns.createJson(Patterns.BLOCK_CHANDELIER_WALL, resourceLocation.getPath()); + } + return ModelsHelper.fromPattern(pattern); + } + + @Override + @Environment(EnvType.CLIENT) + public UnbakedModel getModelVariant( + ResourceLocation stateId, + BlockState blockState, + Map modelCache + ) { + String state = "_wall"; + BlockModelRotation rotation = BlockModelRotation.X0_Y0; + switch (blockState.getValue(FACING)) { + case UP: + state = "_floor"; + break; + case DOWN: + state = "_ceil"; + break; + case EAST: + rotation = BlockModelRotation.X0_Y270; + break; + case NORTH: + rotation = BlockModelRotation.X0_Y180; + break; + case WEST: + rotation = BlockModelRotation.X0_Y90; + break; + default: + break; + } + ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath() + state); + registerBlockModel(stateId, modelId, blockState, modelCache); + return ModelsHelper.createMultiVariant(modelId, rotation.getRotation(), false); + } + + static { + BOUNDING_SHAPES.put(Direction.UP, Block.box(5, 0, 5, 11, 13, 11)); + BOUNDING_SHAPES.put(Direction.DOWN, Block.box(5, 3, 5, 11, 16, 11)); + BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.0, 0.0, 0.5, 1.0, 1.0, 1.0)); + BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 0.5)); + BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.5, 0.0, 0.0, 1.0, 1.0, 1.0)); + BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.0, 0.0, 0.5, 1.0, 1.0)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/CharcoalBlock.java b/src/main/java/org/betterx/betterend/blocks/CharcoalBlock.java new file mode 100644 index 00000000..11e12b5b --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/CharcoalBlock.java @@ -0,0 +1,19 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.interfaces.Fuel; + +import net.minecraft.world.level.block.Blocks; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class CharcoalBlock extends BaseBlock implements Fuel { + public CharcoalBlock() { + super(FabricBlockSettings.copyOf(Blocks.COAL_BLOCK)); + } + + @Override + public int getFuelTime() { + return 16000; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/CharniaBlock.java b/src/main/java/org/betterx/betterend/blocks/CharniaBlock.java new file mode 100644 index 00000000..86744d20 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/CharniaBlock.java @@ -0,0 +1,17 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.EndUnderwaterPlantBlock; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluids; + +public class CharniaBlock extends EndUnderwaterPlantBlock { + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + return canSupportCenter(world, pos.below(), Direction.UP) && world.getFluidState(pos).getType() == Fluids.WATER; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/ChorusGrassBlock.java b/src/main/java/org/betterx/betterend/blocks/ChorusGrassBlock.java new file mode 100644 index 00000000..f4b6feb7 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/ChorusGrassBlock.java @@ -0,0 +1,17 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.EndPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.world.level.block.state.BlockState; + +public class ChorusGrassBlock extends EndPlantBlock { + public ChorusGrassBlock() { + super(true); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.getBlock() == EndBlocks.CHORUS_NYLIUM; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/CrystalMossCoverBlock.java b/src/main/java/org/betterx/betterend/blocks/CrystalMossCoverBlock.java new file mode 100644 index 00000000..aeade1af --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/CrystalMossCoverBlock.java @@ -0,0 +1,122 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class CrystalMossCoverBlock extends MultifaceBlock implements BonemealableBlock, SimpleWaterloggedBlock, RenderLayerProvider { + private static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + private final MultifaceSpreader spreader = new MultifaceSpreader(this); + + public CrystalMossCoverBlock(MaterialColor color) { + super(FabricBlockSettings.of(Material.REPLACEABLE_PLANT, color) + .noCollission() + .strength(0.2f) + .sound(SoundType.GLOW_LICHEN) + .lightLevel(GlowLichenBlock.emission(7))); + this.registerDefaultState(this.defaultBlockState().setValue(WATERLOGGED, false)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + super.createBlockStateDefinition(builder); + builder.add(WATERLOGGED); + } + + @Override + public BlockState updateShape( + BlockState blockState, + Direction direction, + BlockState blockState2, + LevelAccessor levelAccessor, + BlockPos blockPos, + BlockPos blockPos2 + ) { + if (blockState.getValue(WATERLOGGED).booleanValue()) { + levelAccessor.scheduleTick(blockPos, Fluids.WATER, Fluids.WATER.getTickDelay(levelAccessor)); + } + return super.updateShape(blockState, direction, blockState2, levelAccessor, blockPos, blockPos2); + } + + @Override + public boolean canBeReplaced(BlockState blockState, BlockPlaceContext blockPlaceContext) { + return !blockPlaceContext.getItemInHand().is(EndBlocks.CRYSTAL_MOSS_COVER.asItem()) || super.canBeReplaced( + blockState, + blockPlaceContext + ); + } + + @Override + public boolean isValidBonemealTarget( + BlockGetter blockGetter, + BlockPos blockPos, + BlockState blockState, + boolean bl + ) { + return Direction.stream() + .anyMatch(direction -> this.spreader.canSpreadInAnyDirection( + blockState, + blockGetter, + blockPos, + direction.getOpposite() + )); + } + + @Override + public boolean isBonemealSuccess(Level level, RandomSource randomSource, BlockPos blockPos, BlockState blockState) { + return true; + } + + @Override + public void performBonemeal( + ServerLevel serverLevel, + RandomSource randomSource, + BlockPos blockPos, + BlockState blockState + ) { + this.spreader.spreadFromRandomFaceTowardRandomDirection(blockState, serverLevel, blockPos, randomSource); + } + + @Override + public FluidState getFluidState(BlockState blockState) { + if (blockState.getValue(WATERLOGGED).booleanValue()) { + return Fluids.WATER.getSource(false); + } + return super.getFluidState(blockState); + } + + @Override + public boolean propagatesSkylightDown(BlockState blockState, BlockGetter blockGetter, BlockPos blockPos) { + return blockState.getFluidState().isEmpty(); + } + + @Override + public MultifaceSpreader getSpreader() { + return this.spreader; + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/DenseEmeraldIceBlock.java b/src/main/java/org/betterx/betterend/blocks/DenseEmeraldIceBlock.java new file mode 100644 index 00000000..d3a4ce9e --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/DenseEmeraldIceBlock.java @@ -0,0 +1,39 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Collections; +import java.util.List; + +public class DenseEmeraldIceBlock extends BaseBlock implements RenderLayerProvider { + public DenseEmeraldIceBlock() { + super(FabricBlockSettings.copyOf(Blocks.PACKED_ICE)); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.TRANSLUCENT; + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + ItemStack tool = builder.getOptionalParameter(LootContextParams.TOOL); + if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) != 0) { + return Collections.singletonList(new ItemStack(this)); + } else { + return Collections.emptyList(); + } + } +} diff --git a/src/main/java/ru/betterend/blocks/DenseSnowBlock.java b/src/main/java/org/betterx/betterend/blocks/DenseSnowBlock.java similarity index 52% rename from src/main/java/ru/betterend/blocks/DenseSnowBlock.java rename to src/main/java/org/betterx/betterend/blocks/DenseSnowBlock.java index 1371de16..87033f69 100644 --- a/src/main/java/ru/betterend/blocks/DenseSnowBlock.java +++ b/src/main/java/org/betterx/betterend/blocks/DenseSnowBlock.java @@ -1,12 +1,14 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.material.Material; -import ru.bclib.blocks.BaseBlock; - -public class DenseSnowBlock extends BaseBlock { - public DenseSnowBlock() { - super(FabricBlockSettings.of(Material.SNOW).strength(0.2F).sound(SoundType.SNOW)); - } -} +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; + +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.material.Material; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class DenseSnowBlock extends BaseBlock { + public DenseSnowBlock() { + super(FabricBlockSettings.of(Material.SNOW).strength(0.2F).sound(SoundType.SNOW)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/DragonTreeSaplingBlock.java b/src/main/java/org/betterx/betterend/blocks/DragonTreeSaplingBlock.java new file mode 100644 index 00000000..c722f64a --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/DragonTreeSaplingBlock.java @@ -0,0 +1,28 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.PottableFeatureSapling; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.features.trees.DragonTreeFeature; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class DragonTreeSaplingBlock extends PottableFeatureSapling { + public DragonTreeSaplingBlock() { + super((state) -> EndFeatures.DRAGON_TREE.configuredFeature); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + return world.getBlockState(pos.below()).is(EndBlocks.SHADOW_GRASS); + } + + @Override + public boolean canPlantOn(Block block) { + return block == EndBlocks.SHADOW_GRASS; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EmeraldIceBlock.java b/src/main/java/org/betterx/betterend/blocks/EmeraldIceBlock.java new file mode 100644 index 00000000..fc3dd81b --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EmeraldIceBlock.java @@ -0,0 +1,102 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.BlockModelProvider; +import org.betterx.bclib.interfaces.RenderLayerProvider; + +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LightLayer; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.HalfTransparentBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Collections; +import java.util.List; +import org.jetbrains.annotations.Nullable; + +public class EmeraldIceBlock extends HalfTransparentBlock implements RenderLayerProvider, BlockModelProvider { + public EmeraldIceBlock() { + super(FabricBlockSettings.copyOf(Blocks.ICE)); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.TRANSLUCENT; + } + + @Override + public void playerDestroy( + Level world, + Player player, + BlockPos pos, + BlockState state, + @Nullable BlockEntity blockEntity, + ItemStack stack + ) { + super.playerDestroy(world, player, pos, state, blockEntity, stack); + if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, stack) == 0) { + if (world.dimensionType().ultraWarm()) { + world.removeBlock(pos, false); + return; + } + + Material material = world.getBlockState(pos.below()).getMaterial(); + if (material.blocksMotion() || material.isLiquid()) { + world.setBlockAndUpdate(pos, Blocks.WATER.defaultBlockState()); + } + } + + } + + @Override + @SuppressWarnings("deprecation") + public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + if (world.getBrightness(LightLayer.BLOCK, pos) > 11 - state.getLightBlock(world, pos)) { + this.melt(state, world, pos); + } + + } + + protected void melt(BlockState state, Level world, BlockPos pos) { + if (world.dimensionType().ultraWarm()) { + world.removeBlock(pos, false); + } else { + world.setBlockAndUpdate(pos, Blocks.WATER.defaultBlockState()); + world.neighborChanged(pos, Blocks.WATER, pos); + } + } + + @Override + @SuppressWarnings("deprecation") + public List getDrops(BlockState state, LootContext.Builder builder) { + ItemStack tool = builder.getOptionalParameter(LootContextParams.TOOL); + if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) != 0) { + return Collections.singletonList(new ItemStack(this)); + } else { + return Collections.emptyList(); + } + } + + @Override + @Environment(EnvType.CLIENT) + public BlockModel getItemModel(ResourceLocation resourceLocation) { + return getBlockModel(resourceLocation, defaultBlockState()); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EndBlockProperties.java b/src/main/java/org/betterx/betterend/blocks/EndBlockProperties.java new file mode 100644 index 00000000..8b8b20e4 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EndBlockProperties.java @@ -0,0 +1,131 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.betterend.registry.EndPortals; + +import net.minecraft.util.StringRepresentable; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; + +public class EndBlockProperties extends BlockProperties { + public static final EnumProperty HYDRALUX_SHAPE = EnumProperty.create("shape", HydraluxShape.class); + public static final EnumProperty PEDESTAL_STATE = EnumProperty.create("state", PedestalState.class); + public static final EnumProperty CACTUS_BOTTOM = EnumProperty.create("bottom", CactusBottom.class); + + public static final IntegerProperty PORTAL = IntegerProperty.create("portal", 0, EndPortals.getCount()); + public static final IntegerProperty PLANT_ID = IntegerProperty.create("plant_id", 0, 63); + public static final IntegerProperty SOIL_ID = IntegerProperty.create("soil_id", 0, 16); + public static final IntegerProperty POT_LIGHT = IntegerProperty.create("pot_light", 0, 3); + public static final BooleanProperty HAS_ITEM = BooleanProperty.create("has_item"); + + public enum PedestalState implements StringRepresentable { + PEDESTAL_TOP("pedestal_top"), + COLUMN_TOP("column_top"), + BOTTOM("bottom"), + PILLAR("pillar"), + COLUMN("column"), + DEFAULT("default"); + + private final String name; + + PedestalState(String name) { + this.name = name; + } + + @Override + public String getSerializedName() { + return this.name; + } + + @Override + public String toString() { + return this.name; + } + } + + public enum HydraluxShape implements StringRepresentable { + FLOWER_BIG_BOTTOM("flower_big_bottom", true), + FLOWER_BIG_TOP("flower_big_top", true), + FLOWER_SMALL_BOTTOM("flower_small_bottom", true), + FLOWER_SMALL_TOP("flower_small_top", true), + VINE("vine", false), + ROOTS("roots", false); + + private final String name; + private final boolean glow; + + HydraluxShape(String name, boolean glow) { + this.name = name; + this.glow = glow; + } + + @Override + public String getSerializedName() { + return name; + } + + @Override + public String toString() { + return name; + } + + public boolean hasGlow() { + return glow; + } + } + + public enum LumecornShape implements StringRepresentable { + LIGHT_TOP("light_top", 15), + LIGHT_TOP_MIDDLE("light_top_middle", 15), + LIGHT_MIDDLE("light_middle", 15), + LIGHT_BOTTOM("light_bottom", 15), + MIDDLE("middle", 0), + BOTTOM_BIG("bottom_big", 0), + BOTTOM_SMALL("bottom_small", 0); + + private final String name; + private final int light; + + LumecornShape(String name, int light) { + this.name = name; + this.light = light; + } + + @Override + public String getSerializedName() { + return name; + } + + @Override + public String toString() { + return name; + } + + public int getLight() { + return light; + } + } + + public enum CactusBottom implements StringRepresentable { + EMPTY("empty"), + SAND("sand"), + MOSS("moss"); + + private final String name; + + CactusBottom(String name) { + this.name = name; + } + + @Override + public String getSerializedName() { + return name; + } + + @Override + public String toString() { + return name; + } + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EndLilyBlock.java b/src/main/java/org/betterx/betterend/blocks/EndLilyBlock.java new file mode 100644 index 00000000..bf5f1956 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EndLilyBlock.java @@ -0,0 +1,125 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.interfaces.tools.AddMineableShears; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.basis.EndUnderwaterPlantBlock; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import com.google.common.collect.Lists; + +import java.util.Collections; +import java.util.List; + +public class EndLilyBlock extends EndUnderwaterPlantBlock implements AddMineableShears { + public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; + private static final VoxelShape SHAPE_BOTTOM = Block.box(4, 0, 4, 12, 16, 12); + private static final VoxelShape SHAPE_TOP = Block.box(2, 0, 2, 14, 6, 14); + + public EndLilyBlock() { + super(baseUnderwaterPlantSettings() + .lightLevel((state) -> state.getValue(SHAPE) == TripleShape.TOP ? 13 : 0) + ); + } + + @Override + public BlockState updateShape( + BlockState state, + Direction facing, + BlockState neighborState, + LevelAccessor world, + BlockPos pos, + BlockPos neighborPos + ) { + if (!canSurvive(state, world, pos)) { + return state.getValue(SHAPE) == TripleShape.TOP + ? Blocks.AIR.defaultBlockState() + : Blocks.WATER.defaultBlockState(); + } else { + return state; + } + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + Vec3 vec3d = state.getOffset(view, pos); + VoxelShape shape = state.getValue(SHAPE) == TripleShape.TOP ? SHAPE_TOP : SHAPE_BOTTOM; + return shape.move(vec3d.x, vec3d.y, vec3d.z); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(SHAPE); + } + + @Override + public FluidState getFluidState(BlockState state) { + return state.getValue(SHAPE) == TripleShape.TOP ? Fluids.EMPTY.defaultFluidState() : Fluids.WATER.getSource( + false); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + if (state.getValue(SHAPE) == TripleShape.TOP) { + return world.getBlockState(pos.below()).getBlock() == this; + } else if (state.getValue(SHAPE) == TripleShape.BOTTOM) { + return isTerrain(world.getBlockState(pos.below())); + } else { + BlockState up = world.getBlockState(pos.above()); + BlockState down = world.getBlockState(pos.below()); + return up.getBlock() == this && down.getBlock() == this; + } + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + if (state.getValue(SHAPE) == TripleShape.TOP) { + return Lists.newArrayList( + new ItemStack(EndItems.END_LILY_LEAF, MHelper.randRange(1, 2, MHelper.RANDOM_SOURCE)), + new ItemStack(EndBlocks.END_LILY_SEED, MHelper.randRange(1, 2, MHelper.RANDOM_SOURCE)) + ); + } + return Collections.emptyList(); + } + + @Override + @Environment(EnvType.CLIENT) + public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) { + return new ItemStack(EndBlocks.END_LILY_SEED); + } + + @Override + public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { + return false; + } + + @Override + public boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state) { + return false; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EndLilySeedBlock.java b/src/main/java/org/betterx/betterend/blocks/EndLilySeedBlock.java new file mode 100644 index 00000000..3c038d5b --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EndLilySeedBlock.java @@ -0,0 +1,53 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.blocks.UnderwaterPlantWithAgeBlock; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluids; + +public class EndLilySeedBlock extends UnderwaterPlantWithAgeBlock { + @Override + public void grow(WorldGenLevel world, RandomSource random, BlockPos pos) { + if (canGrow(world, pos)) { + BlocksHelper.setWithoutUpdate( + world, + pos, + EndBlocks.END_LILY.defaultBlockState().setValue(EndLilyBlock.SHAPE, TripleShape.BOTTOM) + ); + BlockPos up = pos.above(); + while (world.getFluidState(up).isSource()) { + BlocksHelper.setWithoutUpdate( + world, + up, + EndBlocks.END_LILY.defaultBlockState().setValue(EndLilyBlock.SHAPE, TripleShape.MIDDLE) + ); + up = up.above(); + } + BlocksHelper.setWithoutUpdate( + world, + up, + EndBlocks.END_LILY.defaultBlockState().setValue(EndLilyBlock.SHAPE, TripleShape.TOP) + ); + } + } + + private boolean canGrow(WorldGenLevel world, BlockPos pos) { + BlockPos up = pos.above(); + while (world.getBlockState(up).getFluidState().getType().equals(Fluids.WATER.getSource())) { + up = up.above(); + } + return world.isEmptyBlock(up); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(CommonBlockTags.END_STONES); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EndLotusFlowerBlock.java b/src/main/java/org/betterx/betterend/blocks/EndLotusFlowerBlock.java new file mode 100644 index 00000000..21cccdb6 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EndLotusFlowerBlock.java @@ -0,0 +1,60 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.basis.EndPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import com.google.common.collect.Lists; + +import java.util.List; + +public class EndLotusFlowerBlock extends EndPlantBlock { + private static final VoxelShape SHAPE_OUTLINE = Block.box(2, 0, 2, 14, 14, 14); + private static final VoxelShape SHAPE_COLLISION = Block.box(0, 0, 0, 16, 2, 16); + + public EndLotusFlowerBlock() { + //TODO: 1.19 Test if we can remove dynamic shape and offsetType + super(basePlantSettings(15).offsetType(BlockBehaviour.OffsetType.NONE)); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.END_LOTUS_STEM); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return SHAPE_OUTLINE; + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getCollisionShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return SHAPE_COLLISION; + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + int count = MHelper.randRange(1, 2, MHelper.RANDOM_SOURCE); + return Lists.newArrayList(new ItemStack(EndBlocks.END_LOTUS_SEED, count)); + } + + @Override + @Environment(EnvType.CLIENT) + public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) { + return new ItemStack(EndBlocks.END_LOTUS_SEED); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EndLotusLeafBlock.java b/src/main/java/org/betterx/betterend/blocks/EndLotusLeafBlock.java new file mode 100644 index 00000000..b4ac8b39 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EndLotusLeafBlock.java @@ -0,0 +1,82 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlockNotFull; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.material.WaterFluid; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class EndLotusLeafBlock extends BaseBlockNotFull implements RenderLayerProvider { + public static final EnumProperty HORIZONTAL_FACING = BlockStateProperties.HORIZONTAL_FACING; + public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; + private static final VoxelShape VSHAPE = Block.box(0, 0, 0, 16, 1, 16); + + public EndLotusLeafBlock() { + super(FabricBlockSettings.of(Material.PLANT).noOcclusion().sound(SoundType.WET_GRASS)); + } + + @Override + @SuppressWarnings("deprecation") + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + BlockState down = world.getBlockState(pos.below()); + return !down.getFluidState().isEmpty() && down.getFluidState().getType() instanceof WaterFluid; + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(SHAPE, HORIZONTAL_FACING); + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return VSHAPE; + } + + @Override + @SuppressWarnings("deprecation") + public BlockState rotate(BlockState state, Rotation rotation) { + return BlocksHelper.rotateHorizontal(state, rotation, HORIZONTAL_FACING); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState mirror(BlockState state, Mirror mirror) { + return BlocksHelper.mirrorHorizontal(state, mirror, HORIZONTAL_FACING); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + @Override + @Environment(EnvType.CLIENT) + public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) { + return new ItemStack(EndBlocks.END_LOTUS_SEED); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EndLotusSeedBlock.java b/src/main/java/org/betterx/betterend/blocks/EndLotusSeedBlock.java new file mode 100644 index 00000000..dcc37a0d --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EndLotusSeedBlock.java @@ -0,0 +1,138 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.blocks.UnderwaterPlantWithAgeBlock; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluids; + +public class EndLotusSeedBlock extends UnderwaterPlantWithAgeBlock { + @Override + public void grow(WorldGenLevel world, RandomSource random, BlockPos pos) { + if (canGrow(world, pos)) { + BlockState startLeaf = EndBlocks.END_LOTUS_STEM.defaultBlockState().setValue(EndLotusStemBlock.LEAF, true); + BlockState roots = EndBlocks.END_LOTUS_STEM.defaultBlockState() + .setValue(EndLotusStemBlock.SHAPE, TripleShape.BOTTOM) + .setValue(EndLotusStemBlock.WATERLOGGED, true); + BlockState stem = EndBlocks.END_LOTUS_STEM.defaultBlockState(); + BlockState flower = EndBlocks.END_LOTUS_FLOWER.defaultBlockState(); + + BlocksHelper.setWithoutUpdate(world, pos, roots); + MutableBlockPos bpos = new MutableBlockPos().set(pos); + bpos.setY(bpos.getY() + 1); + while (world.getFluidState(bpos).isSource()) { + BlocksHelper.setWithoutUpdate(world, bpos, stem.setValue(EndLotusStemBlock.WATERLOGGED, true)); + bpos.setY(bpos.getY() + 1); + } + + int height = random.nextBoolean() ? 0 : random.nextBoolean() ? 1 : random.nextBoolean() ? 1 : -1; + TripleShape shape = (height == 0) ? TripleShape.TOP : TripleShape.MIDDLE; + Direction dir = BlocksHelper.randomHorizontal(random); + BlockPos leafCenter = bpos.immutable().relative(dir); + if (hasLeaf(world, leafCenter)) { + generateLeaf(world, leafCenter); + BlocksHelper.setWithoutUpdate( + world, + bpos, + startLeaf.setValue(EndLotusStemBlock.SHAPE, shape).setValue(EndLotusStemBlock.FACING, dir) + ); + } else { + BlocksHelper.setWithoutUpdate(world, bpos, stem.setValue(EndLotusStemBlock.SHAPE, shape)); + } + + bpos.setY(bpos.getY() + 1); + for (int i = 1; i <= height; i++) { + if (!world.isEmptyBlock(bpos)) { + bpos.setY(bpos.getY() - 1); + BlocksHelper.setWithoutUpdate(world, bpos, flower); + bpos.setY(bpos.getY() - 1); + stem = world.getBlockState(bpos); + BlocksHelper.setWithoutUpdate(world, bpos, stem.setValue(EndLotusStemBlock.SHAPE, TripleShape.TOP)); + return; + } + BlocksHelper.setWithoutUpdate(world, bpos, stem); + bpos.setY(bpos.getY() + 1); + } + + if (!world.isEmptyBlock(bpos) || height < 0) { + bpos.setY(bpos.getY() - 1); + } + + BlocksHelper.setWithoutUpdate(world, bpos, flower); + bpos.setY(bpos.getY() - 1); + stem = world.getBlockState(bpos); + if (!stem.is(EndBlocks.END_LOTUS_STEM)) { + stem = EndBlocks.END_LOTUS_STEM.defaultBlockState(); + if (!world.getBlockState(bpos.north()).getFluidState().isEmpty()) { + stem = stem.setValue(EndLotusStemBlock.WATERLOGGED, true); + } + } + + if (world.getBlockState(bpos.relative(dir)).is(EndBlocks.END_LOTUS_LEAF)) { + stem = stem.setValue(EndLotusStemBlock.LEAF, true).setValue(EndLotusStemBlock.FACING, dir); + } + + BlocksHelper.setWithoutUpdate(world, bpos, stem.setValue(EndLotusStemBlock.SHAPE, TripleShape.TOP)); + } + } + + private boolean canGrow(WorldGenLevel world, BlockPos pos) { + MutableBlockPos bpos = new MutableBlockPos(); + bpos.set(pos); + while (world.getBlockState(bpos).getFluidState().getType().equals(Fluids.WATER.getSource())) { + bpos.setY(bpos.getY() + 1); + } + return world.isEmptyBlock(bpos) && world.isEmptyBlock(bpos.above()); + } + + private void generateLeaf(WorldGenLevel world, BlockPos pos) { + MutableBlockPos p = new MutableBlockPos(); + BlockState leaf = EndBlocks.END_LOTUS_LEAF.defaultBlockState(); + BlocksHelper.setWithoutUpdate(world, pos, leaf.setValue(EndLotusLeafBlock.SHAPE, TripleShape.BOTTOM)); + for (Direction move : BlocksHelper.HORIZONTAL) { + BlocksHelper.setWithoutUpdate( + world, + p.set(pos).move(move), + leaf.setValue(EndLotusLeafBlock.HORIZONTAL_FACING, move) + .setValue(EndLotusLeafBlock.SHAPE, TripleShape.MIDDLE) + ); + } + for (int i = 0; i < 4; i++) { + Direction d1 = BlocksHelper.HORIZONTAL[i]; + Direction d2 = BlocksHelper.HORIZONTAL[(i + 1) & 3]; + BlocksHelper.setWithoutUpdate( + world, + p.set(pos).move(d1).move(d2), + leaf.setValue(EndLotusLeafBlock.HORIZONTAL_FACING, d1) + .setValue(EndLotusLeafBlock.SHAPE, TripleShape.TOP) + ); + } + } + + private boolean hasLeaf(WorldGenLevel world, BlockPos pos) { + MutableBlockPos p = new MutableBlockPos(); + p.setY(pos.getY()); + int count = 0; + for (int x = -1; x < 2; x++) { + p.setX(pos.getX() + x); + for (int z = -1; z < 2; z++) { + p.setZ(pos.getZ() + z); + if (world.isEmptyBlock(p) && !world.getFluidState(p.below()).isEmpty()) count++; + } + } + return count == 9; + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(CommonBlockTags.END_STONES); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EndLotusStemBlock.java b/src/main/java/org/betterx/betterend/blocks/EndLotusStemBlock.java new file mode 100644 index 00000000..32dfebd8 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EndLotusStemBlock.java @@ -0,0 +1,112 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.util.BlocksHelper; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Maps; + +import java.util.Map; + +public class EndLotusStemBlock extends BaseBlock implements SimpleWaterloggedBlock, RenderLayerProvider { + public static final EnumProperty FACING = BlockStateProperties.FACING; + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + public static final BooleanProperty LEAF = BooleanProperty.create("leaf"); + public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; + private static final Map SHAPES = Maps.newEnumMap(Axis.class); + + public EndLotusStemBlock() { + super(FabricBlockSettings.copyOf(Blocks.OAK_PLANKS)); + this.registerDefaultState(defaultBlockState().setValue(WATERLOGGED, false) + .setValue(SHAPE, TripleShape.MIDDLE) + .setValue(LEAF, false) + .setValue(FACING, Direction.UP)); + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return state.getValue(LEAF) ? SHAPES.get(Axis.Y) : SHAPES.get(state.getValue(FACING).getAxis()); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(FACING, WATERLOGGED, SHAPE, LEAF); + } + + @Override + @SuppressWarnings("deprecation") + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + LevelAccessor worldAccess = ctx.getLevel(); + BlockPos blockPos = ctx.getClickedPos(); + return this.defaultBlockState() + .setValue(WATERLOGGED, worldAccess.getFluidState(blockPos).getType() == Fluids.WATER) + .setValue(FACING, ctx.getClickedFace()); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState rotate(BlockState state, Rotation rotation) { + return BlocksHelper.rotateHorizontal(state, rotation, FACING); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState mirror(BlockState state, Mirror mirror) { + return BlocksHelper.mirrorHorizontal(state, mirror, FACING); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState updateShape( + BlockState state, + Direction direction, + BlockState newState, + LevelAccessor world, + BlockPos pos, + BlockPos posFrom + ) { + if (state.getValue(WATERLOGGED)) { + world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); + } + return state; + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + static { + SHAPES.put(Axis.X, Block.box(0, 6, 6, 16, 10, 10)); + SHAPES.put(Axis.Y, Block.box(6, 0, 6, 10, 16, 10)); + SHAPES.put(Axis.Z, Block.box(6, 6, 0, 10, 10, 16)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EndPedestal.java b/src/main/java/org/betterx/betterend/blocks/EndPedestal.java new file mode 100644 index 00000000..58af77bb --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EndPedestal.java @@ -0,0 +1,32 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.basis.PedestalBlock; + +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.Block; + +import com.google.common.collect.Maps; + +import java.util.Map; + +public class EndPedestal extends PedestalBlock { + + public EndPedestal(Block parent) { + super(parent); + } + + @Override + protected Map createTexturesMap() { + ResourceLocation blockId = Registry.BLOCK.getKey(parent); + String name = blockId.getPath(); + Map textures = Maps.newHashMap(); + textures.put("%mod%", BetterEnd.MOD_ID); + textures.put("%top%", name + "_polished"); + textures.put("%base%", name + "_polished"); + textures.put("%pillar%", name + "_pillar_side"); + textures.put("%bottom%", name + "_polished"); + return textures; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EndPortalBlock.java b/src/main/java/org/betterx/betterend/blocks/EndPortalBlock.java new file mode 100644 index 00000000..51628f3a --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EndPortalBlock.java @@ -0,0 +1,228 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.CustomColorProvider; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.betterend.advancements.BECriteria; +import org.betterx.betterend.interfaces.TeleportingEntity; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.betterend.registry.EndPortals; +import org.betterx.betterend.rituals.EternalRitual; + +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.item.ItemColor; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.core.Direction.AxisDirection; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.NetherPortalBlock; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.dimension.DimensionType; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Objects; +import java.util.Optional; + +public class EndPortalBlock extends NetherPortalBlock implements RenderLayerProvider, CustomColorProvider { + public static final IntegerProperty PORTAL = EndBlockProperties.PORTAL; + + public EndPortalBlock() { + super(FabricBlockSettings.copyOf(Blocks.NETHER_PORTAL) + .resistance(Blocks.BEDROCK.getExplosionResistance()) + .luminance(15)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + super.createBlockStateDefinition(builder); + builder.add(PORTAL); + } + + @Override + @Environment(EnvType.CLIENT) + public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) { + if (random.nextInt(100) == 0) { + world.playLocalSound( + pos.getX() + 0.5D, + pos.getY() + 0.5D, + pos.getZ() + 0.5D, + SoundEvents.PORTAL_AMBIENT, + SoundSource.BLOCKS, + 0.5F, + random.nextFloat() * 0.4F + 0.8F, + false + ); + } + + double x = pos.getX() + random.nextDouble(); + double y = pos.getY() + random.nextDouble(); + double z = pos.getZ() + random.nextDouble(); + int k = random.nextInt(2) * 2 - 1; + if (!world.getBlockState(pos.west()).is(this) && !world.getBlockState(pos.east()).is(this)) { + x = pos.getX() + 0.5D + 0.25D * k; + } else { + z = pos.getZ() + 0.5D + 0.25D * k; + } + + world.addParticle(EndParticles.PORTAL_SPHERE, x, y, z, 0, 0, 0); + } + + @Override + public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + } + + @Override + public BlockState updateShape( + BlockState state, + Direction direction, + BlockState newState, + LevelAccessor world, + BlockPos pos, + BlockPos posFrom + ) { + return state; + } + + @Override + public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (world.isClientSide || !validate(entity)) return; + entity.setPortalCooldown(); + ServerLevel currentWorld = (ServerLevel) world; + MinecraftServer server = currentWorld.getServer(); + ServerLevel targetWorld = EndPortals.getWorld(server, state.getValue(PORTAL)); + boolean isInEnd = currentWorld.dimension().equals(Level.END); + ServerLevel destination = isInEnd ? targetWorld : server.getLevel(Level.END); + BlockPos exitPos = findExitPos(currentWorld, destination, pos, entity); + if (exitPos == null) return; + if (entity instanceof ServerPlayer sp && sp.isCreative()) { + ((ServerPlayer) entity).teleportTo( + destination, + exitPos.getX() + 0.5, + exitPos.getY(), + exitPos.getZ() + 0.5, + entity.getYRot(), + entity.getXRot() + ); + BECriteria.PORTAL_TRAVEL.trigger(sp); + } else { + if (entity instanceof ServerPlayer sp) { + BECriteria.PORTAL_TRAVEL.trigger(sp); + } + ((TeleportingEntity) entity).be_setExitPos(exitPos); + Optional teleported = Optional.ofNullable(entity.changeDimension(destination)); + teleported.ifPresent(Entity::setPortalCooldown); + } + } + + private boolean validate(Entity entity) { + return !entity.isPassenger() && !entity.isVehicle() && entity.canChangeDimensions() && !entity.isOnPortalCooldown(); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.TRANSLUCENT; + } + + private BlockPos findExitPos( + ServerLevel currentWorld, + ServerLevel targetWorld, + BlockPos currentPos, + Entity entity + ) { + if (targetWorld == null) return null; + Registry registry = targetWorld.registryAccess() + .registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY); + ResourceLocation targetWorldId = targetWorld.dimension().location(); + ResourceLocation currentWorldId = currentWorld.dimension().location(); + double targetMultiplier = Objects.requireNonNull(registry.get(targetWorldId)).coordinateScale(); + double currentMultiplier = Objects.requireNonNull(registry.get(currentWorldId)).coordinateScale(); + double multiplier = targetMultiplier > currentMultiplier ? 1.0 / targetMultiplier : currentMultiplier; + MutableBlockPos basePos = currentPos.mutable() + .set( + currentPos.getX() * multiplier, + currentPos.getY(), + currentPos.getZ() * multiplier + ); + MutableBlockPos checkPos = basePos.mutable(); + BlockState currentState = currentWorld.getBlockState(currentPos); + int radius = (EternalRitual.SEARCH_RADIUS >> 4) + 1; + checkPos = EternalRitual.findBlockPos( + targetWorld, + checkPos, + radius, + this, + state -> state.is(this) && state.getValue(PORTAL).equals(currentState.getValue(PORTAL)) + ); + if (checkPos != null) { + BlockState checkState = targetWorld.getBlockState(checkPos); + Axis axis = checkState.getValue(AXIS); + checkPos = findCenter(targetWorld, checkPos, axis); + Direction frontDir = Direction.fromAxisAndDirection(axis, AxisDirection.POSITIVE).getClockWise(); + Direction entityDir = entity.getMotionDirection(); + if (entityDir.getAxis().isVertical()) { + entityDir = frontDir; + } + if (frontDir != entityDir && frontDir.getOpposite() != entityDir) { + entity.rotate(Rotation.CLOCKWISE_90); + entityDir = entityDir.getClockWise(); + } + return checkPos.relative(entityDir); + } + return null; + } + + private MutableBlockPos findCenter(Level world, MutableBlockPos pos, Direction.Axis axis) { + return findCenter(world, pos, axis, 1); + } + + private MutableBlockPos findCenter(Level world, MutableBlockPos pos, Direction.Axis axis, int step) { + if (step > 8) return pos; + BlockState right, left; + Direction rightDir, leftDir; + rightDir = Direction.fromAxisAndDirection(axis, AxisDirection.POSITIVE); + leftDir = rightDir.getOpposite(); + right = world.getBlockState(pos.relative(rightDir)); + left = world.getBlockState(pos.relative(leftDir)); + BlockState down = world.getBlockState(pos.below()); + if (down.is(this)) { + return findCenter(world, pos.move(Direction.DOWN), axis, step); + } else if (right.is(this) && left.is(this)) { + return pos; + } else if (right.is(this)) { + return findCenter(world, pos.move(rightDir), axis, ++step); + } else if (left.is(this)) { + return findCenter(world, pos.move(leftDir), axis, ++step); + } + return pos; + } + + @Override + public BlockColor getProvider() { + return (state, world, pos, tintIndex) -> EndPortals.getColor(state.getValue(PORTAL)); + } + + @Override + public ItemColor getItemProvider() { + return (stack, tintIndex) -> EndPortals.getColor(0); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EndStoneSmelter.java b/src/main/java/org/betterx/betterend/blocks/EndStoneSmelter.java new file mode 100644 index 00000000..5829e259 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EndStoneSmelter.java @@ -0,0 +1,188 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlockWithEntity; +import org.betterx.bclib.interfaces.AlloyingRecipeWorkstation; +import org.betterx.betterend.blocks.entities.EndStoneSmelterBlockEntity; +import org.betterx.betterend.registry.EndBlockEntities; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.RandomSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.material.MaterialColor; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; +import net.minecraft.world.phys.BlockHitResult; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Lists; + +import java.util.List; +import org.jetbrains.annotations.Nullable; + +public class EndStoneSmelter extends BaseBlockWithEntity implements AlloyingRecipeWorkstation { + public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING; + public static final BooleanProperty LIT = BlockStateProperties.LIT; + public static final String ID = "end_stone_smelter"; + + public EndStoneSmelter() { + super(FabricBlockSettings.of(Material.STONE, MaterialColor.COLOR_GRAY) + .luminance(state -> state.getValue(LIT) ? 15 : 0) + .hardness(4F) + .resistance(100F) + .requiresCorrectToolForDrops() + .sound(SoundType.STONE)); + registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(LIT, false)); + } + + @SuppressWarnings("deprecation") + public InteractionResult use( + BlockState state, + Level world, + BlockPos pos, + Player player, + InteractionHand hand, + BlockHitResult hit + ) { + if (world.isClientSide) { + return InteractionResult.SUCCESS; + } else { + this.openScreen(world, pos, player); + return InteractionResult.CONSUME; + } + } + + private void openScreen(Level world, BlockPos pos, Player player) { + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof EndStoneSmelterBlockEntity) { + player.openMenu((EndStoneSmelterBlockEntity) blockEntity); + } + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + return defaultBlockState().setValue(FACING, ctx.getHorizontalDirection().getOpposite()); + } + + @Override + public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { + return new EndStoneSmelterBlockEntity(blockPos, blockState); + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + List drop = Lists.newArrayList(new ItemStack(this)); + BlockEntity blockEntity = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY); + if (blockEntity instanceof EndStoneSmelterBlockEntity) { + EndStoneSmelterBlockEntity smelterBlockEntity = (EndStoneSmelterBlockEntity) blockEntity; + for (int i = 0; i < smelterBlockEntity.getContainerSize(); i++) { + ItemStack item = smelterBlockEntity.getItem(i); + if (!item.isEmpty()) { + drop.add(item); + } + } + } + return drop; + } + + @Override + @SuppressWarnings("deprecation") + public boolean hasAnalogOutputSignal(BlockState state) { + return true; + } + + @Override + @SuppressWarnings("deprecation") + public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) { + //TODO + return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos)); + } + + @Override + public RenderShape getRenderShape(BlockState state) { + return RenderShape.MODEL; + } + + @Override + @SuppressWarnings("deprecation") + public BlockState rotate(BlockState state, Rotation rotation) { + return state.setValue(FACING, rotation.rotate(state.getValue(FACING))); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState mirror(BlockState state, Mirror mirror) { + return state.rotate(mirror.getRotation(state.getValue(FACING))); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(FACING, LIT); + } + + @Environment(EnvType.CLIENT) + public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) { + if (state.getValue(LIT)) { + double x = pos.getX() + 0.5D; + double y = pos.getY(); + double z = pos.getZ() + 0.5D; + if (random.nextDouble() < 0.1D) { + world.playLocalSound( + x, + y, + z, + SoundEvents.BLASTFURNACE_FIRE_CRACKLE, + SoundSource.BLOCKS, + 1.0F, + 1.0F, + false + ); + } + + Direction direction = state.getValue(FACING); + Direction.Axis axis = direction.getAxis(); + double defOffset = random.nextDouble() * 0.6D - 0.3D; + double offX = axis == Direction.Axis.X ? direction.getStepX() * 0.52D : defOffset; + double offY = random.nextDouble() * 9.0D / 16.0D; + double offZ = axis == Direction.Axis.Z ? direction.getStepZ() * 0.52D : defOffset; + world.addParticle(ParticleTypes.SMOKE, x + offX, y + offY, z + offZ, 0.0D, 0.0D, 0.0D); + } + } + + + @Override + @Nullable + public BlockEntityTicker getTicker( + Level level, + BlockState blockState, + BlockEntityType blockEntityType + ) { + return level.isClientSide() ? null : createTickerHelper( + blockEntityType, + EndBlockEntities.END_STONE_SMELTER, + EndStoneSmelterBlockEntity::tick + ); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EnderBlock.java b/src/main/java/org/betterx/betterend/blocks/EnderBlock.java new file mode 100644 index 00000000..e7223968 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EnderBlock.java @@ -0,0 +1,30 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class EnderBlock extends BaseBlock { + + public EnderBlock() { + super(FabricBlockSettings.of(Material.STONE, MaterialColor.WARPED_WART_BLOCK) + .hardness(5F) + .resistance(6F) + .requiresCorrectToolForDrops() + .sound(SoundType.STONE)); + } + + @Environment(EnvType.CLIENT) + public int getColor(BlockState state, BlockGetter world, BlockPos pos) { + return 0xFF005548; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EndstoneDustBlock.java b/src/main/java/org/betterx/betterend/blocks/EndstoneDustBlock.java new file mode 100644 index 00000000..de84186c --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EndstoneDustBlock.java @@ -0,0 +1,52 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.interfaces.TagProvider; +import org.betterx.bclib.interfaces.tools.AddMineableShovel; +import org.betterx.ui.ColorUtil; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.FallingBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.loot.LootContext; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Collections; +import java.util.List; + +public class EndstoneDustBlock extends FallingBlock implements TagProvider, AddMineableShovel { + @Environment(EnvType.CLIENT) + private static final int COLOR = ColorUtil.color(226, 239, 168); + + public EndstoneDustBlock() { + super(FabricBlockSettings + .copyOf(Blocks.SAND) + .mapColor(Blocks.END_STONE.defaultMaterialColor()) + ); + } + + @Override + @SuppressWarnings("deprecation") + public List getDrops(BlockState state, LootContext.Builder builder) { + return Collections.singletonList(new ItemStack(this)); + } + + @Environment(EnvType.CLIENT) + public int getDustColor(BlockState state, BlockGetter world, BlockPos pos) { + return COLOR; + } + + @Override + public void addTags(List> blockTags, List> itemTags) { + blockTags.add(CommonBlockTags.END_STONES); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/EternalPedestal.java b/src/main/java/org/betterx/betterend/blocks/EternalPedestal.java new file mode 100644 index 00000000..38db647e --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/EternalPedestal.java @@ -0,0 +1,145 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.PedestalBlock; +import org.betterx.betterend.blocks.entities.EternalPedestalEntity; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndPortals; +import org.betterx.betterend.rituals.EternalRitual; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; + +import com.google.common.collect.Lists; + +import java.util.List; + +public class EternalPedestal extends PedestalBlock { + public static final BooleanProperty ACTIVATED = EndBlockProperties.ACTIVE; + + public EternalPedestal() { + super(EndBlocks.FLAVOLITE_RUNED_ETERNAL); + this.registerDefaultState(defaultBlockState().setValue(ACTIVATED, false)); + } + + @Override + public void checkRitual(Level world, Player player, BlockPos pos) { + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof EternalPedestalEntity) { + EternalPedestalEntity pedestal = (EternalPedestalEntity) blockEntity; + BlockState updatedState = world.getBlockState(pos); + if (pedestal.isEmpty()) { + if (pedestal.hasRitual()) { + EternalRitual ritual = pedestal.getRitual(); + if (ritual.isActive()) { + ResourceLocation targetWorld = ritual.getTargetWorldId(); + int portalId; + if (targetWorld != null) { + portalId = EndPortals.getPortalIdByWorld(targetWorld); + } else { + portalId = EndPortals.getPortalIdByWorld(EndPortals.OVERWORLD_ID); + } + ritual.disablePortal(portalId); + } + } + world.setBlockAndUpdate(pos, updatedState.setValue(ACTIVATED, false).setValue(HAS_LIGHT, false)); + } else { + ItemStack itemStack = pedestal.getItem(0); + ResourceLocation id = Registry.ITEM.getKey(itemStack.getItem()); + if (EndPortals.isAvailableItem(id)) { + world.setBlockAndUpdate(pos, updatedState.setValue(ACTIVATED, true).setValue(HAS_LIGHT, true)); + if (pedestal.hasRitual()) { + pedestal.getRitual().checkStructure(player); + } else { + EternalRitual ritual = new EternalRitual(world, pos); + ritual.checkStructure(player); + } + } + } + } + } + + @Override + @Deprecated + public BlockState updateShape( + BlockState state, + Direction direction, + BlockState newState, + LevelAccessor world, + BlockPos pos, + BlockPos posFrom + ) { + BlockState updated = super.updateShape(state, direction, newState, world, pos, posFrom); + if (!updated.is(this)) return updated; + if (!this.isPlaceable(updated)) { + return updated.setValue(ACTIVATED, false); + } + return updated; + } + + @Override + @Deprecated + public float getDestroyProgress(BlockState state, Player player, BlockGetter world, BlockPos pos) { + return 0.0F; + } + + @Override + public float getExplosionResistance() { + return Blocks.BEDROCK.getExplosionResistance(); + } + + @Override + public boolean dropFromExplosion(Explosion explosion) { + return false; + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + if (state.is(this)) { + EndBlockProperties.PedestalState currentState = state.getValue(EndBlockProperties.PEDESTAL_STATE); + if (currentState.equals(EndBlockProperties.PedestalState.BOTTOM) || currentState.equals(EndBlockProperties.PedestalState.PILLAR)) { + return Lists.newArrayList(); + } + } + List drop = Lists.newArrayList(); + BlockEntity blockEntity = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY); + if (blockEntity instanceof EternalPedestalEntity) { + EternalPedestalEntity pedestal = (EternalPedestalEntity) blockEntity; + if (!pedestal.isEmpty()) { + drop.add(pedestal.getItem(0)); + } + } + return drop; + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + super.createBlockStateDefinition(stateManager); + stateManager.add(ACTIVATED); + } + + @Override + public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { + return new EternalPedestalEntity(blockPos, blockState); + } + + @Override + public boolean hasUniqueEntity() { + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/FilaluxBlock.java b/src/main/java/org/betterx/betterend/blocks/FilaluxBlock.java new file mode 100644 index 00000000..84b95a01 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/FilaluxBlock.java @@ -0,0 +1,11 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseVineBlock; + +import net.minecraft.world.level.block.state.BlockBehaviour; + +public class FilaluxBlock extends BaseVineBlock { + public FilaluxBlock() { + super(15, true, p -> p.offsetType(BlockBehaviour.OffsetType.NONE)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/FilaluxLanternBlock.java b/src/main/java/org/betterx/betterend/blocks/FilaluxLanternBlock.java new file mode 100644 index 00000000..438aac7a --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/FilaluxLanternBlock.java @@ -0,0 +1,17 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.interfaces.tools.AddMineableAxe; + +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.material.Material; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class FilaluxLanternBlock extends BaseBlock implements AddMineableAxe { + public FilaluxLanternBlock() { + super(FabricBlockSettings.of(Material.WOOD) + .luminance(15) + .sound(SoundType.WOOD)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/FilaluxWingsBlock.java b/src/main/java/org/betterx/betterend/blocks/FilaluxWingsBlock.java new file mode 100644 index 00000000..317ecfda --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/FilaluxWingsBlock.java @@ -0,0 +1,52 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseAttachedBlock; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.interfaces.tools.AddMineableShears; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Maps; + +import java.util.EnumMap; + +public class FilaluxWingsBlock extends BaseAttachedBlock implements RenderLayerProvider, AddMineableShears { + private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(Direction.class); + + public FilaluxWingsBlock() { + super(FabricBlockSettings.of(Material.PLANT) + .sound(SoundType.WET_GRASS) + .noCollission()); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return BOUNDING_SHAPES.get(state.getValue(FACING)); + } + + static { + BOUNDING_SHAPES.put(Direction.UP, Shapes.box(0.0, 0.0, 0.0, 1.0, 0.5, 1.0)); + BOUNDING_SHAPES.put(Direction.DOWN, Shapes.box(0.0, 0.5, 0.0, 1.0, 1.0, 1.0)); + BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.0, 0.0, 0.5, 1.0, 1.0, 1.0)); + BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 0.5)); + BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.5, 0.0, 0.0, 1.0, 1.0, 1.0)); + BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.0, 0.0, 0.5, 1.0, 1.0)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/FlamaeaBlock.java b/src/main/java/org/betterx/betterend/blocks/FlamaeaBlock.java new file mode 100644 index 00000000..922b5eb0 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/FlamaeaBlock.java @@ -0,0 +1,62 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.interfaces.CustomItemProvider; +import org.betterx.bclib.interfaces.tools.AddMineableShears; +import org.betterx.betterend.blocks.basis.EndPlantBlock; + +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.PlaceOnWaterBlockItem; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.fabric.api.item.v1.FabricItemSettings; + +import com.google.common.collect.Lists; + +import java.util.List; + +public class FlamaeaBlock extends EndPlantBlock implements CustomItemProvider, AddMineableShears { + private static final VoxelShape SHAPE = Block.box(0, 0, 0, 16, 1, 16); + + public FlamaeaBlock() { + super(basePlantSettings() + .sound(SoundType.WET_GRASS) + .offsetType(BlockBehaviour.OffsetType.NONE) + ); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(Blocks.WATER); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return SHAPE; + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + return Lists.newArrayList(new ItemStack(this)); + } + + @Override + public boolean canBePotted() { + return false; + } + + @Override + public BlockItem getCustomItem(ResourceLocation resourceLocation, FabricItemSettings fabricItemSettings) { + return new PlaceOnWaterBlockItem(this, fabricItemSettings); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/FlammalixBlock.java b/src/main/java/org/betterx/betterend/blocks/FlammalixBlock.java new file mode 100644 index 00000000..1876f07b --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/FlammalixBlock.java @@ -0,0 +1,44 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.client.models.ModelsHelper; +import org.betterx.betterend.blocks.basis.EndPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class FlammalixBlock extends EndPlantBlock { + private static final VoxelShape SHAPE = Block.box(2, 0, 2, 14, 14, 14); + + public FlammalixBlock() { + super(basePlantSettings(12).offsetType(OffsetType.NONE)); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.PALLIDIUM_FULL) || + state.is(EndBlocks.PALLIDIUM_HEAVY) || + state.is(EndBlocks.PALLIDIUM_THIN) || + state.is(EndBlocks.PALLIDIUM_TINY); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return SHAPE; + } + + @Override + @Environment(EnvType.CLIENT) + public BlockModel getItemModel(ResourceLocation resourceLocation) { + return ModelsHelper.createItemModel(resourceLocation); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/FlowerPotBlock.java b/src/main/java/org/betterx/betterend/blocks/FlowerPotBlock.java new file mode 100644 index 00000000..3580fbca --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/FlowerPotBlock.java @@ -0,0 +1,460 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlockNotFull; +import org.betterx.bclib.client.models.BasePatterns; +import org.betterx.bclib.client.models.ModelsHelper; +import org.betterx.bclib.client.models.ModelsHelper.MultiPartBuilder; +import org.betterx.bclib.client.models.PatternsHelper; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.PostInitable; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.JsonFactory; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.basis.PottableLeavesBlock; +import org.betterx.betterend.client.models.Patterns; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.interfaces.PottablePlant; +import org.betterx.betterend.interfaces.PottableTerrain; +import org.betterx.betterend.registry.EndBlocks; + +import com.mojang.math.Transformation; +import com.mojang.math.Vector3f; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.resources.model.ModelResourceLocation; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SaplingBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.storage.loot.LootContext.Builder; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; +import net.fabricmc.loader.api.FabricLoader; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class FlowerPotBlock extends BaseBlockNotFull implements RenderLayerProvider, PostInitable { + private static final IntegerProperty PLANT_ID = EndBlockProperties.PLANT_ID; + private static final IntegerProperty SOIL_ID = EndBlockProperties.SOIL_ID; + private static final IntegerProperty POT_LIGHT = EndBlockProperties.POT_LIGHT; + private static final VoxelShape SHAPE_EMPTY; + private static final VoxelShape SHAPE_FULL; + private static Block[] plants; + private static Block[] soils; + + public FlowerPotBlock(Block source) { + super(FabricBlockSettings.copyOf(source).luminance(state -> state.getValue(POT_LIGHT) * 5)); + this.registerDefaultState( + this.defaultBlockState() + .setValue(PLANT_ID, 0) + .setValue(SOIL_ID, 0) + .setValue(POT_LIGHT, 0) + ); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + super.createBlockStateDefinition(builder); + builder.add(PLANT_ID, SOIL_ID, POT_LIGHT); + } + + @Override + public List getDrops(BlockState state, Builder builder) { + List drop = Lists.newArrayList(new ItemStack(this)); + int id = state.getValue(SOIL_ID) - 1; + if (id >= 0 && id < soils.length && soils[id] != null) { + drop.add(new ItemStack(soils[id])); + } + id = state.getValue(PLANT_ID) - 1; + if (id >= 0 && id < plants.length && plants[id] != null) { + drop.add(new ItemStack(plants[id])); + } + return drop; + } + + @Override + @SuppressWarnings("deprecation") + public BlockState updateShape( + BlockState state, + Direction facing, + BlockState neighborState, + LevelAccessor world, + BlockPos pos, + BlockPos neighborPos + ) { + int plantID = state.getValue(PLANT_ID); + if (plantID < 1 || plantID > plants.length || plants[plantID - 1] == null) { + return state.getValue(POT_LIGHT) > 0 ? state.setValue(POT_LIGHT, 0) : state; + } + int light = plants[plantID - 1].defaultBlockState().getLightEmission() / 5; + if (state.getValue(POT_LIGHT) != light) { + state = state.setValue(POT_LIGHT, light); + } + return state; + } + + @Override + public void postInit() { + if (FlowerPotBlock.plants != null) { + return; + } + + Block[] plants = new Block[128]; + Block[] soils = new Block[16]; + + Map reservedPlantsIDs = Maps.newHashMap(); + Map reservedSoilIDs = Maps.newHashMap(); + + JsonObject obj = JsonFactory.getJsonObject(new File( + FabricLoader.getInstance().getConfigDir().toFile(), + BetterEnd.MOD_ID + "/blocks.json" + )); + if (obj.get("flower_pots") != null) { + JsonElement plantsObj = obj.get("flower_pots").getAsJsonObject().get("plants"); + JsonElement soilsObj = obj.get("flower_pots").getAsJsonObject().get("soils"); + if (plantsObj != null) { + plantsObj.getAsJsonObject().entrySet().forEach(entry -> { + String name = entry.getKey().substring(0, entry.getKey().indexOf(' ')); + reservedPlantsIDs.put(name, entry.getValue().getAsInt()); + }); + } + if (soilsObj != null) { + soilsObj.getAsJsonObject().entrySet().forEach(entry -> { + String name = entry.getKey().substring(0, entry.getKey().indexOf(' ')); + reservedSoilIDs.put(name, entry.getValue().getAsInt()); + }); + } + } + + EndBlocks.getModBlocks().forEach(block -> { + if (block instanceof PottablePlant && ((PottablePlant) block).canBePotted()) { + processBlock(plants, block, "flower_pots.plants", reservedPlantsIDs); + } else if (block instanceof PottableTerrain && ((PottableTerrain) block).canBePotted()) { + processBlock(soils, block, "flower_pots.soils", reservedSoilIDs); + } + }); + Configs.BLOCK_CONFIG.saveChanges(); + + FlowerPotBlock.plants = new Block[maxNotNull(plants) + 1]; + System.arraycopy(plants, 0, FlowerPotBlock.plants, 0, FlowerPotBlock.plants.length); + + FlowerPotBlock.soils = new Block[maxNotNull(soils) + 1]; + System.arraycopy(soils, 0, FlowerPotBlock.soils, 0, FlowerPotBlock.soils.length); + + if (PLANT_ID.getValue(Integer.toString(FlowerPotBlock.plants.length)).isEmpty()) { + throw new RuntimeException("There are too much plant ID values!"); + } + if (SOIL_ID.getValue(Integer.toString(FlowerPotBlock.soils.length)).isEmpty()) { + throw new RuntimeException("There are too much soil ID values!"); + } + } + + private int maxNotNull(Block[] array) { + int max = 0; + for (int i = 0; i < array.length; i++) { + if (array[i] != null) { + max = i; + } + } + return max; + } + + private void processBlock(Block[] target, Block block, String path, Map idMap) { + ResourceLocation location = Registry.BLOCK.getKey(block); + if (idMap.containsKey(location.getPath())) { + target[idMap.get(location.getPath())] = block; + } else { + for (int i = 0; i < target.length; i++) { + if (!idMap.containsValue(i)) { + target[i] = block; + idMap.put(location.getPath(), i); + Configs.BLOCK_CONFIG.getInt(path, location.getPath(), i); + break; + } + } + } + } + + @Override + @SuppressWarnings("deprecation") + public InteractionResult use( + BlockState state, + Level level, + BlockPos pos, + Player player, + InteractionHand hand, + BlockHitResult hit + ) { + if (level.isClientSide) { + return InteractionResult.CONSUME; + } + ItemStack itemStack = player.getItemInHand(hand); + int soilID = state.getValue(SOIL_ID); + if (soilID == 0 || soilID > soils.length || soils[soilID - 1] == null) { + if (!(itemStack.getItem() instanceof BlockItem)) { + return InteractionResult.PASS; + } + Block block = ((BlockItem) itemStack.getItem()).getBlock(); + for (int i = 0; i < soils.length; i++) { + if (block == soils[i]) { + BlocksHelper.setWithUpdate(level, pos, state.setValue(SOIL_ID, i + 1)); + if (!player.isCreative()) { + itemStack.shrink(1); + } + level.playSound( + player, + pos.getX() + 0.5, + pos.getY() + 0.5, + pos.getZ() + 0.5, + SoundEvents.SOUL_SOIL_PLACE, + SoundSource.BLOCKS, + 1, + 1 + ); + return InteractionResult.SUCCESS; + } + } + return InteractionResult.PASS; + } + + int plantID = state.getValue(PLANT_ID); + if (itemStack.isEmpty()) { + if (plantID > 0 && plantID <= plants.length && plants[plantID - 1] != null) { + BlocksHelper.setWithUpdate(level, pos, state.setValue(PLANT_ID, 0).setValue(POT_LIGHT, 0)); + player.addItem(new ItemStack(plants[plantID - 1])); + return InteractionResult.SUCCESS; + } + if (soilID > 0 && soilID <= soils.length && soils[soilID - 1] != null) { + BlocksHelper.setWithUpdate(level, pos, state.setValue(SOIL_ID, 0)); + player.addItem(new ItemStack(soils[soilID - 1])); + } + return InteractionResult.PASS; + } + if (!(itemStack.getItem() instanceof BlockItem)) { + return InteractionResult.PASS; + } + BlockItem item = (BlockItem) itemStack.getItem(); + for (int i = 0; i < plants.length; i++) { + if (item.getBlock() == plants[i]) { + if (!((PottablePlant) plants[i]).canPlantOn(soils[soilID - 1])) { + return InteractionResult.PASS; + } + int light = plants[i].defaultBlockState().getLightEmission() / 5; + BlocksHelper.setWithUpdate(level, pos, state.setValue(PLANT_ID, i + 1).setValue(POT_LIGHT, light)); + level.playSound( + player, + pos.getX() + 0.5, + pos.getY() + 0.5, + pos.getZ() + 0.5, + SoundEvents.HOE_TILL, + SoundSource.BLOCKS, + 1, + 1 + ); + if (!player.isCreative()) { + itemStack.shrink(1); + } + return InteractionResult.SUCCESS; + } + } + return InteractionResult.PASS; + } + + @Override + @Environment(EnvType.CLIENT) + public BlockModel getItemModel(ResourceLocation blockId) { + Optional pattern = PatternsHelper.createJson(Patterns.BLOCK_FLOWER_POT, blockId); + return ModelsHelper.fromPattern(pattern); + } + + @Override + @Environment(EnvType.CLIENT) + public UnbakedModel getModelVariant( + ResourceLocation stateId, + BlockState blockState, + Map modelCache + ) { + MultiPartBuilder model = MultiPartBuilder.create(stateDefinition); + model.part(new ModelResourceLocation(stateId.getNamespace(), stateId.getPath(), "inventory")).add(); + Transformation offset = new Transformation(new Vector3f(0, 7.5F / 16F, 0), null, null, null); + + for (int i = 0; i < plants.length; i++) { + if (plants[i] == null) { + continue; + } + + final int compareID = i + 1; + ResourceLocation modelPath = Registry.BLOCK.getKey(plants[i]); + ResourceLocation objSource = new ResourceLocation( + modelPath.getNamespace(), + "models/block/" + modelPath.getPath() + "_potted.json" + ); + + if (Minecraft.getInstance().getResourceManager().getResource(objSource).isPresent()) { + objSource = new ResourceLocation(modelPath.getNamespace(), "block/" + modelPath.getPath() + "_potted"); + model.part(objSource) + .setTransformation(offset) + .setCondition(state -> state.getValue(PLANT_ID) == compareID) + .add(); + continue; + } else if (plants[i] instanceof SaplingBlock) { + ResourceLocation loc = Registry.BLOCK.getKey(plants[i]); + modelPath = new ResourceLocation(loc.getNamespace(), "block/" + loc.getPath() + "_potted"); + Map textures = Maps.newHashMap(); + textures.put("%modid%", loc.getNamespace()); + textures.put("%texture%", loc.getPath()); + Optional pattern = Patterns.createJson(BasePatterns.BLOCK_CROSS, textures); + UnbakedModel unbakedModel = ModelsHelper.fromPattern(pattern); + modelCache.put(modelPath, unbakedModel); + model.part(modelPath) + .setTransformation(offset) + .setCondition(state -> state.getValue(PLANT_ID) == compareID) + .add(); + continue; + } else if (plants[i] instanceof PottableLeavesBlock) { + ResourceLocation loc = Registry.BLOCK.getKey(plants[i]); + modelPath = new ResourceLocation(loc.getNamespace(), "block/" + loc.getPath() + "_potted"); + Map textures = Maps.newHashMap(); + textures.put("%leaves%", loc.getPath().contains("lucernia") ? loc.getPath() + "_1" : loc.getPath()); + textures.put("%stem%", loc.getPath().replace("_leaves", "_log_side")); + Optional pattern = Patterns.createJson(Patterns.BLOCK_POTTED_LEAVES, textures); + UnbakedModel unbakedModel = ModelsHelper.fromPattern(pattern); + modelCache.put(modelPath, unbakedModel); + model.part(modelPath) + .setTransformation(offset) + .setCondition(state -> state.getValue(PLANT_ID) == compareID) + .add(); + continue; + } + + objSource = new ResourceLocation(modelPath.getNamespace(), "blockstates/" + modelPath.getPath() + ".json"); + JsonObject obj = JsonFactory.getJsonObject(objSource); + if (obj != null) { + JsonElement variants = obj.get("variants"); + JsonElement list = null; + String path = null; + + if (variants == null) { + continue; + } + + if (variants.isJsonArray()) { + list = variants.getAsJsonArray().get(0); + } else if (variants.isJsonObject()) { + list = variants.getAsJsonObject().get(((PottablePlant) plants[i]).getPottedState()); + } + + if (list == null) { + BetterEnd.LOGGER.warning("Incorrect json for pot plant " + objSource + ", no matching variants"); + continue; + } + + if (list.isJsonArray()) { + path = list.getAsJsonArray().get(0).getAsJsonObject().get("model").getAsString(); + } else { + path = list.getAsJsonObject().get("model").getAsString(); + } + + if (path == null) { + BetterEnd.LOGGER.warning("Incorrect json for pot plant " + objSource + ", no matching variants"); + continue; + } + + model.part(new ResourceLocation(path)) + .setTransformation(offset) + .setCondition(state -> state.getValue(PLANT_ID) == compareID) + .add(); + } else { + ResourceLocation loc = Registry.BLOCK.getKey(plants[i]); + modelPath = new ResourceLocation(loc.getNamespace(), "block/" + loc.getPath() + "_potted"); + Map textures = Maps.newHashMap(); + textures.put("%modid%", loc.getNamespace()); + textures.put("%texture%", loc.getPath()); + Optional pattern = Patterns.createJson(BasePatterns.BLOCK_CROSS, textures); + UnbakedModel unbakedModel = ModelsHelper.fromPattern(pattern); + modelCache.put(modelPath, unbakedModel); + model.part(modelPath) + .setTransformation(offset) + .setCondition(state -> state.getValue(PLANT_ID) == compareID) + .add(); + } + } + + for (int i = 0; i < soils.length; i++) { + if (soils[i] == null) { + continue; + } + + ResourceLocation soilLoc = BetterEnd.makeID("flower_pot_soil_" + i); + if (!modelCache.containsKey(soilLoc)) { + String texture = Registry.BLOCK.getKey(soils[i]).getPath() + "_top"; + if (texture.contains("rutiscus")) { + texture += "_1"; + } + Optional pattern = Patterns.createJson(Patterns.BLOCK_FLOWER_POT_SOIL, texture); + UnbakedModel soil = ModelsHelper.fromPattern(pattern); + modelCache.put(soilLoc, soil); + } + final int compareID = i + 1; + model.part(soilLoc).setCondition(state -> state.getValue(SOIL_ID) == compareID).add(); + } + + UnbakedModel result = model.build(); + modelCache.put(stateId, result); + return result; + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + int id = state.getValue(PLANT_ID); + return id > 0 && id <= plants.length ? SHAPE_FULL : SHAPE_EMPTY; + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getCollisionShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return SHAPE_EMPTY; + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + static { + SHAPE_EMPTY = Shapes.or(Block.box(4, 1, 4, 12, 8, 12), Block.box(5, 0, 5, 11, 1, 11)); + SHAPE_FULL = Shapes.or(SHAPE_EMPTY, Block.box(3, 8, 3, 13, 16, 13)); + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/blocks/GlowingHymenophoreBlock.java b/src/main/java/org/betterx/betterend/blocks/GlowingHymenophoreBlock.java new file mode 100644 index 00000000..eeaafd33 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/GlowingHymenophoreBlock.java @@ -0,0 +1,17 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.interfaces.tools.AddMineableAxe; + +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.material.Material; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class GlowingHymenophoreBlock extends BaseBlock implements AddMineableAxe { + public GlowingHymenophoreBlock() { + super(FabricBlockSettings.of(Material.WOOD) + .luminance(15) + .sound(SoundType.WART_BLOCK)); + } +} diff --git a/src/main/java/ru/betterend/blocks/GlowingMossBlock.java b/src/main/java/org/betterx/betterend/blocks/GlowingMossBlock.java similarity index 50% rename from src/main/java/ru/betterend/blocks/GlowingMossBlock.java rename to src/main/java/org/betterx/betterend/blocks/GlowingMossBlock.java index 22191437..9c7c33dd 100644 --- a/src/main/java/ru/betterend/blocks/GlowingMossBlock.java +++ b/src/main/java/org/betterx/betterend/blocks/GlowingMossBlock.java @@ -1,30 +1,32 @@ -package ru.betterend.blocks; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.state.BlockState; -import ru.betterend.blocks.basis.EndPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class GlowingMossBlock extends EndPlantBlock { - public GlowingMossBlock(int light) { - super(light); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.getBlock() == EndBlocks.END_MOSS || state.getBlock() == EndBlocks.END_MYCELIUM; - } - - @Environment(EnvType.CLIENT) - public boolean hasEmissiveLighting(BlockGetter world, BlockPos pos) { - return true; - } - - @Environment(EnvType.CLIENT) - public float getAmbientOcclusionLightLevel(BlockGetter world, BlockPos pos) { - return 1F; - } +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.EndPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.state.BlockState; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class GlowingMossBlock extends EndPlantBlock { + public GlowingMossBlock(int light) { + super(light); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.getBlock() == EndBlocks.END_MOSS || state.getBlock() == EndBlocks.END_MYCELIUM; + } + + @Environment(EnvType.CLIENT) + public boolean hasEmissiveLighting(BlockGetter world, BlockPos pos) { + return true; + } + + @Environment(EnvType.CLIENT) + public float getAmbientOcclusionLightLevel(BlockGetter world, BlockPos pos) { + return 1F; + } } \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/blocks/GlowingPillarLuminophorBlock.java b/src/main/java/org/betterx/betterend/blocks/GlowingPillarLuminophorBlock.java new file mode 100644 index 00000000..b2c44702 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/GlowingPillarLuminophorBlock.java @@ -0,0 +1,61 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.interfaces.tools.AddMineableShears; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class GlowingPillarLuminophorBlock extends BaseBlock implements AddMineableShears { + public static final BooleanProperty NATURAL = EndBlockProperties.NATURAL; + + public GlowingPillarLuminophorBlock() { + super(FabricBlockSettings.of(Material.LEAVES) + .mapColor(MaterialColor.COLOR_ORANGE) + .strength(0.2F) + .luminance(15) + .sound(SoundType.GRASS)); + this.registerDefaultState(this.stateDefinition.any().setValue(NATURAL, false)); + } + + @Override + @SuppressWarnings("deprecation") + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + return !state.getValue(NATURAL) || world.getBlockState(pos.below()).is(EndBlocks.GLOWING_PILLAR_ROOTS); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState updateShape( + BlockState state, + Direction facing, + BlockState neighborState, + LevelAccessor world, + BlockPos pos, + BlockPos neighborPos + ) { + if (!canSurvive(state, world, pos)) { + return Blocks.AIR.defaultBlockState(); + } else { + return state; + } + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(NATURAL); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/GlowingPillarRootsBlock.java b/src/main/java/org/betterx/betterend/blocks/GlowingPillarRootsBlock.java new file mode 100644 index 00000000..daacc8af --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/GlowingPillarRootsBlock.java @@ -0,0 +1,37 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.blocks.UpDownPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.EnumProperty; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class GlowingPillarRootsBlock extends UpDownPlantBlock { + public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(SHAPE); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.AMBER_MOSS); + } + + @Override + @Environment(EnvType.CLIENT) + public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) { + return new ItemStack(EndBlocks.GLOWING_PILLAR_SEED); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/GlowingPillarSeedBlock.java b/src/main/java/org/betterx/betterend/blocks/GlowingPillarSeedBlock.java new file mode 100644 index 00000000..730e91a0 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/GlowingPillarSeedBlock.java @@ -0,0 +1,82 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.interfaces.tools.AddMineableShears; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.material.Material; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class GlowingPillarSeedBlock extends EndPlantWithAgeBlock implements AddMineableShears { + + public GlowingPillarSeedBlock() { + super(FabricBlockSettings.of(Material.PLANT) + .sound(SoundType.GRASS) + .lightLevel(state -> state.getValue(AGE) * 3 + 3) + .randomTicks() + .noCollission() + .offsetType(OffsetType.NONE)); + } + + @Override + public void growAdult(WorldGenLevel world, RandomSource random, BlockPos pos) { + int height = MHelper.randRange(1, 2, random); + int h = BlocksHelper.upRay(world, pos, height + 2); + if (h < height) { + return; + } + + MutableBlockPos mut = new MutableBlockPos().set(pos); + BlockState roots = EndBlocks.GLOWING_PILLAR_ROOTS.defaultBlockState(); + if (height < 2) { + BlocksHelper.setWithUpdate(world, mut, roots.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE)); + } else { + BlocksHelper.setWithUpdate(world, mut, roots.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM)); + mut.move(Direction.UP); + BlocksHelper.setWithUpdate(world, mut, roots.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP)); + } + mut.move(Direction.UP); + BlocksHelper.setWithUpdate( + world, + mut, + EndBlocks.GLOWING_PILLAR_LUMINOPHOR.defaultBlockState().setValue(BlueVineLanternBlock.NATURAL, true) + ); + for (Direction dir : BlocksHelper.DIRECTIONS) { + pos = mut.relative(dir); + if (world.isEmptyBlock(pos)) { + BlocksHelper.setWithUpdate( + world, + pos, + EndBlocks.GLOWING_PILLAR_LEAVES.defaultBlockState().setValue(BlockStateProperties.FACING, dir) + ); + } + } + mut.move(Direction.UP); + if (world.isEmptyBlock(mut)) { + BlocksHelper.setWithUpdate( + world, + mut, + EndBlocks.GLOWING_PILLAR_LEAVES.defaultBlockState() + .setValue(BlockStateProperties.FACING, Direction.UP) + ); + } + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.AMBER_MOSS); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/HelixTreeLeavesBlock.java b/src/main/java/org/betterx/betterend/blocks/HelixTreeLeavesBlock.java new file mode 100644 index 00000000..71e24824 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/HelixTreeLeavesBlock.java @@ -0,0 +1,84 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.blocks.BaseLeavesBlock; +import org.betterx.bclib.interfaces.CustomColorProvider; +import org.betterx.bclib.interfaces.tools.AddMineableShears; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.ui.ColorUtil; +import org.betterx.worlds.together.tag.v3.TagManager; + +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.item.ItemColor; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.Mth; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.material.MaterialColor; +import net.minecraft.world.level.storage.loot.LootContext; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.List; + +public class HelixTreeLeavesBlock extends BaseBlock implements CustomColorProvider, AddMineableShears { + public static final IntegerProperty COLOR = EndBlockProperties.COLOR; + private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(0); + + public HelixTreeLeavesBlock() { + super(FabricBlockSettings + .of(Material.LEAVES) + .mapColor(MaterialColor.COLOR_ORANGE) + .sound(SoundType.WART_BLOCK) + .sound(SoundType.GRASS) + .strength(0.2F) + ); + + TagManager.BLOCKS.add(BlockTags.LEAVES, this); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(COLOR); + } + + @Override + public BlockColor getProvider() { + return (state, world, pos, tintIndex) -> { + return ColorUtil.color(237, getGreen(state.getValue(COLOR)), 20); + }; + } + + @Override + public ItemColor getItemProvider() { + return (stack, tintIndex) -> { + return ColorUtil.color(237, getGreen(4), 20); + }; + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + double px = ctx.getClickedPos().getX() * 0.1; + double py = ctx.getClickedPos().getY() * 0.1; + double pz = ctx.getClickedPos().getZ() * 0.1; + return this.defaultBlockState().setValue(COLOR, MHelper.floor(NOISE.eval(px, py, pz) * 3.5 + 4)); + } + + private int getGreen(int color) { + float delta = color / 7F; + return (int) Mth.lerp(delta, 80, 158); + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + return BaseLeavesBlock.getLeaveDrops(this, EndBlocks.HELIX_TREE_SAPLING, builder, 16, 32); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/HelixTreeSaplingBlock.java b/src/main/java/org/betterx/betterend/blocks/HelixTreeSaplingBlock.java new file mode 100644 index 00000000..c59a070d --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/HelixTreeSaplingBlock.java @@ -0,0 +1,28 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.PottableFeatureSapling; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.features.trees.HelixTreeFeature; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class HelixTreeSaplingBlock extends PottableFeatureSapling { + public HelixTreeSaplingBlock() { + super((state) -> EndFeatures.HELIX_TREE.configuredFeature); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + return world.getBlockState(pos.below()).is(EndBlocks.AMBER_MOSS); + } + + @Override + public boolean canPlantOn(Block block) { + return block == EndBlocks.AMBER_MOSS; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/HydraluxBlock.java b/src/main/java/org/betterx/betterend/blocks/HydraluxBlock.java new file mode 100644 index 00000000..c2e57103 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/HydraluxBlock.java @@ -0,0 +1,96 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.UnderwaterPlantBlock; +import org.betterx.bclib.interfaces.tools.AddMineableShears; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.EndBlockProperties.HydraluxShape; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.storage.loot.LootContext; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import com.google.common.collect.Lists; + +import java.util.Collections; +import java.util.List; + +public class HydraluxBlock extends UnderwaterPlantBlock implements AddMineableShears { + + public static final EnumProperty SHAPE = EndBlockProperties.HYDRALUX_SHAPE; + + public HydraluxBlock() { + super(baseUnderwaterPlantSettings() + .lightLevel((state) -> state.getValue(SHAPE).hasGlow() ? 15 : 0) + ); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(SHAPE); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + BlockState down = world.getBlockState(pos.below()); + HydraluxShape shape = state.getValue(SHAPE); + if (shape == HydraluxShape.FLOWER_BIG_TOP || shape == HydraluxShape.FLOWER_SMALL_TOP) { + return down.is(this); + } else if (shape == HydraluxShape.ROOTS) { + return down.is(EndBlocks.SULPHURIC_ROCK.stone) && world.getBlockState(pos.above()).is(this); + } else { + return down.is(this) && world.getBlockState(pos.above()).is(this); + } + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(CommonBlockTags.END_STONES); + } + + @Override + public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { + return false; + } + + @Override + public boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state) { + return false; + } + + @Override + @Environment(EnvType.CLIENT) + public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) { + return new ItemStack(EndBlocks.HYDRALUX_SAPLING); + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + HydraluxShape shape = state.getValue(SHAPE); + if (shape == HydraluxShape.FLOWER_BIG_BOTTOM || shape == HydraluxShape.FLOWER_SMALL_BOTTOM) { + return Lists.newArrayList(new ItemStack( + EndItems.HYDRALUX_PETAL, + MHelper.randRange(1, 4, MHelper.RANDOM_SOURCE) + )); + } else if (shape == HydraluxShape.ROOTS) { + return Lists.newArrayList(new ItemStack( + EndBlocks.HYDRALUX_SAPLING, + MHelper.randRange(1, 2, MHelper.RANDOM_SOURCE) + )); + } + return Collections.emptyList(); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/HydraluxPetalBlock.java b/src/main/java/org/betterx/betterend/blocks/HydraluxPetalBlock.java new file mode 100644 index 00000000..7ab668d4 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/HydraluxPetalBlock.java @@ -0,0 +1,35 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.interfaces.tools.AddMineableAxe; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class HydraluxPetalBlock extends BaseBlock implements AddMineableAxe { + public HydraluxPetalBlock() { + this( + FabricBlockSettings + .of(Material.PLANT) + .hardness(1) + .resistance(1) + .mapColor(MaterialColor.PODZOL) + .sound(SoundType.WART_BLOCK) + ); + } + + public HydraluxPetalBlock(Properties settings) { + super(settings); + } + + @Override + public void fallOn(Level level, BlockState blockState, BlockPos blockPos, Entity entity, float f) { + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/HydraluxPetalColoredBlock.java b/src/main/java/org/betterx/betterend/blocks/HydraluxPetalColoredBlock.java new file mode 100644 index 00000000..8e2b8e80 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/HydraluxPetalColoredBlock.java @@ -0,0 +1,43 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.client.models.ModelsHelper; +import org.betterx.bclib.interfaces.CustomColorProvider; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.client.models.Patterns; + +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.item.ItemColor; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.state.BlockState; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Optional; +import org.jetbrains.annotations.Nullable; + +public class HydraluxPetalColoredBlock extends HydraluxPetalBlock implements CustomColorProvider { + public HydraluxPetalColoredBlock(FabricBlockSettings settings) { + super(settings); + } + + @Override + public BlockColor getProvider() { + return (state, world, pos, tintIndex) -> BlocksHelper.getBlockColor(this); + } + + @Override + public ItemColor getItemProvider() { + return (stack, tintIndex) -> BlocksHelper.getBlockColor(this); + } + + @Override + @Environment(EnvType.CLIENT) + public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { + String path = "betterend:block/block_petal_colored"; + Optional pattern = Patterns.createJson(Patterns.BLOCK_PETAL_COLORED, path, path); + return ModelsHelper.fromPattern(pattern); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/HydraluxSaplingBlock.java b/src/main/java/org/betterx/betterend/blocks/HydraluxSaplingBlock.java new file mode 100644 index 00000000..c06202cd --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/HydraluxSaplingBlock.java @@ -0,0 +1,75 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.UnderwaterPlantWithAgeBlock; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +public class HydraluxSaplingBlock extends UnderwaterPlantWithAgeBlock { + + @Override + public void grow(WorldGenLevel world, RandomSource random, BlockPos pos) { + int h = MHelper.randRange(4, 8, random); + MutableBlockPos mut = new MutableBlockPos().set(pos); + + for (int i = 1; i < h; i++) { + mut.setY(pos.getY() + i); + if (!world.getBlockState(mut).is(Blocks.WATER)) { + return; + } + } + + mut.setY(pos.getY()); + BlockState state = EndBlocks.HYDRALUX.defaultBlockState(); + BlocksHelper.setWithoutUpdate( + world, + pos, + state.setValue(EndBlockProperties.HYDRALUX_SHAPE, EndBlockProperties.HydraluxShape.ROOTS) + ); + for (int i = 1; i < h - 2; i++) { + mut.setY(pos.getY() + i); + BlocksHelper.setWithoutUpdate( + world, + mut, + state.setValue(EndBlockProperties.HYDRALUX_SHAPE, EndBlockProperties.HydraluxShape.VINE) + ); + } + + mut.setY(mut.getY() + 1); + boolean big = random.nextBoolean(); + BlocksHelper.setWithoutUpdate( + world, + mut, + state.setValue( + EndBlockProperties.HYDRALUX_SHAPE, + big + ? EndBlockProperties.HydraluxShape.FLOWER_BIG_BOTTOM + : EndBlockProperties.HydraluxShape.FLOWER_SMALL_BOTTOM + ) + ); + + mut.setY(mut.getY() + 1); + BlocksHelper.setWithoutUpdate( + world, + mut, + state.setValue( + EndBlockProperties.HYDRALUX_SHAPE, + big + ? EndBlockProperties.HydraluxShape.FLOWER_BIG_TOP + : EndBlockProperties.HydraluxShape.FLOWER_SMALL_TOP + ) + ); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.SULPHURIC_ROCK.stone); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/HydrothermalVentBlock.java b/src/main/java/org/betterx/betterend/blocks/HydrothermalVentBlock.java new file mode 100644 index 00000000..56e32f04 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/HydrothermalVentBlock.java @@ -0,0 +1,161 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlockNotFull; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.interfaces.tools.AddMineablePickaxe; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.blocks.entities.BlockEntityHydrothermalVent; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import org.jetbrains.annotations.Nullable; + +@SuppressWarnings("deprecation") +public class HydrothermalVentBlock extends BaseBlockNotFull implements EntityBlock, LiquidBlockContainer, SimpleWaterloggedBlock, AddMineablePickaxe { + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + public static final BooleanProperty ACTIVATED = BlockProperties.ACTIVE; + private static final VoxelShape SHAPE = Block.box(1, 1, 1, 15, 16, 15); + + public HydrothermalVentBlock() { + super(FabricBlockSettings.of(Material.STONE) + .sound(SoundType.STONE) + .noCollission() + .requiresCorrectToolForDrops()); + this.registerDefaultState(defaultBlockState().setValue(WATERLOGGED, true).setValue(ACTIVATED, false)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(WATERLOGGED, ACTIVATED); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return SHAPE; + } + + @Override + public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { + return false; + } + + @Override + public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) { + return false; + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + state = world.getBlockState(pos.below()); + return state.is(EndBlocks.SULPHURIC_ROCK.stone); + } + + @Override + public BlockState updateShape( + BlockState state, + Direction facing, + BlockState neighborState, + LevelAccessor world, + BlockPos pos, + BlockPos neighborPos + ) { + if (!canSurvive(state, world, pos)) { + return Blocks.WATER.defaultBlockState(); + } else if (state.getValue(WATERLOGGED) && facing == Direction.UP && neighborState.is(Blocks.WATER)) { + world.scheduleTick(pos, this, 20); + } + return state; + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + LevelAccessor worldAccess = ctx.getLevel(); + BlockPos blockPos = ctx.getClickedPos(); + return this.defaultBlockState() + .setValue(WATERLOGGED, worldAccess.getFluidState(blockPos).getType() == Fluids.WATER); + } + + @Override + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); + } + + @Override + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { + return new BlockEntityHydrothermalVent(pos, state); + } + + @Override + public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + BlockPos up = pos.above(); + if (world.getBlockState(up).is(Blocks.WATER)) { + BlocksHelper.setWithoutUpdate(world, up, EndBlocks.VENT_BUBBLE_COLUMN); + world.scheduleTick(up, EndBlocks.VENT_BUBBLE_COLUMN, 5); + } + } + + @Override + public void setPlacedBy( + Level world, + BlockPos pos, + BlockState state, + @Nullable LivingEntity placer, + ItemStack itemStack + ) { + if (world instanceof ServerLevel && state.getValue(WATERLOGGED) && world.getBlockState(pos.above()) + .is(Blocks.WATER)) { + tick(state, (ServerLevel) world, pos, world.random); + } + } + + @Environment(EnvType.CLIENT) + public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) { + super.animateTick(state, world, pos, random); + if (!state.getValue(ACTIVATED) && random.nextBoolean()) { + double x = pos.getX() + random.nextDouble(); + double y = pos.getY() + 0.9 + random.nextDouble() * 0.3; + double z = pos.getZ() + random.nextDouble(); + world.addParticle(ParticleTypes.LARGE_SMOKE, x, y, z, 0, 0, 0); + } + } + + @Nullable + @Override + public BlockEntityTicker getTicker( + Level level, + BlockState blockState, + BlockEntityType blockEntityType + ) { + return BlockEntityHydrothermalVent::tick; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/InfusionPedestal.java b/src/main/java/org/betterx/betterend/blocks/InfusionPedestal.java new file mode 100644 index 00000000..49e500b4 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/InfusionPedestal.java @@ -0,0 +1,103 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.PedestalBlock; +import org.betterx.betterend.blocks.entities.InfusionPedestalEntity; +import org.betterx.betterend.rituals.InfusionRitual; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import org.jetbrains.annotations.Nullable; + +@SuppressWarnings("deprecation") +public class InfusionPedestal extends PedestalBlock { + private static final VoxelShape SHAPE_DEFAULT; + private static final VoxelShape SHAPE_PEDESTAL_TOP; + + public InfusionPedestal() { + super(Blocks.OBSIDIAN); + this.height = 1.08F; + } + + @Override + public void checkRitual(Level world, Player player, BlockPos pos) { + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof InfusionPedestalEntity) { + InfusionPedestalEntity pedestal = (InfusionPedestalEntity) blockEntity; + if (pedestal.hasRitual()) { + InfusionRitual ritual = pedestal.getRitual(); + if (!ritual.isValid()) { + ritual.configure(); + } + pedestal.getRitual().checkRecipe(); + } else { + InfusionRitual ritual = pedestal.linkRitual(pedestal, world, pos); + ritual.checkRecipe(); + } + } + } + + @Override + public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { + return new InfusionPedestalEntity(blockPos, blockState); + } + + @Override + public boolean hasUniqueEntity() { + return true; + } + + @Override + @Deprecated + public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + if (state.is(this)) { + switch (state.getValue(STATE)) { + case PEDESTAL_TOP: { + return SHAPE_PEDESTAL_TOP; + } + case DEFAULT: { + return SHAPE_DEFAULT; + } + default: { + return super.getShape(state, world, pos, context); + } + } + } + return super.getShape(state, world, pos, context); + } + + @Override + @Nullable + public BlockEntityTicker getTicker( + Level level, + BlockState blockState, + BlockEntityType blockEntityType + ) { + return InfusionPedestalEntity::tickEnity; + } + + static { + VoxelShape basinUp = Block.box(2, 3, 2, 14, 4, 14); + VoxelShape basinDown = Block.box(0, 0, 0, 16, 3, 16); + VoxelShape pedestalTop = Block.box(1, 9, 1, 15, 11, 15); + VoxelShape pedestalDefault = Block.box(1, 13, 1, 15, 15, 15); + VoxelShape pillar = Block.box(3, 0, 3, 13, 9, 13); + VoxelShape pillarDefault = Block.box(3, 4, 3, 13, 13, 13); + VoxelShape eyeDefault = Block.box(4, 15, 4, 12, 16, 12); + VoxelShape eyeTop = Block.box(4, 11, 4, 12, 12, 12); + VoxelShape basin = Shapes.or(basinDown, basinUp); + SHAPE_DEFAULT = Shapes.or(basin, pillarDefault, pedestalDefault, eyeDefault); + SHAPE_PEDESTAL_TOP = Shapes.or(pillar, pedestalTop, eyeTop); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/JellyshroomCapBlock.java b/src/main/java/org/betterx/betterend/blocks/JellyshroomCapBlock.java new file mode 100644 index 00000000..60f66e40 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/JellyshroomCapBlock.java @@ -0,0 +1,107 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.client.models.ModelsHelper; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.BlockModelProvider; +import org.betterx.bclib.interfaces.CustomColorProvider; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.client.models.Patterns; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.ui.ColorUtil; + +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.item.ItemColor; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.core.Vec3i; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SlimeBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.storage.loot.LootContext; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.Optional; +import org.jetbrains.annotations.Nullable; + +public class JellyshroomCapBlock extends SlimeBlock implements RenderLayerProvider, BlockModelProvider, CustomColorProvider { + public static final IntegerProperty COLOR = EndBlockProperties.COLOR; + private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(0); + private final Vec3i colorStart; + private final Vec3i colorEnd; + private final int coloritem; + + public JellyshroomCapBlock(int r1, int g1, int b1, int r2, int g2, int b2) { + super(FabricBlockSettings.copyOf(Blocks.SLIME_BLOCK)); + colorStart = new Vec3i(r1, g1, b1); + colorEnd = new Vec3i(r2, g2, b2); + coloritem = ColorUtil.color((r1 + r2) >> 1, (g1 + g2) >> 1, (b1 + b2) >> 1); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + double px = ctx.getClickedPos().getX() * 0.1; + double py = ctx.getClickedPos().getY() * 0.1; + double pz = ctx.getClickedPos().getZ() * 0.1; + return this.defaultBlockState().setValue(COLOR, MHelper.floor(NOISE.eval(px, py, pz) * 3.5 + 4)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(COLOR); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.TRANSLUCENT; + } + + @Override + @SuppressWarnings("deprecation") + public List getDrops(BlockState state, LootContext.Builder builder) { + return Lists.newArrayList(new ItemStack(this)); + } + + @Override + @Environment(EnvType.CLIENT) + public BlockModel getItemModel(ResourceLocation resourceLocation) { + return getBlockModel(resourceLocation, defaultBlockState()); + } + + @Override + @Environment(EnvType.CLIENT) + public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { + Optional pattern = Patterns.createJson(Patterns.BLOCK_COLORED, "jellyshroom_cap"); + return ModelsHelper.fromPattern(pattern); + } + + @Override + public BlockColor getProvider() { + return (state, world, pos, tintIndex) -> { + float delta = (float) state.getValue(COLOR) / 7F; + int r = Mth.floor(Mth.lerp(delta, colorStart.getX() / 255F, colorEnd.getX() / 255F) * 255F); + int g = Mth.floor(Mth.lerp(delta, colorStart.getY() / 255F, colorEnd.getY() / 255F) * 255F); + int b = Mth.floor(Mth.lerp(delta, colorStart.getZ() / 255F, colorEnd.getZ() / 255F) * 255F); + return ColorUtil.color(r, g, b); + }; + } + + @Override + public ItemColor getItemProvider() { + return (stack, tintIndex) -> { + return coloritem; + }; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/LacugroveSaplingBlock.java b/src/main/java/org/betterx/betterend/blocks/LacugroveSaplingBlock.java new file mode 100644 index 00000000..6ff9a157 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/LacugroveSaplingBlock.java @@ -0,0 +1,29 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.PottableFeatureSapling; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.features.trees.LacugroveFeature; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class LacugroveSaplingBlock extends PottableFeatureSapling { + public LacugroveSaplingBlock() { + super((state) -> EndFeatures.LACUGROVE.configuredFeature); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + return world.getBlockState(pos.below()).is(EndBlocks.END_MOSS) || world.getBlockState(pos.below()) + .is(EndBlocks.ENDSTONE_DUST); + } + + @Override + public boolean canPlantOn(Block block) { + return block == EndBlocks.END_MOSS; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/LanceleafBlock.java b/src/main/java/org/betterx/betterend/blocks/LanceleafBlock.java new file mode 100644 index 00000000..f74bd49f --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/LanceleafBlock.java @@ -0,0 +1,76 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.PentaShape; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.basis.EndPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.storage.loot.LootContext; + +import java.util.Collections; +import java.util.List; + +public class LanceleafBlock extends EndPlantBlock { + + public static final EnumProperty SHAPE = BlockProperties.PENTA_SHAPE; + public static final IntegerProperty ROTATION = BlockProperties.ROTATION; + + public LanceleafBlock() { + super(); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(SHAPE, ROTATION); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + PentaShape shape = state.getValue(SHAPE); + if (shape == PentaShape.TOP) { + return world.getBlockState(pos.below()).is(this); + } else if (shape == PentaShape.BOTTOM) { + return world.getBlockState(pos.below()).is(EndBlocks.AMBER_MOSS) && world.getBlockState(pos.above()) + .is(this); + } else { + return world.getBlockState(pos.below()).is(this) && world.getBlockState(pos.above()).is(this); + } + } + + @Override + public BlockState updateShape( + BlockState state, + Direction facing, + BlockState neighborState, + LevelAccessor world, + BlockPos pos, + BlockPos neighborPos + ) { + if (!canSurvive(state, world, pos)) { + return Blocks.AIR.defaultBlockState(); + } else { + return state; + } + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + if (state.getValue(SHAPE) == PentaShape.BOTTOM) { + return Collections.singletonList(new ItemStack(EndBlocks.LANCELEAF_SEED)); + } + return MHelper.RANDOM.nextBoolean() ? Collections.emptyList() : Collections.singletonList(new ItemStack( + EndBlocks.LANCELEAF_SEED)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/LanceleafSeedBlock.java b/src/main/java/org/betterx/betterend/blocks/LanceleafSeedBlock.java new file mode 100644 index 00000000..5ba28dc1 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/LanceleafSeedBlock.java @@ -0,0 +1,61 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.PentaShape; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; + +public class LanceleafSeedBlock extends EndPlantWithAgeBlock { + public LanceleafSeedBlock() { + super(basePlantSettings().offsetType(OffsetType.NONE)); + } + + @Override + public void growAdult(WorldGenLevel world, RandomSource random, BlockPos pos) { + int height = MHelper.randRange(4, 6, random); + int h = BlocksHelper.upRay(world, pos, height + 2); + if (h < height + 1) { + return; + } + int rotation = random.nextInt(4); + MutableBlockPos mut = new MutableBlockPos().set(pos); + BlockState plant = EndBlocks.LANCELEAF.defaultBlockState().setValue(BlockProperties.ROTATION, rotation); + BlocksHelper.setWithoutUpdate(world, mut, plant.setValue(BlockProperties.PENTA_SHAPE, PentaShape.BOTTOM)); + BlocksHelper.setWithoutUpdate( + world, + mut.move(Direction.UP), + plant.setValue(BlockProperties.PENTA_SHAPE, PentaShape.PRE_BOTTOM) + ); + for (int i = 2; i < height - 2; i++) { + BlocksHelper.setWithoutUpdate( + world, + mut.move(Direction.UP), + plant.setValue(BlockProperties.PENTA_SHAPE, PentaShape.MIDDLE) + ); + } + BlocksHelper.setWithoutUpdate( + world, + mut.move(Direction.UP), + plant.setValue(BlockProperties.PENTA_SHAPE, PentaShape.PRE_TOP) + ); + BlocksHelper.setWithoutUpdate( + world, + mut.move(Direction.UP), + plant.setValue(BlockProperties.PENTA_SHAPE, PentaShape.TOP) + ); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.AMBER_MOSS); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/LargeAmaranitaBlock.java b/src/main/java/org/betterx/betterend/blocks/LargeAmaranitaBlock.java new file mode 100644 index 00000000..bb298119 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/LargeAmaranitaBlock.java @@ -0,0 +1,70 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.interfaces.tools.AddMineableShears; +import org.betterx.betterend.blocks.basis.EndPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +public class LargeAmaranitaBlock extends EndPlantBlock implements AddMineableShears { + public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; + private static final VoxelShape SHAPE_BOTTOM = Block.box(4, 0, 4, 12, 14, 12); + private static final VoxelShape SHAPE_TOP = Shapes.or(Block.box(1, 3, 1, 15, 16, 15), SHAPE_BOTTOM); + + public LargeAmaranitaBlock() { + super(basePlantSettings() + .lightLevel((state) -> (state.getValue(SHAPE) == TripleShape.TOP) ? 15 : 0) + .offsetType(OffsetType.NONE) + ); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return state.getValue(SHAPE) == TripleShape.TOP ? SHAPE_TOP : SHAPE_BOTTOM; + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.SANGNUM) || state.is(EndBlocks.MOSSY_OBSIDIAN) || state.is(EndBlocks.MOSSY_DRAGON_BONE); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(SHAPE); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + TripleShape shape = state.getValue(SHAPE); + if (shape == TripleShape.BOTTOM) { + return isTerrain(world.getBlockState(pos.below())) && world.getBlockState(pos.above()).is(this); + } else if (shape == TripleShape.TOP) { + return world.getBlockState(pos.below()).is(this); + } else { + return world.getBlockState(pos.below()).is(this) && world.getBlockState(pos.above()).is(this); + } + } + + @Override + public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { + return false; + } + + @Override + public boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state) { + return false; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/LucerniaSaplingBlock.java b/src/main/java/org/betterx/betterend/blocks/LucerniaSaplingBlock.java new file mode 100644 index 00000000..3a2163b5 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/LucerniaSaplingBlock.java @@ -0,0 +1,28 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.PottableFeatureSapling; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.features.trees.LucerniaFeature; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class LucerniaSaplingBlock extends PottableFeatureSapling { + public LucerniaSaplingBlock() { + super((state) -> EndFeatures.LUCERNIA.configuredFeature); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + return world.getBlockState(pos.below()).is(EndBlocks.RUTISCUS); + } + + @Override + public boolean canPlantOn(Block block) { + return block == EndBlocks.RUTISCUS; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/LumecornBlock.java b/src/main/java/org/betterx/betterend/blocks/LumecornBlock.java new file mode 100644 index 00000000..67ae4966 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/LumecornBlock.java @@ -0,0 +1,117 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlockNotFull; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.interfaces.tools.AddMineableAxe; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Collections; +import java.util.List; + +@SuppressWarnings("deprecation") +public class LumecornBlock extends BaseBlockNotFull implements RenderLayerProvider, AddMineableAxe { + public static final EnumProperty SHAPE = EnumProperty.create( + "shape", + EndBlockProperties.LumecornShape.class + ); + private static final VoxelShape SHAPE_BOTTOM = Block.box(6, 0, 6, 10, 16, 10); + private static final VoxelShape SHAPE_TOP = Block.box(6, 0, 6, 10, 8, 10); + + public LumecornBlock() { + super(FabricBlockSettings.of(Material.WOOD) + .hardness(0.5F) + .luminance(state -> state.getValue(SHAPE).getLight())); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(SHAPE); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return state.getValue(SHAPE) == EndBlockProperties.LumecornShape.LIGHT_TOP ? SHAPE_TOP : SHAPE_BOTTOM; + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + EndBlockProperties.LumecornShape shape = state.getValue(SHAPE); + if (shape == EndBlockProperties.LumecornShape.BOTTOM_BIG || shape == EndBlockProperties.LumecornShape.BOTTOM_SMALL) { + return world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES); + } else if (shape == EndBlockProperties.LumecornShape.LIGHT_TOP) { + return world.getBlockState(pos.below()).is(this); + } else { + return world.getBlockState(pos.below()).is(this) && world.getBlockState(pos.above()).is(this); + } + } + + @Override + public BlockState updateShape( + BlockState state, + Direction facing, + BlockState neighborState, + LevelAccessor world, + BlockPos pos, + BlockPos neighborPos + ) { + if (!canSurvive(state, world, pos)) { + return Blocks.AIR.defaultBlockState(); + } else { + return state; + } + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + EndBlockProperties.LumecornShape shape = state.getValue(SHAPE); + if (shape == EndBlockProperties.LumecornShape.BOTTOM_BIG || shape == EndBlockProperties.LumecornShape.BOTTOM_SMALL || shape == EndBlockProperties.LumecornShape.MIDDLE) { + return Collections.singletonList(new ItemStack( + EndBlocks.LUMECORN_SEED, + MHelper.randRange(1, 2, MHelper.RANDOM_SOURCE) + )); + } + return MHelper.RANDOM.nextBoolean() + ? Collections.singletonList(new ItemStack(EndItems.LUMECORN_ROD)) + : Collections + .emptyList(); + } + + @Override + @Environment(EnvType.CLIENT) + public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) { + EndBlockProperties.LumecornShape shape = state.getValue(SHAPE); + if (shape == EndBlockProperties.LumecornShape.BOTTOM_BIG || shape == EndBlockProperties.LumecornShape.BOTTOM_SMALL || shape == EndBlockProperties.LumecornShape.MIDDLE) { + return new ItemStack(EndBlocks.LUMECORN_SEED); + } + return new ItemStack(EndItems.LUMECORN_ROD); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/LumecornSeedBlock.java b/src/main/java/org/betterx/betterend/blocks/LumecornSeedBlock.java new file mode 100644 index 00000000..388cc259 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/LumecornSeedBlock.java @@ -0,0 +1,39 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +import java.util.Optional; + +public class LumecornSeedBlock extends EndPlantWithAgeBlock { + + public LumecornSeedBlock() { + super(basePlantSettings().offsetType(OffsetType.NONE)); + } + + @Override + public void growAdult(WorldGenLevel world, RandomSource random, BlockPos pos) { + ((Feature) (EndFeatures.LUMECORN.getFeature())).place(new FeaturePlaceContext<>( + Optional.empty(), + world, + null, + random, + pos, + null + )); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.END_MOSS); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/MengerSpongeBlock.java b/src/main/java/org/betterx/betterend/blocks/MengerSpongeBlock.java new file mode 100644 index 00000000..89cff017 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/MengerSpongeBlock.java @@ -0,0 +1,141 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlockNotFull; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.tags.FluidTags; +import net.minecraft.util.Tuple; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.BucketPickup; +import net.minecraft.world.level.block.LiquidBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Lists; + +import java.util.Queue; + +@SuppressWarnings("deprecation") +public class MengerSpongeBlock extends BaseBlockNotFull implements RenderLayerProvider { + private static final VoxelShape SHAPE; + + public MengerSpongeBlock() { + super(FabricBlockSettings.copyOf(Blocks.SPONGE).noOcclusion()); + } + + @Override + public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { + if (absorbWater(world, pos)) { + world.setBlockAndUpdate(pos, EndBlocks.MENGER_SPONGE_WET.defaultBlockState()); + } + } + + @Override + public BlockState updateShape( + BlockState state, + Direction facing, + BlockState neighborState, + LevelAccessor world, + BlockPos pos, + BlockPos neighborPos + ) { + if (absorbWater(world, pos)) { + return EndBlocks.MENGER_SPONGE_WET.defaultBlockState(); + } + return state; + } + + private boolean absorbWater(LevelAccessor world, BlockPos pos) { + Queue> queue = Lists.newLinkedList(); + queue.add(new Tuple<>(pos, 0)); + int i = 0; + + while (!queue.isEmpty()) { + Tuple pair = queue.poll(); + BlockPos blockPos = pair.getA(); + int j = pair.getB(); + + for (Direction direction : Direction.values()) { + BlockPos blockPos2 = blockPos.relative(direction); + BlockState blockState = world.getBlockState(blockPos2); + FluidState fluidState = world.getFluidState(blockPos2); + Material material = blockState.getMaterial(); + if (fluidState.is(FluidTags.WATER)) { + if (blockState.getBlock() instanceof BucketPickup && !((BucketPickup) blockState.getBlock()).pickupBlock( + world, + blockPos2, + blockState + ) + .isEmpty()) { + ++i; + if (j < 6) { + queue.add(new Tuple<>(blockPos2, j + 1)); + } + } else if (blockState.getBlock() instanceof LiquidBlock) { + world.setBlock(blockPos2, Blocks.AIR.defaultBlockState(), 3); + ++i; + if (j < 6) { + queue.add(new Tuple<>(blockPos2, j + 1)); + } + } else if (material == Material.WATER_PLANT || material == Material.REPLACEABLE_WATER_PLANT) { + BlockEntity blockEntity = blockState.hasBlockEntity() ? world.getBlockEntity(blockPos2) : null; + dropResources(blockState, world, blockPos2, blockEntity); + world.setBlock(blockPos2, Blocks.AIR.defaultBlockState(), 3); + ++i; + if (j < 6) { + queue.add(new Tuple<>(blockPos2, j + 1)); + } + } + } + } + + if (i > 64) { + break; + } + } + + return i > 0; + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + @Override + public VoxelShape getShape( + BlockState blockState, + BlockGetter blockGetter, + BlockPos blockPos, + CollisionContext collisionContext + ) { + return SHAPE; + } + + static { + SHAPE = Shapes.or( + Shapes.or(box(0, 0, 0, 16, 6, 6), box(0, 0, 10, 16, 6, 16), + Shapes.or(box(0, 10, 0, 16, 16, 6), box(0, 10, 10, 16, 16, 16)), + + Shapes.or(box(0, 0, 0, 6, 6, 16), box(10, 0, 0, 16, 6, 16)), + Shapes.or(box(0, 10, 0, 6, 16, 16), box(10, 10, 0, 16, 16, 16)), + + Shapes.or(box(0, 0, 0, 6, 16, 6), box(10, 0, 0, 16, 16, 6)), + Shapes.or(box(0, 0, 10, 6, 16, 16), box(10, 0, 10, 16, 16, 16)) + )); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/MengerSpongeWetBlock.java b/src/main/java/org/betterx/betterend/blocks/MengerSpongeWetBlock.java new file mode 100644 index 00000000..b3f8ae4d --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/MengerSpongeWetBlock.java @@ -0,0 +1,130 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlockNotFull; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.GameRules; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +@SuppressWarnings("deprecation") +public class MengerSpongeWetBlock extends BaseBlockNotFull implements RenderLayerProvider { + public MengerSpongeWetBlock() { + super(FabricBlockSettings.copyOf(Blocks.WET_SPONGE).noOcclusion()); + } + + @Override + public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { + if (world.dimensionType().ultraWarm()) { + world.setBlock(pos, EndBlocks.MENGER_SPONGE.defaultBlockState(), 3); + world.levelEvent(2009, pos, 0); + world.playSound( + null, + pos, + SoundEvents.FIRE_EXTINGUISH, + SoundSource.BLOCKS, + 1.0F, + (1.0F + world.getRandom().nextFloat() * 0.2F) * 0.7F + ); + } + } + + @Override + @Environment(EnvType.CLIENT) + public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) { + Direction direction = Direction.getRandom(random); + if (direction != Direction.UP) { + BlockPos blockPos = pos.relative(direction); + BlockState blockState = world.getBlockState(blockPos); + if (!state.canOcclude() || !blockState.isFaceSturdy(world, blockPos, direction.getOpposite())) { + double x = pos.getX(); + double y = pos.getY(); + double z = pos.getZ(); + if (direction == Direction.DOWN) { + y -= 0.05; + x += random.nextDouble(); + z += random.nextDouble(); + } else { + y += random.nextDouble() * 0.8; + if (direction.getAxis() == Direction.Axis.X) { + z += random.nextDouble(); + if (direction == Direction.EAST) { + ++x; + } else { + x += 0.05; + } + } else { + x += random.nextDouble(); + if (direction == Direction.SOUTH) { + ++z; + } else { + z += 0.05; + } + } + } + + world.addParticle(ParticleTypes.DRIPPING_WATER, x, y, z, 0, 0, 0); + } + } + } + + @Override + public void playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) { + BlocksHelper.setWithUpdate(world, pos, Blocks.AIR); + if (!world.isClientSide()) { + world.levelEvent(2001, pos, getId(state)); + } + if (world.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS) && (player == null || !player.isCreative())) { + ItemEntity drop = new ItemEntity( + world, + pos.getX() + 0.5, + pos.getY() + 0.5, + pos.getZ() + 0.5, + new ItemStack(this) + ); + world.addFreshEntity(drop); + } + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + @Override + public FluidState getFluidState(BlockState state) { + return Fluids.WATER.getSource(false); + } + + @Override + public VoxelShape getShape( + BlockState blockState, + BlockGetter blockGetter, + BlockPos blockPos, + CollisionContext collisionContext + ) { + return EndBlocks.MENGER_SPONGE.getShape(blockState, blockGetter, blockPos, collisionContext); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/MissingTileBlock.java b/src/main/java/org/betterx/betterend/blocks/MissingTileBlock.java new file mode 100644 index 00000000..bf543766 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/MissingTileBlock.java @@ -0,0 +1,13 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; + +import net.minecraft.world.level.block.Blocks; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class MissingTileBlock extends BaseBlock { + public MissingTileBlock() { + super(FabricBlockSettings.copyOf(Blocks.END_STONE)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/MossyDragonBoneBlock.java b/src/main/java/org/betterx/betterend/blocks/MossyDragonBoneBlock.java new file mode 100644 index 00000000..25cc041c --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/MossyDragonBoneBlock.java @@ -0,0 +1,69 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseRotatedPillarBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SnowLayerBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.lighting.LayerLightEngine; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Collections; +import java.util.List; + +@SuppressWarnings("deprecation") +public class MossyDragonBoneBlock extends BaseRotatedPillarBlock { + public MossyDragonBoneBlock() { + super(FabricBlockSettings.copyOf(Blocks.BONE_BLOCK).hardness(0.5F).randomTicks()); + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + ItemStack tool = builder.getParameter(LootContextParams.TOOL); + if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) { + return Collections.singletonList(new ItemStack(this)); + } + return Collections.singletonList(new ItemStack(EndBlocks.DRAGON_BONE_BLOCK)); + } + + @Override + public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + if (random.nextInt(16) == 0 && !canSurvive(state, world, pos)) { + world.setBlockAndUpdate(pos, Blocks.BONE_BLOCK.defaultBlockState().setValue(AXIS, state.getValue(AXIS))); + } + } + + @Override + public boolean canSurvive(BlockState state, LevelReader worldView, BlockPos pos) { + BlockPos blockPos = pos.above(); + BlockState blockState = worldView.getBlockState(blockPos); + if (blockState.is(Blocks.SNOW) && blockState.getValue(SnowLayerBlock.LAYERS) == 1) { + return true; + } else if (blockState.getFluidState().getAmount() == 8) { + return false; + } else { + int i = LayerLightEngine.getLightBlockInto( + worldView, + state, + pos, + blockState, + blockPos, + Direction.UP, + blockState.getLightBlock(worldView, blockPos) + ); + return i < 5; + } + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/MossyGlowshroomCapBlock.java b/src/main/java/org/betterx/betterend/blocks/MossyGlowshroomCapBlock.java new file mode 100644 index 00000000..db6d5c15 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/MossyGlowshroomCapBlock.java @@ -0,0 +1,47 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.interfaces.TagProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.MineableTags; + +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.Material; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.List; + +public class MossyGlowshroomCapBlock extends BaseBlock implements TagProvider { + public static final BooleanProperty TRANSITION = EndBlockProperties.TRANSITION; + + public MossyGlowshroomCapBlock() { + super(FabricBlockSettings.of(Material.WOOD).sound(SoundType.WOOD)); + this.registerDefaultState(this.stateDefinition.any().setValue(TRANSITION, false)); + } + + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + return this.defaultBlockState() + .setValue( + TRANSITION, + EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(ctx.getLevel() + .getBlockState(ctx.getClickedPos().below())) + ); + } + + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(TRANSITION); + } + + @Override + public void addTags(List> blockTags, List> itemTags) { + blockTags.add(MineableTags.AXE); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/MossyGlowshroomSaplingBlock.java b/src/main/java/org/betterx/betterend/blocks/MossyGlowshroomSaplingBlock.java new file mode 100644 index 00000000..d8170eb6 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/MossyGlowshroomSaplingBlock.java @@ -0,0 +1,29 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.PottableFeatureSapling; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.features.trees.MossyGlowshroomFeature; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class MossyGlowshroomSaplingBlock extends PottableFeatureSapling { + public MossyGlowshroomSaplingBlock() { + super(7, (state) -> EndFeatures.MOSSY_GLOWSHROOM.configuredFeature); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + return world.getBlockState(pos.below()).is(EndBlocks.END_MOSS) || world.getBlockState(pos.below()) + .is(EndBlocks.END_MYCELIUM); + } + + @Override + public boolean canPlantOn(Block block) { + return block == EndBlocks.END_MOSS || block == EndBlocks.END_MYCELIUM; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/MossyObsidian.java b/src/main/java/org/betterx/betterend/blocks/MossyObsidian.java new file mode 100644 index 00000000..5cdb2b2e --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/MossyObsidian.java @@ -0,0 +1,68 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SnowLayerBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.lighting.LayerLightEngine; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Collections; +import java.util.List; + +public class MossyObsidian extends BaseBlock { + public MossyObsidian() { + super(FabricBlockSettings.copyOf(Blocks.OBSIDIAN).hardness(3).randomTicks()); + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + ItemStack tool = builder.getParameter(LootContextParams.TOOL); + if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) { + return Collections.singletonList(new ItemStack(this)); + } + return Collections.singletonList(new ItemStack(Blocks.OBSIDIAN)); + } + + @Override + @SuppressWarnings("deprecation") + public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + if (random.nextInt(16) == 0 && !canSurvive(state, world, pos)) { + world.setBlockAndUpdate(pos, Blocks.OBSIDIAN.defaultBlockState()); + } + } + + @SuppressWarnings("deprecation") + public boolean canSurvive(BlockState state, LevelReader worldView, BlockPos pos) { + BlockPos blockPos = pos.above(); + BlockState blockState = worldView.getBlockState(blockPos); + if (blockState.is(Blocks.SNOW) && blockState.getValue(SnowLayerBlock.LAYERS) == 1) { + return true; + } else if (blockState.getFluidState().getAmount() == 8) { + return false; + } else { + int i = LayerLightEngine.getLightBlockInto( + worldView, + state, + pos, + blockState, + blockPos, + Direction.UP, + blockState.getLightBlock(worldView, blockPos) + ); + return i < 5; + } + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/MurkweedBlock.java b/src/main/java/org/betterx/betterend/blocks/MurkweedBlock.java new file mode 100644 index 00000000..6d693af2 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/MurkweedBlock.java @@ -0,0 +1,50 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.EndPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.util.RandomSource; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.pathfinder.PathComputationType; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class MurkweedBlock extends EndPlantBlock { + @Override + @Environment(EnvType.CLIENT) + public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) { + double x = pos.getX() + random.nextDouble(); + double y = pos.getY() + random.nextDouble() * 0.5 + 0.5; + double z = pos.getZ() + random.nextDouble(); + double v = random.nextDouble() * 0.1; + world.addParticle(ParticleTypes.ENTITY_EFFECT, x, y, z, v, v, v); + } + + @Override + @SuppressWarnings("deprecation") + public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (entity instanceof LivingEntity && !((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS)) { + ((LivingEntity) entity).addEffect(new MobEffectInstance(MobEffects.BLINDNESS, 50)); + } + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.SHADOW_GRASS); + } + + @Override + @SuppressWarnings("deprecation") + public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { + return false; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/NeedlegrassBlock.java b/src/main/java/org/betterx/betterend/blocks/NeedlegrassBlock.java new file mode 100644 index 00000000..d7165a6f --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/NeedlegrassBlock.java @@ -0,0 +1,59 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.items.tool.BaseShearsItem; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.basis.EndPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; + +import com.google.common.collect.Lists; + +import java.util.List; + +public class NeedlegrassBlock extends EndPlantBlock { + @Override + @SuppressWarnings("deprecation") + public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (entity instanceof LivingEntity) { + entity.hurt(DamageSource.CACTUS, 0.1F); + } + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + ItemStack tool = builder.getParameter(LootContextParams.TOOL); + if (tool != null && BaseShearsItem.isShear(tool) || EnchantmentHelper.getItemEnchantmentLevel( + Enchantments.SILK_TOUCH, + tool + ) > 0) { + return Lists.newArrayList(new ItemStack(this)); + } else { + return Lists.newArrayList(new ItemStack(Items.STICK, MHelper.randRange(0, 2, MHelper.RANDOM_SOURCE))); + } + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.SHADOW_GRASS); + } + + @Override + @SuppressWarnings("deprecation") + public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { + return false; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/NeonCactusBlock.java b/src/main/java/org/betterx/betterend/blocks/NeonCactusBlock.java new file mode 100644 index 00000000..2958e556 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/NeonCactusBlock.java @@ -0,0 +1,13 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.LitPillarBlock; + +import net.minecraft.world.level.block.Blocks; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class NeonCactusBlock extends LitPillarBlock { + public NeonCactusBlock() { + super(FabricBlockSettings.copyOf(Blocks.CACTUS).luminance(15)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/NeonCactusPlantBlock.java b/src/main/java/org/betterx/betterend/blocks/NeonCactusPlantBlock.java new file mode 100644 index 00000000..0fe46eb4 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/NeonCactusPlantBlock.java @@ -0,0 +1,438 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlockNotFull; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.EndBlockProperties.CactusBottom; +import org.betterx.betterend.interfaces.PottablePlant; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.*; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.util.EnumMap; +import java.util.List; + +@SuppressWarnings("deprecation") +public class NeonCactusPlantBlock extends BaseBlockNotFull implements SimpleWaterloggedBlock, RenderLayerProvider, PottablePlant { + public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; + public static final EnumProperty CACTUS_BOTTOM = EndBlockProperties.CACTUS_BOTTOM; + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + public static final DirectionProperty FACING = BlockStateProperties.FACING; + + private static final EnumMap BIG_SHAPES_OPEN = Maps.newEnumMap(Direction.class); + private static final EnumMap MEDIUM_SHAPES_OPEN = Maps.newEnumMap(Direction.class); + private static final EnumMap SMALL_SHAPES_OPEN = Maps.newEnumMap(Direction.class); + private static final EnumMap BIG_SHAPES = Maps.newEnumMap(Axis.class); + private static final EnumMap MEDIUM_SHAPES = Maps.newEnumMap(Axis.class); + private static final EnumMap SMALL_SHAPES = Maps.newEnumMap(Axis.class); + private static final int MAX_LENGTH = 12; + + public NeonCactusPlantBlock() { + super(FabricBlockSettings.copyOf(Blocks.CACTUS).luminance(15).randomTicks()); + registerDefaultState(defaultBlockState().setValue(WATERLOGGED, false) + .setValue(FACING, Direction.UP) + .setValue(SHAPE, TripleShape.TOP)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(SHAPE, CACTUS_BOTTOM, WATERLOGGED, FACING); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + LevelAccessor world = ctx.getLevel(); + BlockPos pos = ctx.getClickedPos(); + Direction dir = ctx.getClickedFace(); + BlockState down = world.getBlockState(pos.relative(dir.getOpposite())); + BlockState state = this.defaultBlockState() + .setValue(WATERLOGGED, world.getFluidState(pos).getType() == Fluids.WATER) + .setValue(FACING, ctx.getClickedFace()); + if (down.is(Blocks.END_STONE) || down.is(EndBlocks.ENDSTONE_DUST)) { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.SAND); + } else if (down.is(EndBlocks.END_MOSS)) { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.MOSS); + } else { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.EMPTY); + } + return state; + } + + @Override + public BlockState rotate(BlockState state, Rotation rotation) { + return BlocksHelper.rotateHorizontal(state, rotation, FACING); + } + + @Override + public BlockState mirror(BlockState state, Mirror mirror) { + return BlocksHelper.mirrorHorizontal(state, mirror, FACING); + } + + @Override + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); + } + + @Override + public BlockState updateShape( + BlockState state, + Direction direction, + BlockState newState, + LevelAccessor world, + BlockPos pos, + BlockPos posFrom + ) { + world.scheduleTick(pos, this, 2); + if (state.getValue(WATERLOGGED)) { + world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); + } + Direction dir = state.getValue(FACING); + BlockState downState = world.getBlockState(pos.relative(dir.getOpposite())); + if (downState.is(Blocks.END_STONE) || downState.is(EndBlocks.ENDSTONE_DUST)) { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.SAND); + } else if (downState.is(EndBlocks.END_MOSS)) { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.MOSS); + } else { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.EMPTY); + } + return state; + } + + @Override + public void tick(BlockState blockState, ServerLevel serverLevel, BlockPos blockPos, RandomSource random) { + if (!blockState.canSurvive(serverLevel, blockPos)) { + serverLevel.destroyBlock(blockPos, true, null, 1); + } + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + TripleShape shape = state.getValue(SHAPE); + Direction dir = state.getValue(FACING); + BlockState next = view.getBlockState(pos.relative(dir)); + if (next.is(this)) { + Axis axis = dir.getAxis(); + if (shape == TripleShape.BOTTOM) { + return BIG_SHAPES.get(axis); + } + return shape == TripleShape.MIDDLE ? MEDIUM_SHAPES.get(axis) : SMALL_SHAPES.get(axis); + } else { + if (shape == TripleShape.BOTTOM) { + return BIG_SHAPES_OPEN.get(dir); + } + return shape == TripleShape.MIDDLE ? MEDIUM_SHAPES_OPEN.get(dir) : SMALL_SHAPES_OPEN.get(dir); + } + } + + @Override + public boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { + Direction dir = state.getValue(FACING); + BlockPos supportPos = pos.relative(dir.getOpposite()); + BlockState support = level.getBlockState(supportPos); + return support.is(this) || support.isFaceSturdy(level, supportPos, dir); + } + + @Override + public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + if (!this.canSurvive(state, world, pos) || random.nextInt(8) > 0) { + return; + } + Direction dir = state.getValue(FACING); + if (!world.isEmptyBlock(pos.relative(dir))) { + return; + } + int length = getLength(state, world, pos, MAX_LENGTH); + if (length < 0 || length > MAX_LENGTH - 1) { + return; + } + if (dir.getAxis().isHorizontal()) { + int horizontal = getHorizontal(state, world, pos, 2); + if (horizontal > random.nextInt(2)) { + dir = Direction.UP; + if (!world.getBlockState(pos.above()).isAir()) { + return; + } + } + } else if (length > 1 && world.getBlockState(pos.relative(dir.getOpposite())).is(this)) { + Direction side = getSideDirection(world, pos, state, dir, random); + BlockPos sidePos = pos.relative(side); + if (world.isEmptyBlock(sidePos)) { + BlockState placement = state.setValue(SHAPE, TripleShape.TOP) + .setValue(CACTUS_BOTTOM, CactusBottom.EMPTY) + .setValue(WATERLOGGED, false) + .setValue(FACING, side); + BlocksHelper.setWithoutUpdate(world, sidePos, placement); + } + } + BlockState placement = state.setValue(SHAPE, TripleShape.TOP) + .setValue(CACTUS_BOTTOM, CactusBottom.EMPTY) + .setValue(WATERLOGGED, false) + .setValue(FACING, dir); + BlocksHelper.setWithoutUpdate(world, pos.relative(dir), placement); + mutateStem(placement, world, pos, MAX_LENGTH); + } + + public void growPlant(WorldGenLevel world, BlockPos pos, RandomSource random) { + growPlant(world, pos, random, MHelper.randRange(MAX_LENGTH >> 1, MAX_LENGTH, random)); + } + + public void growPlant(WorldGenLevel world, BlockPos pos, RandomSource random, int iterations) { + BlockState state = defaultBlockState(); + BlockState downState = world.getBlockState(pos.below()); + if (downState.is(Blocks.END_STONE) || downState.is(EndBlocks.ENDSTONE_DUST)) { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.SAND); + } else if (downState.is(EndBlocks.END_MOSS)) { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.MOSS); + } else { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.EMPTY); + } + BlocksHelper.setWithoutUpdate(world, pos, state); + List ends = Lists.newArrayList(pos.mutable()); + for (int i = 0; i < iterations; i++) { + int count = ends.size(); + for (int n = 0; n < count; n++) { + if (!growIteration(world, ends.get(n), random, ends, i)) { + ends.remove(n); + count--; + n--; + } + } + } + } + + private boolean growIteration( + WorldGenLevel world, + MutableBlockPos pos, + RandomSource random, + List ends, + int length + ) { + BlockState state = world.getBlockState(pos); + if (!state.is(this)) { + return false; + } + Direction dir = state.getValue(FACING); + if (!world.isEmptyBlock(pos.relative(dir))) { + return false; + } + if (dir.getAxis().isHorizontal()) { + int horizontal = getHorizontal(state, world, pos, 2); + if (horizontal > random.nextInt(2)) { + dir = Direction.UP; + if (!world.getBlockState(pos.above()).isAir()) { + return false; + } + } + } else if (length > 1 && world.getBlockState(pos.below()).is(this)) { + Direction side = getSideDirection(world, pos, state, dir, random); + BlockPos sidePos = pos.relative(side); + if (world.isEmptyBlock(sidePos)) { + BlockState placement = state.setValue(SHAPE, TripleShape.TOP) + .setValue(CACTUS_BOTTOM, CactusBottom.EMPTY) + .setValue(WATERLOGGED, false) + .setValue(FACING, side); + BlocksHelper.setWithoutUpdate(world, sidePos, placement); + ends.add(sidePos.mutable()); + } + } + BlockState placement = state.setValue(SHAPE, TripleShape.TOP) + .setValue(CACTUS_BOTTOM, CactusBottom.EMPTY) + .setValue(WATERLOGGED, false) + .setValue(FACING, dir); + BlocksHelper.setWithoutUpdate(world, pos.relative(dir), placement); + mutateStem(placement, world, pos, MAX_LENGTH); + pos.move(dir); + return true; + } + + private Direction getSideDirection( + WorldGenLevel world, + BlockPos pos, + BlockState iterState, + Direction dir, + RandomSource random + ) { + MutableBlockPos iterPos = pos.mutable(); + Direction startDir = dir; + Direction lastDir = null; + while (iterState.is(this) && startDir.getAxis().isVertical()) { + startDir = iterState.getValue(FACING); + if (lastDir == null) { + for (Direction side : BlocksHelper.HORIZONTAL) { + BlockState sideState = world.getBlockState(iterPos.relative(side)); + if (sideState.is(this)) { + Direction sideDir = sideState.getValue(FACING); + if (sideDir != side) { + continue; + } + lastDir = sideDir; + } + } + } + iterPos.move(dir); + iterState = world.getBlockState(iterPos); + } + + Direction side = lastDir == null ? BlocksHelper.randomHorizontal(random) : lastDir.getClockWise(); + if (side.getOpposite() == startDir) { + side = side.getOpposite(); + } + return side; + } + + @Override + public boolean isPathfindable( + BlockState blockState, + BlockGetter blockGetter, + BlockPos blockPos, + PathComputationType pathComputationType + ) { + return false; + } + + @Override + public void entityInside(BlockState blockState, Level level, BlockPos blockPos, Entity entity) { + entity.hurt(DamageSource.CACTUS, 1.0F); + } + + private int getLength(BlockState state, ServerLevel world, BlockPos pos, int max) { + int length = 0; + Direction dir = state.getValue(FACING).getOpposite(); + MutableBlockPos mut = new MutableBlockPos().set(pos); + for (int i = 0; i < max; i++) { + mut.move(dir); + state = world.getBlockState(mut); + if (!state.is(this)) { + if (!state.is(CommonBlockTags.END_STONES)) { + length = -1; + } + break; + } + dir = state.getValue(FACING).getOpposite(); + length++; + } + return length; + } + + private int getHorizontal(BlockState state, WorldGenLevel world, BlockPos pos, int max) { + int count = 0; + Direction dir = state.getValue(FACING).getOpposite(); + MutableBlockPos mut = new MutableBlockPos().set(pos); + for (int i = 0; i < max; i++) { + mut.move(dir); + state = world.getBlockState(mut); + if (!state.is(this)) { + break; + } + dir = state.getValue(FACING).getOpposite(); + if (dir.getStepY() != 0) { + break; + } + count++; + } + return count; + } + + private void mutateStem(BlockState state, WorldGenLevel world, BlockPos pos, int max) { + Direction dir = state.getValue(FACING).getOpposite(); + MutableBlockPos mut = new MutableBlockPos().set(pos); + for (int i = 0; i < max; i++) { + mut.move(dir); + state = world.getBlockState(mut); + if (!state.is(this)) { + return; + } + int size = (i + 2) * 3 / max; + int src = state.getValue(SHAPE).getIndex(); + dir = state.getValue(FACING).getOpposite(); + if (src < size) { + TripleShape shape = TripleShape.fromIndex(size); + BlocksHelper.setWithoutUpdate(world, mut, state.setValue(SHAPE, shape)); + } + } + } + + static { + BIG_SHAPES.put(Axis.X, Block.box(0, 2, 2, 16, 14, 14)); + BIG_SHAPES.put(Axis.Y, Block.box(2, 0, 2, 14, 16, 14)); + BIG_SHAPES.put(Axis.Z, Block.box(2, 2, 0, 14, 14, 16)); + + MEDIUM_SHAPES.put(Axis.X, Block.box(0, 3, 3, 16, 13, 13)); + MEDIUM_SHAPES.put(Axis.Y, Block.box(3, 0, 3, 13, 16, 13)); + MEDIUM_SHAPES.put(Axis.Z, Block.box(3, 3, 0, 13, 13, 16)); + + SMALL_SHAPES.put(Axis.X, Block.box(0, 4, 4, 16, 12, 12)); + SMALL_SHAPES.put(Axis.Y, Block.box(4, 0, 4, 12, 16, 12)); + SMALL_SHAPES.put(Axis.Z, Block.box(4, 4, 0, 12, 12, 16)); + + BIG_SHAPES_OPEN.put(Direction.UP, Block.box(2, 0, 2, 14, 14, 14)); + BIG_SHAPES_OPEN.put(Direction.DOWN, Block.box(2, 2, 2, 14, 16, 14)); + BIG_SHAPES_OPEN.put(Direction.NORTH, Block.box(2, 2, 2, 14, 14, 16)); + BIG_SHAPES_OPEN.put(Direction.SOUTH, Block.box(2, 2, 0, 14, 14, 14)); + BIG_SHAPES_OPEN.put(Direction.WEST, Block.box(2, 2, 2, 16, 14, 14)); + BIG_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 2, 2, 14, 14, 14)); + + MEDIUM_SHAPES_OPEN.put(Direction.UP, Block.box(3, 0, 3, 13, 13, 13)); + MEDIUM_SHAPES_OPEN.put(Direction.DOWN, Block.box(3, 3, 3, 13, 16, 13)); + MEDIUM_SHAPES_OPEN.put(Direction.NORTH, Block.box(3, 3, 3, 13, 13, 16)); + MEDIUM_SHAPES_OPEN.put(Direction.SOUTH, Block.box(3, 3, 0, 13, 13, 13)); + MEDIUM_SHAPES_OPEN.put(Direction.WEST, Block.box(3, 3, 3, 16, 13, 13)); + MEDIUM_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 3, 3, 13, 13, 13)); + + SMALL_SHAPES_OPEN.put(Direction.UP, Block.box(4, 0, 4, 12, 12, 12)); + SMALL_SHAPES_OPEN.put(Direction.DOWN, Block.box(4, 4, 4, 12, 16, 12)); + SMALL_SHAPES_OPEN.put(Direction.NORTH, Block.box(4, 4, 4, 12, 12, 16)); + SMALL_SHAPES_OPEN.put(Direction.SOUTH, Block.box(4, 4, 0, 12, 12, 12)); + SMALL_SHAPES_OPEN.put(Direction.WEST, Block.box(4, 4, 4, 16, 12, 12)); + SMALL_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 4, 4, 12, 12, 12)); + } + + @Override + public boolean canPlantOn(Block block) { + return true; + } + + @Override + @Environment(EnvType.CLIENT) + public String getPottedState() { + return "bottom=moss,shape=top,facing=up"; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/PallidiumBlock.java b/src/main/java/org/betterx/betterend/blocks/PallidiumBlock.java new file mode 100644 index 00000000..37f5527b --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/PallidiumBlock.java @@ -0,0 +1,78 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.blocks.basis.EndTerrainBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.MaterialColor; +import net.minecraft.world.phys.BlockHitResult; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import java.util.Map; + +public class PallidiumBlock extends EndTerrainBlock { + private final Block nextLevel; + + public PallidiumBlock(String thickness, Block nextLevel) { + super(MaterialColor.COLOR_LIGHT_GRAY); + this.nextLevel = nextLevel; + } + + public boolean canBePotted() { + return this == EndBlocks.PALLIDIUM_FULL; + } + + @Override + public Block getBaseBlock() { + return EndBlocks.UMBRALITH.stone; + } + + @Override + public InteractionResult use( + BlockState state, + Level level, + BlockPos pos, + Player player, + InteractionHand hand, + BlockHitResult hit + ) { + if (nextLevel == null) { + return InteractionResult.PASS; + } else if (level.isClientSide) { + return InteractionResult.PASS; + } + + ItemStack itemStack = player.getItemInHand(hand); + if (itemStack.is(Items.BONE_MEAL)) { + BlocksHelper.setWithUpdate(level, pos, nextLevel); + if (!player.isCreative()) { + itemStack.shrink(1); + } + return InteractionResult.SUCCESS; + } + return InteractionResult.PASS; + } + + @Override + @Environment(EnvType.CLIENT) + public UnbakedModel getModelVariant( + ResourceLocation stateId, + BlockState blockState, + Map modelCache + ) { + return this.getBlockModel(stateId, blockState); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/PedestalVanilla.java b/src/main/java/org/betterx/betterend/blocks/PedestalVanilla.java new file mode 100644 index 00000000..d2c33f31 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/PedestalVanilla.java @@ -0,0 +1,34 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.PedestalBlock; + +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.Block; + +import java.util.HashMap; +import java.util.Map; + +public class PedestalVanilla extends PedestalBlock { + + public PedestalVanilla(Block parent) { + super(parent); + } + + @Override + protected Map createTexturesMap() { + ResourceLocation blockId = Registry.BLOCK.getKey(parent); + String name = blockId.getPath().replace("_block", ""); + return new HashMap() { + private static final long serialVersionUID = 1L; + + { + put("%mod%", blockId.getNamespace()); + put("%top%", "polished_" + name); + put("%base%", "polished_" + name); + put("%pillar%", name + "_pillar"); + put("%bottom%", "polished_" + name); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/PondAnemoneBlock.java b/src/main/java/org/betterx/betterend/blocks/PondAnemoneBlock.java new file mode 100644 index 00000000..9e8d9f56 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/PondAnemoneBlock.java @@ -0,0 +1,51 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.interfaces.tools.AddMineableShears; +import org.betterx.betterend.blocks.basis.EndUnderwaterPlantBlock; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class PondAnemoneBlock extends EndUnderwaterPlantBlock implements AddMineableShears { + private static final VoxelShape SHAPE = Block.box(2, 0, 2, 14, 14, 14); + + public PondAnemoneBlock() { + super(baseUnderwaterPlantSettings(13).sound(SoundType.CORAL_BLOCK) + .offsetType(OffsetType.NONE) + ); + } + + @Environment(EnvType.CLIENT) + public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) { + double x = pos.getX() + random.nextDouble(); + double y = pos.getY() + random.nextDouble() * 0.5F + 0.5F; + double z = pos.getZ() + random.nextDouble(); + world.addParticle(ParticleTypes.BUBBLE, x, y, z, 0.0D, 0.0D, 0.0D); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return SHAPE; + } + + @Override + public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { + return false; + } + + @Override + public boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state) { + return false; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/PythadendronSaplingBlock.java b/src/main/java/org/betterx/betterend/blocks/PythadendronSaplingBlock.java new file mode 100644 index 00000000..63759429 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/PythadendronSaplingBlock.java @@ -0,0 +1,28 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.PottableFeatureSapling; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.features.trees.PythadendronTreeFeature; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class PythadendronSaplingBlock extends PottableFeatureSapling { + public PythadendronSaplingBlock() { + super((state) -> EndFeatures.PYTHADENDRON_TREE.configuredFeature); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + return world.getBlockState(pos.below()).is(EndBlocks.CHORUS_NYLIUM); + } + + @Override + public boolean canPlantOn(Block block) { + return block == EndBlocks.CHORUS_NYLIUM; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/RespawnObeliskBlock.java b/src/main/java/org/betterx/betterend/blocks/RespawnObeliskBlock.java new file mode 100644 index 00000000..d2be7645 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/RespawnObeliskBlock.java @@ -0,0 +1,221 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.CustomColorProvider; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.particle.InfusionParticleType; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; +import org.betterx.ui.ColorUtil; + +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.item.ItemColor; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Lists; + +import java.util.List; +import org.jetbrains.annotations.Nullable; + +public class RespawnObeliskBlock extends BaseBlock implements CustomColorProvider, RenderLayerProvider { + private static final VoxelShape VOXEL_SHAPE_BOTTOM = Block.box(1, 0, 1, 15, 16, 15); + private static final VoxelShape VOXEL_SHAPE_MIDDLE_TOP = Block.box(2, 0, 2, 14, 16, 14); + + public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; + + public RespawnObeliskBlock() { + super(FabricBlockSettings.copyOf(Blocks.END_STONE).luminance((state) -> { + return (state.getValue(SHAPE) == TripleShape.BOTTOM) ? 0 : 15; + })); + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return (state.getValue(SHAPE) == TripleShape.BOTTOM) ? VOXEL_SHAPE_BOTTOM : VOXEL_SHAPE_MIDDLE_TOP; + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(SHAPE); + } + + @Override + @SuppressWarnings("deprecation") + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + for (int i = 0; i < 3; i++) { + if (!world.getBlockState(pos.above(i)).getMaterial().isReplaceable()) { + return false; + } + } + return true; + } + + @Override + public void setPlacedBy( + Level world, + BlockPos pos, + BlockState state, + @Nullable LivingEntity placer, + ItemStack itemStack + ) { + state = this.defaultBlockState(); + BlocksHelper.setWithUpdate(world, pos, state.setValue(SHAPE, TripleShape.BOTTOM)); + BlocksHelper.setWithUpdate(world, pos.above(), state.setValue(SHAPE, TripleShape.MIDDLE)); + BlocksHelper.setWithUpdate(world, pos.above(2), state.setValue(SHAPE, TripleShape.TOP)); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState updateShape( + BlockState state, + Direction facing, + BlockState neighborState, + LevelAccessor world, + BlockPos pos, + BlockPos neighborPos + ) { + TripleShape shape = state.getValue(SHAPE); + if (shape == TripleShape.BOTTOM) { + if (world.getBlockState(pos.above()).is(this)) { + return state; + } else { + return Blocks.AIR.defaultBlockState(); + } + } else if (shape == TripleShape.MIDDLE) { + if (world.getBlockState(pos.above()).is(this) && world.getBlockState(pos.below()).is(this)) { + return state; + } else { + return Blocks.AIR.defaultBlockState(); + } + } else { + if (world.getBlockState(pos.below()).is(this)) { + return state; + } else { + return Blocks.AIR.defaultBlockState(); + } + } + } + + @Override + public void playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) { + if (player.isCreative()) { + TripleShape shape = state.getValue(SHAPE); + if (shape == TripleShape.MIDDLE) { + BlocksHelper.setWithUpdate(world, pos.below(), Blocks.AIR); + } else if (shape == TripleShape.TOP) { + BlocksHelper.setWithUpdate(world, pos.below(2), Blocks.AIR); + } + } + super.playerWillDestroy(world, pos, state, player); + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + if (state.getValue(SHAPE) == TripleShape.BOTTOM) { + return Lists.newArrayList(new ItemStack(this)); + } else { + return Lists.newArrayList(); + } + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.TRANSLUCENT; + } + + @Override + public BlockColor getProvider() { + return ((CustomColorProvider) EndBlocks.AURORA_CRYSTAL).getProvider(); + } + + @Override + public ItemColor getItemProvider() { + return (stack, tintIndex) -> { + return ColorUtil.color(255, 255, 255); + }; + } + + @Override + @SuppressWarnings("deprecation") + public InteractionResult use( + BlockState state, + Level world, + BlockPos pos, + Player player, + InteractionHand hand, + BlockHitResult hit + ) { + ItemStack itemStack = player.getItemInHand(hand); + boolean canActivate = itemStack.getItem() == EndItems.AMBER_GEM && itemStack.getCount() > 5; + if (hand != InteractionHand.MAIN_HAND || !canActivate) { + if (!world.isClientSide && !(itemStack.getItem() instanceof BlockItem) && !player.isCreative()) { + ServerPlayer serverPlayerEntity = (ServerPlayer) player; + serverPlayerEntity.displayClientMessage( + Component.translatable("message.betterend.fail_spawn"), + true + ); + } + return InteractionResult.FAIL; + } else if (!world.isClientSide) { + ServerPlayer serverPlayerEntity = (ServerPlayer) player; + serverPlayerEntity.setRespawnPosition(world.dimension(), pos, 0.0F, false, false); + serverPlayerEntity.displayClientMessage(Component.translatable("message.betterend.set_spawn"), true); + double px = pos.getX() + 0.5; + double py = pos.getY() + 0.5; + double pz = pos.getZ() + 0.5; + InfusionParticleType particle = new InfusionParticleType(new ItemStack(EndItems.AMBER_GEM)); + if (world instanceof ServerLevel) { + double py1 = py; + double py2 = py - 0.2; + if (state.getValue(SHAPE) == TripleShape.BOTTOM) { + py1 += 1; + py2 += 2; + } else if (state.getValue(SHAPE) == TripleShape.MIDDLE) { + py1 += 0; + py2 += 1; + } else { + py1 -= 2; + } + ((ServerLevel) world).sendParticles(particle, px, py1, pz, 20, 0.14, 0.5, 0.14, 0.1); + ((ServerLevel) world).sendParticles(particle, px, py2, pz, 20, 0.14, 0.3, 0.14, 0.1); + } + world.playSound(null, px, py, py, SoundEvents.RESPAWN_ANCHOR_SET_SPAWN, SoundSource.BLOCKS, 1F, 1F); + if (!player.isCreative()) { + itemStack.shrink(6); + } + } + return player.isCreative() ? InteractionResult.PASS : InteractionResult.sidedSuccess(world.isClientSide); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/RunedFlavolite.java b/src/main/java/org/betterx/betterend/blocks/RunedFlavolite.java new file mode 100644 index 00000000..38df9229 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/RunedFlavolite.java @@ -0,0 +1,57 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.storage.loot.LootContext; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Lists; + +import java.util.List; + +public class RunedFlavolite extends BaseBlock { + public static final BooleanProperty ACTIVATED = BlockProperties.ACTIVE; + + public RunedFlavolite(boolean unbreakable) { + super(FabricBlockSettings.copyOf(EndBlocks.FLAVOLITE.polished) + .strength( + unbreakable ? -1 : 1, + unbreakable + ? Blocks.BEDROCK.getExplosionResistance() + : Blocks.OBSIDIAN.getExplosionResistance() + ) + .luminance(state -> { + return state.getValue(ACTIVATED) ? 8 : 0; + })); + this.registerDefaultState(stateDefinition.any().setValue(ACTIVATED, false)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(ACTIVATED); + } + + @Override + public boolean dropFromExplosion(Explosion explosion) { + return !BlocksHelper.isInvulnerableUnsafe(this.defaultBlockState()); + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + if (BlocksHelper.isInvulnerableUnsafe(this.defaultBlockState())) { + return Lists.newArrayList(); + } + return super.getDrops(state, builder); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/ShadowBerryBlock.java b/src/main/java/org/betterx/betterend/blocks/ShadowBerryBlock.java new file mode 100644 index 00000000..e808a0ca --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/ShadowBerryBlock.java @@ -0,0 +1,25 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.PottableCropBlock; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +public class ShadowBerryBlock extends PottableCropBlock { + private static final VoxelShape SHAPE = Block.box(1, 0, 1, 15, 8, 15); + + public ShadowBerryBlock() { + super(EndItems.SHADOW_BERRY_RAW, EndBlocks.SHADOW_GRASS); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return SHAPE; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/ShadowGrassBlock.java b/src/main/java/org/betterx/betterend/blocks/ShadowGrassBlock.java new file mode 100644 index 00000000..e76ac91d --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/ShadowGrassBlock.java @@ -0,0 +1,47 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.interfaces.TagProvider; +import org.betterx.betterend.blocks.basis.EndTerrainBlock; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.tags.TagKey; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import java.util.List; + +public class ShadowGrassBlock extends EndTerrainBlock implements TagProvider { + public ShadowGrassBlock() { + super(MaterialColor.COLOR_BLACK); + } + + @Environment(EnvType.CLIENT) + public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) { + super.animateTick(state, world, pos, random); + if (random.nextInt(32) == 0) { + world.addParticle( + EndParticles.BLACK_SPORE, + (double) pos.getX() + random.nextDouble(), + (double) pos.getY() + 1.1D, + (double) pos.getZ() + random.nextDouble(), + 0.0D, + 0.0D, + 0.0D + ); + } + } + + @Override + public void addTags(List> blockTags, List> itemTags) { + blockTags.add(CommonBlockTags.END_STONES); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/SilkMothHiveBlock.java b/src/main/java/org/betterx/betterend/blocks/SilkMothHiveBlock.java new file mode 100644 index 00000000..5b0ace24 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/SilkMothHiveBlock.java @@ -0,0 +1,133 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.items.tool.BaseShearsItem; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.entity.SilkMothEntity; +import org.betterx.betterend.registry.EndEntities; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.RandomSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class SilkMothHiveBlock extends BaseBlock { + public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + public static final IntegerProperty FULLNESS = EndBlockProperties.FULLNESS; + + public SilkMothHiveBlock() { + super(FabricBlockSettings.of(Material.WOOD) + .hardness(0.5F) + .resistance(0.1F) + .sound(SoundType.WOOL) + .noOcclusion() + .randomTicks()); + this.registerDefaultState(defaultBlockState().setValue(FULLNESS, 0)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(FACING, FULLNESS); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + Direction dir = ctx.getHorizontalDirection().getOpposite(); + return this.defaultBlockState().setValue(FACING, dir); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState rotate(BlockState state, Rotation rotation) { + return BlocksHelper.rotateHorizontal(state, rotation, FACING); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState mirror(BlockState state, Mirror mirror) { + return BlocksHelper.mirrorHorizontal(state, mirror, FACING); + } + + @Override + @SuppressWarnings("deprecation") + public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + Direction dir = state.getValue(FACING); + BlockPos spawn = pos.relative(dir); + if (!world.getBlockState(spawn).isAir()) { + return; + } + int count = world.getEntities(EndEntities.SILK_MOTH, new AABB(pos).inflate(16), (entity) -> { + return true; + }).size(); + if (count > 6) { + return; + } + SilkMothEntity moth = new SilkMothEntity(EndEntities.SILK_MOTH, world); + moth.moveTo(spawn.getX() + 0.5, spawn.getY() + 0.5, spawn.getZ() + 0.5, dir.toYRot(), 0); + moth.setDeltaMovement(new Vec3(dir.getStepX() * 0.4, 0, dir.getStepZ() * 0.4)); + moth.setHive(world, pos); + world.addFreshEntity(moth); + world.playSound(null, pos, SoundEvents.BEEHIVE_EXIT, SoundSource.BLOCKS, 1, 1); + } + + @Override + @SuppressWarnings("deprecation") + public InteractionResult use( + BlockState state, + Level world, + BlockPos pos, + Player player, + InteractionHand hand, + BlockHitResult hit + ) { + if (hand == InteractionHand.MAIN_HAND) { + ItemStack stack = player.getMainHandItem(); + if (BaseShearsItem.isShear(stack) && state.getValue(FULLNESS) == 3) { + BlocksHelper.setWithUpdate(world, pos, state.setValue(FULLNESS, 0)); + Direction dir = state.getValue(FACING); + double px = pos.getX() + dir.getStepX() + 0.5; + double py = pos.getY() + dir.getStepY() + 0.5; + double pz = pos.getZ() + dir.getStepZ() + 0.5; + ItemStack drop = new ItemStack(EndItems.SILK_FIBER, MHelper.randRange(8, 16, world.getRandom())); + ItemEntity entity = new ItemEntity(world, px, py, pz, drop); + world.addFreshEntity(entity); + if (world.getRandom().nextInt(4) == 0) { + drop = new ItemStack(EndItems.SILK_MOTH_MATRIX); + entity = new ItemEntity(world, px, py, pz, drop); + world.addFreshEntity(entity); + } + if (!player.isCreative()) { + stack.setDamageValue(stack.getDamageValue() + 1); + } + return InteractionResult.SUCCESS; + } + } + return InteractionResult.FAIL; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/SilkMothNestBlock.java b/src/main/java/org/betterx/betterend/blocks/SilkMothNestBlock.java new file mode 100644 index 00000000..76d79fa4 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/SilkMothNestBlock.java @@ -0,0 +1,198 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.items.tool.BaseShearsItem; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.entity.SilkMothEntity; +import org.betterx.betterend.registry.EndEntities; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.RandomSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Collections; +import java.util.List; + +public class SilkMothNestBlock extends BaseBlock implements RenderLayerProvider { + public static final BooleanProperty ACTIVE = EndBlockProperties.ACTIVE; + public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + public static final IntegerProperty FULLNESS = EndBlockProperties.FULLNESS; + private static final VoxelShape TOP = box(6, 0, 6, 10, 16, 10); + private static final VoxelShape BOTTOM = box(0, 0, 0, 16, 16, 16); + + public SilkMothNestBlock() { + super(FabricBlockSettings.of(Material.WOOL) + .hardness(0.5F) + .resistance(0.1F) + .sound(SoundType.WOOL) + .noOcclusion() + .randomTicks()); + this.registerDefaultState(defaultBlockState().setValue(ACTIVE, true).setValue(FULLNESS, 0)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(ACTIVE, FACING, FULLNESS); + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return state.getValue(ACTIVE) ? BOTTOM : TOP; + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + Direction dir = ctx.getHorizontalDirection().getOpposite(); + return this.defaultBlockState().setValue(FACING, dir); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState updateShape( + BlockState state, + Direction facing, + BlockState neighborState, + LevelAccessor world, + BlockPos pos, + BlockPos neighborPos + ) { + if (!state.getValue(ACTIVE)) { + if (canSupportCenter(world, pos.above(), Direction.DOWN) || world.getBlockState(pos.above()) + .is(BlockTags.LEAVES)) { + return state; + } else { + return Blocks.AIR.defaultBlockState(); + } + } + return state; + } + + @Override + @SuppressWarnings("deprecation") + public BlockState rotate(BlockState state, Rotation rotation) { + return BlocksHelper.rotateHorizontal(state, rotation, FACING); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState mirror(BlockState state, Mirror mirror) { + return BlocksHelper.mirrorHorizontal(state, mirror, FACING); + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + return state.getValue(ACTIVE) ? Collections.singletonList(new ItemStack(this)) : Collections.emptyList(); + } + + @Override + public void playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) { + if (!state.getValue(ACTIVE) && player.isCreative()) { + BlocksHelper.setWithUpdate(world, pos.below(), Blocks.AIR); + } + BlockState up = world.getBlockState(pos.above()); + if (up.is(this) && !up.getValue(ACTIVE)) { + BlocksHelper.setWithUpdate(world, pos.above(), Blocks.AIR); + } + super.playerWillDestroy(world, pos, state, player); + } + + @Override + @SuppressWarnings("deprecation") + public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + if (!state.getValue(ACTIVE)) { + return; + } + if (random.nextBoolean()) { + return; + } + Direction dir = state.getValue(FACING); + BlockPos spawn = pos.relative(dir); + if (!world.getBlockState(spawn).isAir()) { + return; + } + int count = world.getEntities(EndEntities.SILK_MOTH, new AABB(pos).inflate(16), (entity) -> { + return true; + }).size(); + if (count > 6) { + return; + } + SilkMothEntity moth = new SilkMothEntity(EndEntities.SILK_MOTH, world); + moth.moveTo(spawn.getX() + 0.5, spawn.getY() + 0.5, spawn.getZ() + 0.5, dir.toYRot(), 0); + moth.setDeltaMovement(new Vec3(dir.getStepX() * 0.4, 0, dir.getStepZ() * 0.4)); + moth.setHive(world, pos); + world.addFreshEntity(moth); + world.playSound(null, pos, SoundEvents.BEEHIVE_EXIT, SoundSource.BLOCKS, 1, 1); + } + + @Override + @SuppressWarnings("deprecation") + public InteractionResult use( + BlockState state, + Level world, + BlockPos pos, + Player player, + InteractionHand hand, + BlockHitResult hit + ) { + if (hand == InteractionHand.MAIN_HAND) { + ItemStack stack = player.getMainHandItem(); + if (BaseShearsItem.isShear(stack) && state.getValue(ACTIVE) && state.getValue(FULLNESS) == 3) { + BlocksHelper.setWithUpdate(world, pos, state.setValue(FULLNESS, 0)); + Direction dir = state.getValue(FACING); + double px = pos.getX() + dir.getStepX() + 0.5; + double py = pos.getY() + dir.getStepY() + 0.5; + double pz = pos.getZ() + dir.getStepZ() + 0.5; + ItemStack drop = new ItemStack(EndItems.SILK_FIBER, MHelper.randRange(1, 4, world.getRandom())); + ItemEntity entity = new ItemEntity(world, px, py, pz, drop); + world.addFreshEntity(entity); + drop = new ItemStack(EndItems.SILK_MOTH_MATRIX, MHelper.randRange(1, 3, world.getRandom())); + entity = new ItemEntity(world, px, py, pz, drop); + world.addFreshEntity(entity); + if (!player.isCreative()) { + stack.setDamageValue(stack.getDamageValue() + 1); + } + return InteractionResult.SUCCESS; + } + } + return InteractionResult.FAIL; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/SmallAmaranitaBlock.java b/src/main/java/org/betterx/betterend/blocks/SmallAmaranitaBlock.java new file mode 100644 index 00000000..f241ef50 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/SmallAmaranitaBlock.java @@ -0,0 +1,97 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.blocks.basis.EndPlantBlock; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import java.util.Optional; + +public class SmallAmaranitaBlock extends EndPlantBlock { + private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 10, 12); + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.SANGNUM) || state.is(EndBlocks.MOSSY_OBSIDIAN) || state.is(EndBlocks.MOSSY_DRAGON_BONE); + } + + @Override + public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { + BlockPos bigPos = growBig(world, pos); + if (bigPos != null) { + if (EndFeatures.GIGANTIC_AMARANITA.getFeature() + .place(new FeaturePlaceContext( + Optional.empty(), + world, + null, + random, + bigPos, + null + ))) { + replaceMushroom(world, bigPos); + replaceMushroom(world, bigPos.south()); + replaceMushroom(world, bigPos.east()); + replaceMushroom(world, bigPos.south().east()); + } + return; + } + EndFeatures.LARGE_AMARANITA.getFeature() + .place(new FeaturePlaceContext( + Optional.empty(), + world, + null, + random, + pos, + null + )); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + Vec3 vec3d = state.getOffset(view, pos); + return SHAPE.move(vec3d.x, vec3d.y, vec3d.z); + } + + private BlockPos growBig(ServerLevel world, BlockPos pos) { + for (int x = -1; x < 2; x++) { + for (int z = -1; z < 2; z++) { + BlockPos p = pos.offset(x, 0, z); + if (checkFrame(world, p)) { + return p; + } + } + } + return null; + } + + private boolean checkFrame(ServerLevel world, BlockPos pos) { + return world.getBlockState(pos).is(this) && world.getBlockState(pos.south()).is(this) && world.getBlockState(pos + .east()) + .is(this) && world.getBlockState( + pos.south().east()).is(this); + } + + private void replaceMushroom(ServerLevel world, BlockPos pos) { + if (world.getBlockState(pos).is(this)) { + BlocksHelper.setWithUpdate(world, pos, Blocks.AIR); + } + } + + @Override + public boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state) { + return random.nextInt(8) == 0; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/SmallJellyshroomBlock.java b/src/main/java/org/betterx/betterend/blocks/SmallJellyshroomBlock.java new file mode 100644 index 00000000..78150cff --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/SmallJellyshroomBlock.java @@ -0,0 +1,129 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseAttachedBlock; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.items.tool.BaseShearsItem; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.interfaces.PottablePlant; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.BonemealableBlock; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.util.EnumMap; +import java.util.List; +import java.util.Optional; + +public class SmallJellyshroomBlock extends BaseAttachedBlock implements RenderLayerProvider, BonemealableBlock, PottablePlant { + private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(Direction.class); + + public SmallJellyshroomBlock() { + super(FabricBlockSettings.of(Material.PLANT).sound(SoundType.NETHER_WART).noCollission()); + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return BOUNDING_SHAPES.get(state.getValue(FACING)); + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + ItemStack tool = builder.getParameter(LootContextParams.TOOL); + if (tool != null && BaseShearsItem.isShear(tool) || EnchantmentHelper.getItemEnchantmentLevel( + Enchantments.SILK_TOUCH, + tool + ) > 0) { + return Lists.newArrayList(new ItemStack(this)); + } else { + return Lists.newArrayList(); + } + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + Direction direction = state.getValue(FACING); + BlockPos blockPos = pos.relative(direction.getOpposite()); + BlockState support = world.getBlockState(blockPos); + return canSupportCenter(world, blockPos, direction) && support.canOcclude() && support.getLightEmission() == 0; + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + static { + BOUNDING_SHAPES.put(Direction.UP, Block.box(3, 0, 3, 13, 16, 13)); + BOUNDING_SHAPES.put(Direction.DOWN, Block.box(3, 0, 3, 13, 16, 13)); + BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.0, 0.0, 0.5, 1.0, 1.0, 1.0)); + BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 0.5)); + BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.5, 0.0, 0.0, 1.0, 1.0, 1.0)); + BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.0, 0.0, 0.5, 1.0, 1.0)); + } + + @Override + public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { + return state.getValue(FACING) == Direction.UP && world.getBlockState(pos.below()) + .is(CommonBlockTags.END_STONES); + } + + @Override + public boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state) { + return random.nextInt(16) == 0; + } + + @Override + public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { + BlocksHelper.setWithUpdate(world, pos, Blocks.AIR); + EndFeatures.JELLYSHROOM.getFeature() + .place(new FeaturePlaceContext( + Optional.empty(), + world, + null, + random, + pos, + null + )); + } + + @Override + public boolean canPlantOn(Block block) { + return true; + } + + @Override + @Environment(EnvType.CLIENT) + public String getPottedState() { + return "facing=up"; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/SmaragdantCrystalBlock.java b/src/main/java/org/betterx/betterend/blocks/SmaragdantCrystalBlock.java new file mode 100644 index 00000000..b33f7a65 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/SmaragdantCrystalBlock.java @@ -0,0 +1,20 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.interfaces.tools.AddMineablePickaxe; +import org.betterx.betterend.blocks.basis.LitPillarBlock; + +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.material.Material; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class SmaragdantCrystalBlock extends LitPillarBlock implements AddMineablePickaxe { + public SmaragdantCrystalBlock() { + super(FabricBlockSettings.of(Material.GLASS) + .luminance(15) + .hardness(1F) + .resistance(1F) + .noOcclusion() + .sound(SoundType.AMETHYST)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/SmaragdantCrystalShardBlock.java b/src/main/java/org/betterx/betterend/blocks/SmaragdantCrystalShardBlock.java new file mode 100644 index 00000000..566d7843 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/SmaragdantCrystalShardBlock.java @@ -0,0 +1,105 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseAttachedBlock; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.interfaces.tools.AddMineablePickaxe; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.LiquidBlockContainer; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.*; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Maps; + +import java.util.EnumMap; + +@SuppressWarnings("deprecation") +public class SmaragdantCrystalShardBlock extends BaseAttachedBlock implements AddMineablePickaxe, RenderLayerProvider, SimpleWaterloggedBlock, LiquidBlockContainer { + private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(Direction.class); + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + + public SmaragdantCrystalShardBlock() { + super(FabricBlockSettings.of(Material.STONE) + .materialColor(MaterialColor.COLOR_GREEN) + .luminance(15) + .sound(SoundType.AMETHYST_CLUSTER) + .requiresCorrectToolForDrops() + .noCollission()); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + super.createBlockStateDefinition(stateManager); + stateManager.add(WATERLOGGED); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + @Override + public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { + return !state.getValue(WATERLOGGED); + } + + @Override + public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) { + return !state.getValue(WATERLOGGED); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + BlockState state = super.getStateForPlacement(ctx); + if (state != null) { + LevelReader worldView = ctx.getLevel(); + BlockPos blockPos = ctx.getClickedPos(); + boolean water = worldView.getFluidState(blockPos).getType() == Fluids.WATER; + return state.setValue(WATERLOGGED, water); + } + return null; + } + + @Override + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : Fluids.EMPTY.defaultFluidState(); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return BOUNDING_SHAPES.get(state.getValue(FACING)); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + Direction direction = state.getValue(FACING); + BlockPos blockPos = pos.relative(direction.getOpposite()); + return world.getBlockState(blockPos).isFaceSturdy(world, blockPos, direction); + } + + static { + BOUNDING_SHAPES.put(Direction.UP, Shapes.box(0.125, 0.0, 0.125, 0.875F, 0.875F, 0.875F)); + BOUNDING_SHAPES.put(Direction.DOWN, Shapes.box(0.125, 0.125, 0.125, 0.875F, 1.0, 0.875F)); + BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.125, 0.125, 0.125, 0.875F, 0.875F, 1.0)); + BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.125, 0.125, 0.0, 0.875F, 0.875F, 0.875F)); + BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.125, 0.125, 0.125, 1.0, 0.875F, 0.875F)); + BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.125, 0.125, 0.875F, 0.875F, 0.875F)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/SulphurCrystalBlock.java b/src/main/java/org/betterx/betterend/blocks/SulphurCrystalBlock.java new file mode 100644 index 00000000..704a8f80 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/SulphurCrystalBlock.java @@ -0,0 +1,122 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseAttachedBlock; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.interfaces.tools.AddMineablePickaxe; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.LiquidBlockContainer; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.material.*; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.util.Collections; +import java.util.EnumMap; +import java.util.List; + +@SuppressWarnings("deprecation") +public class SulphurCrystalBlock extends BaseAttachedBlock implements AddMineablePickaxe, RenderLayerProvider, SimpleWaterloggedBlock, LiquidBlockContainer { + private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(Direction.class); + public static final IntegerProperty AGE = IntegerProperty.create("age", 0, 2); + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + + public SulphurCrystalBlock() { + super(FabricBlockSettings.of(Material.STONE) + .materialColor(MaterialColor.COLOR_YELLOW) + .sound(SoundType.GLASS) + .requiresCorrectToolForDrops() + .noCollission()); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + super.createBlockStateDefinition(stateManager); + stateManager.add(AGE, WATERLOGGED); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + return state.getValue(AGE) < 2 ? Collections.emptyList() : Lists.newArrayList(new ItemStack( + EndItems.CRYSTALLINE_SULPHUR, + MHelper.randRange(1, 3, MHelper.RANDOM_SOURCE) + )); + } + + @Override + public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { + return !state.getValue(WATERLOGGED); + } + + @Override + public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) { + return !state.getValue(WATERLOGGED); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + BlockState state = super.getStateForPlacement(ctx); + if (state != null) { + LevelReader worldView = ctx.getLevel(); + BlockPos blockPos = ctx.getClickedPos(); + boolean water = worldView.getFluidState(blockPos).getType() == Fluids.WATER; + return state.setValue(WATERLOGGED, water); + } + return null; + } + + @Override + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : Fluids.EMPTY.defaultFluidState(); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return BOUNDING_SHAPES.get(state.getValue(FACING)); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + Direction direction = state.getValue(FACING); + BlockPos blockPos = pos.relative(direction.getOpposite()); + return world.getBlockState(blockPos).is(EndBlocks.BRIMSTONE); + } + + static { + BOUNDING_SHAPES.put(Direction.UP, Shapes.box(0.125, 0.0, 0.125, 0.875F, 0.5, 0.875F)); + BOUNDING_SHAPES.put(Direction.DOWN, Shapes.box(0.125, 0.5, 0.125, 0.875F, 1.0, 0.875F)); + BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.125, 0.125, 0.5, 0.875F, 0.875F, 1.0)); + BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.125, 0.125, 0.0, 0.875F, 0.875F, 0.5)); + BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.5, 0.125, 0.125, 1.0, 0.875F, 0.875F)); + BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.125, 0.125, 0.5, 0.875F, 0.875F)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/TenaneaFlowersBlock.java b/src/main/java/org/betterx/betterend/blocks/TenaneaFlowersBlock.java new file mode 100644 index 00000000..9058df9e --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/TenaneaFlowersBlock.java @@ -0,0 +1,83 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseVineBlock; +import org.betterx.bclib.interfaces.CustomColorProvider; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.ui.ColorUtil; + +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.item.ItemColor; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class TenaneaFlowersBlock extends BaseVineBlock implements CustomColorProvider { + public static final Vec3i[] COLORS; + + public TenaneaFlowersBlock() { + super(15); + } + + @Override + public BlockColor getProvider() { + return (state, world, pos, tintIndex) -> { + if (pos == null) { + pos = BlockPos.ZERO; + } + long i = (MHelper.getRandom(pos.getX(), pos.getZ()) & 63) + pos.getY(); + double delta = i * 0.1; + int index = MHelper.floor(delta); + int index2 = (index + 1) & 3; + delta -= index; + index &= 3; + + Vec3i color1 = COLORS[index]; + Vec3i color2 = COLORS[index2]; + + int r = MHelper.floor(Mth.lerp(delta, color1.getX(), color2.getX())); + int g = MHelper.floor(Mth.lerp(delta, color1.getY(), color2.getY())); + int b = MHelper.floor(Mth.lerp(delta, color1.getZ(), color2.getZ())); + float[] hsb = ColorUtil.RGBtoHSB(r, g, b, new float[3]); + + return ColorUtil.HSBtoRGB(hsb[0], MHelper.max(0.5F, hsb[1]), hsb[2]); + }; + } + + @Override + public ItemColor getItemProvider() { + return (stack, tintIndex) -> ColorUtil.color(255, 255, 255); + } + + @Override + public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { + return false; + } + + @Environment(EnvType.CLIENT) + public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) { + super.animateTick(state, world, pos, random); + if (random.nextInt(32) == 0) { + double x = (double) pos.getX() + random.nextGaussian() + 0.5; + double z = (double) pos.getZ() + random.nextGaussian() + 0.5; + double y = (double) pos.getY() + random.nextDouble(); + world.addParticle(EndParticles.TENANEA_PETAL, x, y, z, 0, 0, 0); + } + } + + static { + COLORS = new Vec3i[]{ + new Vec3i(250, 111, 222), + new Vec3i(167, 89, 255), + new Vec3i(120, 207, 239), + new Vec3i(255, 87, 182) + }; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/TenaneaSaplingBlock.java b/src/main/java/org/betterx/betterend/blocks/TenaneaSaplingBlock.java new file mode 100644 index 00000000..695d5275 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/TenaneaSaplingBlock.java @@ -0,0 +1,28 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.PottableFeatureSapling; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.features.trees.TenaneaFeature; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class TenaneaSaplingBlock extends PottableFeatureSapling { + public TenaneaSaplingBlock() { + super((state) -> EndFeatures.TENANEA.configuredFeature); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + return world.getBlockState(pos.below()).is(EndBlocks.PINK_MOSS); + } + + @Override + public boolean canPlantOn(Block block) { + return block == EndBlocks.PINK_MOSS; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/TerrainPlantBlock.java b/src/main/java/org/betterx/betterend/blocks/TerrainPlantBlock.java new file mode 100644 index 00000000..c6013d1b --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/TerrainPlantBlock.java @@ -0,0 +1,25 @@ +package org.betterx.betterend.blocks; + +import org.betterx.betterend.blocks.basis.EndPlantBlock; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +public class TerrainPlantBlock extends EndPlantBlock { + private final Block[] ground; + + public TerrainPlantBlock(Block... ground) { + super(true); + this.ground = ground; + } + + @Override + protected boolean isTerrain(BlockState state) { + for (Block block : ground) { + if (state.is(block)) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/TwistedUmbrellaMossBlock.java b/src/main/java/org/betterx/betterend/blocks/TwistedUmbrellaMossBlock.java new file mode 100644 index 00000000..5a52b679 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/TwistedUmbrellaMossBlock.java @@ -0,0 +1,51 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseDoublePlantBlock; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.blocks.basis.EndPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class TwistedUmbrellaMossBlock extends EndPlantBlock { + public TwistedUmbrellaMossBlock() { + super(11); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.END_MOSS) || state.is(EndBlocks.END_MYCELIUM) || state.is(EndBlocks.JUNGLE_MOSS); + } + + @Environment(EnvType.CLIENT) + public boolean hasEmissiveLighting(BlockGetter world, BlockPos pos) { + return true; + } + + @Environment(EnvType.CLIENT) + public float getAmbientOcclusionLightLevel(BlockGetter world, BlockPos pos) { + return 1F; + } + + @Override + public boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state) { + return world.isEmptyBlock(pos.above()); + } + + @Override + public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { + int rot = world.random.nextInt(4); + BlockState bs = EndBlocks.TWISTED_UMBRELLA_MOSS_TALL.defaultBlockState() + .setValue(BaseDoublePlantBlock.ROTATION, rot); + BlocksHelper.setWithoutUpdate(world, pos, bs); + BlocksHelper.setWithoutUpdate(world, pos.above(), bs.setValue(BaseDoublePlantBlock.TOP, true)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/TwistedUmbrellaMossTallBlock.java b/src/main/java/org/betterx/betterend/blocks/TwistedUmbrellaMossTallBlock.java new file mode 100644 index 00000000..36788839 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/TwistedUmbrellaMossTallBlock.java @@ -0,0 +1,34 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseDoublePlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; + +public class TwistedUmbrellaMossTallBlock extends BaseDoublePlantBlock { + public TwistedUmbrellaMossTallBlock() { + super(12); + } + + @Override + public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { + ItemEntity item = new ItemEntity( + world, + pos.getX() + 0.5, + pos.getY() + 0.5, + pos.getZ() + 0.5, + new ItemStack(EndBlocks.TWISTED_UMBRELLA_MOSS) + ); + world.addFreshEntity(item); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.END_MOSS) || state.is(EndBlocks.END_MYCELIUM) || state.is(EndBlocks.JUNGLE_MOSS); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/UmbrellaMossBlock.java b/src/main/java/org/betterx/betterend/blocks/UmbrellaMossBlock.java new file mode 100644 index 00000000..5a7cea99 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/UmbrellaMossBlock.java @@ -0,0 +1,50 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseDoublePlantBlock; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.blocks.basis.EndPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class UmbrellaMossBlock extends EndPlantBlock { + public UmbrellaMossBlock() { + super(11); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.END_MOSS) || state.is(EndBlocks.END_MYCELIUM) || state.is(EndBlocks.JUNGLE_MOSS); + } + + @Environment(EnvType.CLIENT) + public boolean hasEmissiveLighting(BlockGetter world, BlockPos pos) { + return true; + } + + @Environment(EnvType.CLIENT) + public float getAmbientOcclusionLightLevel(BlockGetter world, BlockPos pos) { + return 1F; + } + + @Override + public boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state) { + return world.isEmptyBlock(pos.above()); + } + + @Override + public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { + int rot = world.random.nextInt(4); + BlockState bs = EndBlocks.UMBRELLA_MOSS_TALL.defaultBlockState().setValue(BaseDoublePlantBlock.ROTATION, rot); + BlocksHelper.setWithoutUpdate(world, pos, bs); + BlocksHelper.setWithoutUpdate(world, pos.above(), bs.setValue(BaseDoublePlantBlock.TOP, true)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/UmbrellaMossTallBlock.java b/src/main/java/org/betterx/betterend/blocks/UmbrellaMossTallBlock.java new file mode 100644 index 00000000..4a9c8b36 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/UmbrellaMossTallBlock.java @@ -0,0 +1,34 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseDoublePlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; + +public class UmbrellaMossTallBlock extends BaseDoublePlantBlock { + public UmbrellaMossTallBlock() { + super(12); + } + + @Override + public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { + ItemEntity item = new ItemEntity( + world, + pos.getX() + 0.5, + pos.getY() + 0.5, + pos.getZ() + 0.5, + new ItemStack(EndBlocks.UMBRELLA_MOSS) + ); + world.addFreshEntity(item); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(EndBlocks.END_MOSS) || state.is(EndBlocks.END_MYCELIUM) || state.is(EndBlocks.JUNGLE_MOSS); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/UmbrellaTreeClusterBlock.java b/src/main/java/org/betterx/betterend/blocks/UmbrellaTreeClusterBlock.java new file mode 100644 index 00000000..88c2fbe2 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/UmbrellaTreeClusterBlock.java @@ -0,0 +1,81 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.core.BlockPos; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.MaterialColor; +import net.minecraft.world.phys.BlockHitResult; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class UmbrellaTreeClusterBlock extends BaseBlock { + public static final BooleanProperty NATURAL = BlockProperties.NATURAL; + + public UmbrellaTreeClusterBlock() { + super(FabricBlockSettings + .copyOf(Blocks.NETHER_WART_BLOCK) + .mapColor(MaterialColor.COLOR_PURPLE) + .luminance(15) + ); + registerDefaultState(stateDefinition.any().setValue(NATURAL, false)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(NATURAL); + } + + @Override + @SuppressWarnings("deprecation") + public InteractionResult use( + BlockState state, + Level world, + BlockPos pos, + Player player, + InteractionHand hand, + BlockHitResult hit + ) { + ItemStack stack = player.getMainHandItem(); + if (stack.getItem() == Items.GLASS_BOTTLE) { + if (!player.isCreative()) { + stack.shrink(1); + } + stack = new ItemStack(EndItems.UMBRELLA_CLUSTER_JUICE); + player.addItem(stack); + world.playLocalSound( + pos.getX() + 0.5, + pos.getY() + 0.5, + pos.getZ() + 0.5, + SoundEvents.BOTTLE_FILL, + SoundSource.BLOCKS, + 1, + 1, + false + ); + BlocksHelper.setWithUpdate( + world, + pos, + EndBlocks.UMBRELLA_TREE_CLUSTER_EMPTY.defaultBlockState().setValue(NATURAL, state.getValue(NATURAL)) + ); + return InteractionResult.SUCCESS; + } + return InteractionResult.FAIL; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/UmbrellaTreeClusterEmptyBlock.java b/src/main/java/org/betterx/betterend/blocks/UmbrellaTreeClusterEmptyBlock.java new file mode 100644 index 00000000..be832127 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/UmbrellaTreeClusterEmptyBlock.java @@ -0,0 +1,47 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.blocks.BaseBlock; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class UmbrellaTreeClusterEmptyBlock extends BaseBlock { + public static final BooleanProperty NATURAL = EndBlockProperties.NATURAL; + + public UmbrellaTreeClusterEmptyBlock() { + super(FabricBlockSettings + .copyOf(Blocks.NETHER_WART_BLOCK) + .mapColor(MaterialColor.COLOR_PURPLE) + .randomTicks() + ); + registerDefaultState(stateDefinition.any().setValue(NATURAL, false)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(NATURAL); + } + + @Override + @SuppressWarnings("deprecation") + public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + if (state.getValue(NATURAL) && random.nextInt(16) == 0) { + BlocksHelper.setWithUpdate( + world, + pos, + EndBlocks.UMBRELLA_TREE_CLUSTER.defaultBlockState().setValue(UmbrellaTreeClusterBlock.NATURAL, true) + ); + } + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/UmbrellaTreeMembraneBlock.java b/src/main/java/org/betterx/betterend/blocks/UmbrellaTreeMembraneBlock.java new file mode 100644 index 00000000..17eaa887 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/UmbrellaTreeMembraneBlock.java @@ -0,0 +1,92 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.BlockModelProvider; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SlimeBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.storage.loot.LootContext; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Lists; + +import java.util.Collections; +import java.util.List; + +public class UmbrellaTreeMembraneBlock extends SlimeBlock implements RenderLayerProvider, BlockModelProvider { + public static final IntegerProperty COLOR = EndBlockProperties.COLOR; + private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(0); + + public UmbrellaTreeMembraneBlock() { + super(FabricBlockSettings.copyOf(Blocks.SLIME_BLOCK)); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + double px = ctx.getClickedPos().getX() * 0.1; + double py = ctx.getClickedPos().getY() * 0.1; + double pz = ctx.getClickedPos().getZ() * 0.1; + return this.defaultBlockState().setValue(COLOR, MHelper.floor(NOISE.eval(px, py, pz) * 3.5 + 4)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(COLOR); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.TRANSLUCENT; + } + + @Override + @SuppressWarnings("deprecation") + public List getDrops(BlockState state, LootContext.Builder builder) { + if (state.getValue(COLOR) > 0) { + return Lists.newArrayList(new ItemStack(this)); + } else { + return MHelper.RANDOM.nextInt(4) == 0 + ? Lists.newArrayList(new ItemStack(EndBlocks.UMBRELLA_TREE_SAPLING)) + : Collections + .emptyList(); + } + } + + @Override + public boolean propagatesSkylightDown(BlockState state, BlockGetter world, BlockPos pos) { + return state.getValue(COLOR) > 0; + } + + @Environment(EnvType.CLIENT) + public boolean skipRendering(BlockState state, BlockState stateFrom, Direction direction) { + if (state.getValue(COLOR) > 0) { + return super.skipRendering(state, stateFrom, direction); + } else { + return false; + } + } + + @Override + @Environment(EnvType.CLIENT) + public BlockModel getItemModel(ResourceLocation resourceLocation) { + return getBlockModel(resourceLocation, defaultBlockState()); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/UmbrellaTreeSaplingBlock.java b/src/main/java/org/betterx/betterend/blocks/UmbrellaTreeSaplingBlock.java new file mode 100644 index 00000000..11ab4ba7 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/UmbrellaTreeSaplingBlock.java @@ -0,0 +1,34 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.betterend.blocks.basis.PottableFeatureSapling; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.features.trees.UmbrellaTreeFeature; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class UmbrellaTreeSaplingBlock extends PottableFeatureSapling { + public UmbrellaTreeSaplingBlock() { + super((state) -> EndFeatures.UMBRELLA_TREE.configuredFeature); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + return world.getBlockState(pos.below()).is(EndBlocks.JUNGLE_MOSS); + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.TRANSLUCENT; + } + + @Override + public boolean canPlantOn(Block block) { + return block == EndBlocks.JUNGLE_MOSS; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/VentBubbleColumnBlock.java b/src/main/java/org/betterx/betterend/blocks/VentBubbleColumnBlock.java new file mode 100644 index 00000000..7b645578 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/VentBubbleColumnBlock.java @@ -0,0 +1,171 @@ +package org.betterx.betterend.blocks; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Optional; + +public class VentBubbleColumnBlock extends Block implements BucketPickup, LiquidBlockContainer { + public VentBubbleColumnBlock() { + super(FabricBlockSettings.of(Material.BUBBLE_COLUMN).nonOpaque().noCollision().noLootTable()); + } + + @Override + public ItemStack pickupBlock(LevelAccessor world, BlockPos pos, BlockState state) { + world.setBlock(pos, Blocks.AIR.defaultBlockState(), 11); + return new ItemStack(Items.WATER_BUCKET); + } + + @Override + @SuppressWarnings("deprecation") + public RenderShape getRenderShape(BlockState state) { + return RenderShape.INVISIBLE; + } + + @Override + @SuppressWarnings("deprecation") + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + BlockState blockState = world.getBlockState(pos.below()); + return blockState.is(this) || blockState.is(EndBlocks.HYDROTHERMAL_VENT); + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + return Shapes.empty(); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState updateShape( + BlockState state, + Direction direction, + BlockState newState, + LevelAccessor world, + BlockPos pos, + BlockPos posFrom + ) { + if (!state.canSurvive(world, pos)) { + return Blocks.WATER.defaultBlockState(); + } else { + BlockPos up = pos.above(); + if (world.getBlockState(up).is(Blocks.WATER)) { + BlocksHelper.setWithoutUpdate(world, up, this); + world.scheduleTick(up, this, 5); + } + } + return state; + } + + @Environment(EnvType.CLIENT) + public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) { + if (random.nextInt(4) == 0) { + double px = pos.getX() + random.nextDouble(); + double py = pos.getY() + random.nextDouble(); + double pz = pos.getZ() + random.nextDouble(); + world.addAlwaysVisibleParticle(ParticleTypes.BUBBLE_COLUMN_UP, px, py, pz, 0, 0.04, 0); + } + if (random.nextInt(200) == 0) { + world.playLocalSound( + pos.getX(), + pos.getY(), + pos.getZ(), + SoundEvents.BUBBLE_COLUMN_UPWARDS_AMBIENT, + SoundSource.BLOCKS, + 0.2F + random.nextFloat() * 0.2F, + 0.9F + random.nextFloat() * 0.15F, + false + ); + } + } + + @Environment(EnvType.CLIENT) + @SuppressWarnings("deprecation") + public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + BlockState blockState = world.getBlockState(pos.above()); + if (blockState.isAir()) { + entity.onAboveBubbleCol(false); + if (!world.isClientSide) { + ServerLevel serverWorld = (ServerLevel) world; + + for (int i = 0; i < 2; ++i) { + serverWorld.sendParticles( + ParticleTypes.SPLASH, + (double) pos.getX() + world.random.nextDouble(), + pos.getY() + 1, + (double) pos.getZ() + world.random.nextDouble(), + 1, + 0.0D, + 0.0D, + 0.0D, + 1.0D + ); + serverWorld.sendParticles( + ParticleTypes.BUBBLE, + (double) pos.getX() + world.random.nextDouble(), + pos.getY() + 1, + (double) pos.getZ() + world.random.nextDouble(), + 1, + 0.0D, + 0.01D, + 0.0D, + 0.2D + ); + } + } + } else { + entity.onInsideBubbleColumn(false); + } + } + + @Override + public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { + return false; + } + + @Override + public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) { + return false; + } + + @Override + @SuppressWarnings("deprecation") + public FluidState getFluidState(BlockState state) { + return Fluids.WATER.getSource(false); + } + + + @Override + public Optional getPickupSound() { + return Fluids.WATER.getPickupSound(); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/EndAnvilBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/EndAnvilBlock.java new file mode 100644 index 00000000..23626c14 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/EndAnvilBlock.java @@ -0,0 +1,19 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.LeveledAnvilBlock; +import org.betterx.betterend.complexmaterials.MetalMaterial; + +import net.minecraft.world.level.material.MaterialColor; + +public class EndAnvilBlock extends LeveledAnvilBlock { + protected MetalMaterial metalMaterial; + + public EndAnvilBlock(MaterialColor color, int level) { + super(color, level); + } + + public EndAnvilBlock(MetalMaterial metalMaterial, MaterialColor color, int level) { + super(color, level); + this.metalMaterial = metalMaterial; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/EndLanternBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/EndLanternBlock.java new file mode 100644 index 00000000..664453ce --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/EndLanternBlock.java @@ -0,0 +1,140 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.BaseBlockNotFull; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.client.models.ModelsHelper; + +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.LiquidBlockContainer; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Map; + +@SuppressWarnings("deprecation") +public class EndLanternBlock extends BaseBlockNotFull implements SimpleWaterloggedBlock, LiquidBlockContainer { + public static final BooleanProperty IS_FLOOR = BlockProperties.IS_FLOOR; + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + + public EndLanternBlock(Block source) { + this(FabricBlockSettings.copyOf(source).luminance(15).noOcclusion()); + } + + public EndLanternBlock(Properties settings) { + super(settings.noOcclusion()); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(IS_FLOOR, WATERLOGGED); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + LevelReader worldView = ctx.getLevel(); + BlockPos blockPos = ctx.getClickedPos(); + Direction dir = ctx.getClickedFace(); + boolean water = worldView.getFluidState(blockPos).getType() == Fluids.WATER; + if (dir != Direction.DOWN && dir != Direction.UP) { + if (canSupportCenter(worldView, blockPos.above(), Direction.DOWN)) { + return defaultBlockState().setValue(IS_FLOOR, false).setValue(WATERLOGGED, water); + } else if (canSupportCenter(worldView, blockPos.below(), Direction.UP)) { + return defaultBlockState().setValue(IS_FLOOR, true).setValue(WATERLOGGED, water); + } else { + return null; + } + } else if (dir == Direction.DOWN) { + if (canSupportCenter(worldView, blockPos.above(), Direction.DOWN)) { + return defaultBlockState().setValue(IS_FLOOR, false).setValue(WATERLOGGED, water); + } else if (canSupportCenter(worldView, blockPos.below(), Direction.UP)) { + return defaultBlockState().setValue(IS_FLOOR, true).setValue(WATERLOGGED, water); + } else { + return null; + } + } else { + if (canSupportCenter(worldView, blockPos.below(), Direction.UP)) { + return defaultBlockState().setValue(IS_FLOOR, true).setValue(WATERLOGGED, water); + } else if (canSupportCenter(worldView, blockPos.above(), Direction.DOWN)) { + return defaultBlockState().setValue(IS_FLOOR, false).setValue(WATERLOGGED, water); + } else { + return null; + } + } + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + if (state.getValue(IS_FLOOR)) { + return canSupportCenter(world, pos.below(), Direction.UP); + } else { + return canSupportCenter(world, pos.above(), Direction.DOWN); + } + } + + @Override + public BlockState updateShape( + BlockState state, + Direction facing, + BlockState neighborState, + LevelAccessor world, + BlockPos pos, + BlockPos neighborPos + ) { + Boolean water = state.getValue(WATERLOGGED); + if (water) { + world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); + } + if (!canSurvive(state, world, pos)) { + return water ? Blocks.WATER.defaultBlockState() : Blocks.AIR.defaultBlockState(); + } else { + return state; + } + } + + @Override + public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { + return false; + } + + @Override + public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) { + return false; + } + + @Override + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : Fluids.EMPTY.defaultFluidState(); + } + + @Override + @Environment(EnvType.CLIENT) + public UnbakedModel getModelVariant( + ResourceLocation stateId, + BlockState blockState, + Map modelCache + ) { + String floor = blockState.getValue(IS_FLOOR) ? "_floor" : ""; + ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath() + floor); + registerBlockModel(stateId, modelId, blockState, modelCache); + return ModelsHelper.createBlockSimple(modelId); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/EndPlantBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/EndPlantBlock.java new file mode 100644 index 00000000..267cd115 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/EndPlantBlock.java @@ -0,0 +1,41 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.BasePlantBlock; +import org.betterx.betterend.interfaces.PottablePlant; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +public class EndPlantBlock extends BasePlantBlock implements PottablePlant { + protected EndPlantBlock() { + super(); + } + + protected EndPlantBlock(boolean replaceable) { + super(replaceable); + } + + protected EndPlantBlock(int light) { + super(light); + } + + protected EndPlantBlock(Properties props) { + super(props); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(CommonBlockTags.END_STONES); + } + + @Override + public boolean canPlantOn(Block block) { + return isTerrain(block.defaultBlockState()); + } + + @Override + public boolean canBePotted() { + return getStateDefinition().getProperties().isEmpty(); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/EndPlantWithAgeBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/EndPlantWithAgeBlock.java new file mode 100644 index 00000000..3187ef08 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/EndPlantWithAgeBlock.java @@ -0,0 +1,21 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.BasePlantWithAgeBlock; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.world.level.block.state.BlockState; + +public abstract class EndPlantWithAgeBlock extends BasePlantWithAgeBlock { + protected EndPlantWithAgeBlock() { + super(); + } + + public EndPlantWithAgeBlock(Properties settings) { + super(settings); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(CommonBlockTags.END_STONES); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/EndTerrainBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/EndTerrainBlock.java new file mode 100644 index 00000000..a4e10f0f --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/EndTerrainBlock.java @@ -0,0 +1,25 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.BaseTerrainBlock; +import org.betterx.bclib.interfaces.TagProvider; +import org.betterx.betterend.interfaces.PottableTerrain; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.material.MaterialColor; + +import java.util.List; + +public class EndTerrainBlock extends BaseTerrainBlock implements PottableTerrain, TagProvider { + public EndTerrainBlock(MaterialColor color) { + super(Blocks.END_STONE, color); + } + + @Override + public void addTags(List> blockTags, List> itemTags) { + blockTags.add(CommonBlockTags.END_STONES); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/EndTripleTerrain.java b/src/main/java/org/betterx/betterend/blocks/basis/EndTripleTerrain.java new file mode 100644 index 00000000..1bbcc2b4 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/EndTripleTerrain.java @@ -0,0 +1,13 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.TripleTerrainBlock; +import org.betterx.betterend.interfaces.PottableTerrain; + +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.material.MaterialColor; + +public class EndTripleTerrain extends TripleTerrainBlock implements PottableTerrain { + public EndTripleTerrain(MaterialColor color) { + super(Blocks.END_STONE, color); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/EndUnderwaterPlantBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/EndUnderwaterPlantBlock.java new file mode 100644 index 00000000..c6edf9c8 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/EndUnderwaterPlantBlock.java @@ -0,0 +1,21 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.UnderwaterPlantBlock; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.world.level.block.state.BlockState; + +public class EndUnderwaterPlantBlock extends UnderwaterPlantBlock { + + public EndUnderwaterPlantBlock() { + } + + public EndUnderwaterPlantBlock(Properties settings) { + super(settings); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(CommonBlockTags.END_STONES); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/EndUnderwaterWallPlantBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/EndUnderwaterWallPlantBlock.java new file mode 100644 index 00000000..be4cf3d3 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/EndUnderwaterWallPlantBlock.java @@ -0,0 +1,17 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.BaseUnderwaterWallPlantBlock; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.world.level.block.state.BlockState; + +public class EndUnderwaterWallPlantBlock extends BaseUnderwaterWallPlantBlock { + + public EndUnderwaterWallPlantBlock() { + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(CommonBlockTags.END_STONES); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/EndWallMushroom.java b/src/main/java/org/betterx/betterend/blocks/basis/EndWallMushroom.java new file mode 100644 index 00000000..c57b47b6 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/EndWallMushroom.java @@ -0,0 +1,18 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.WallMushroomBlock; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.world.level.block.state.BlockState; + +public class EndWallMushroom extends WallMushroomBlock { + + public EndWallMushroom(int light) { + super(light); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(CommonBlockTags.END_STONES); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/EndWallPlantBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/EndWallPlantBlock.java new file mode 100644 index 00000000..c065e79d --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/EndWallPlantBlock.java @@ -0,0 +1,20 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.BaseWallPlantBlock; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.world.level.block.state.BlockState; + +public class EndWallPlantBlock extends BaseWallPlantBlock { + public EndWallPlantBlock() { + } + + public EndWallPlantBlock(int light) { + super(light); + } + + @Override + protected boolean isTerrain(BlockState state) { + return state.is(CommonBlockTags.END_STONES); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/FurBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/FurBlock.java new file mode 100644 index 00000000..ed87f844 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/FurBlock.java @@ -0,0 +1,95 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.BaseAttachedBlock; +import org.betterx.bclib.client.render.BCLRenderLayer; +import org.betterx.bclib.interfaces.RenderLayerProvider; +import org.betterx.bclib.interfaces.tools.AddMineableShears; +import org.betterx.bclib.items.tool.BaseShearsItem; +import org.betterx.bclib.util.MHelper; +import org.betterx.worlds.together.tag.v3.TagManager; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.tags.BlockTags; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.util.EnumMap; +import java.util.List; + +public class FurBlock extends BaseAttachedBlock implements RenderLayerProvider, AddMineableShears { + private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(Direction.class); + private final ItemLike drop; + private final int dropChance; + + public FurBlock(ItemLike drop, int light, int dropChance, boolean wet) { + super(FabricBlockSettings.of(Material.REPLACEABLE_PLANT) + .luminance(light) + .sound(wet ? SoundType.WET_GRASS : SoundType.GRASS) + .noCollission()); + this.drop = drop; + this.dropChance = dropChance; + TagManager.BLOCKS.add(BlockTags.LEAVES, this); + } + + public FurBlock(ItemLike drop, int dropChance) { + super(FabricBlockSettings.of(Material.REPLACEABLE_PLANT) + + .sound(SoundType.GRASS) + .noCollission()); + this.drop = drop; + this.dropChance = dropChance; + TagManager.BLOCKS.add(BlockTags.LEAVES, this); + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return BOUNDING_SHAPES.get(state.getValue(FACING)); + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + ItemStack tool = builder.getParameter(LootContextParams.TOOL); + if (tool != null && BaseShearsItem.isShear(tool) || EnchantmentHelper.getItemEnchantmentLevel( + Enchantments.SILK_TOUCH, + tool + ) > 0) { + return Lists.newArrayList(new ItemStack(this)); + } else if (dropChance < 1 || MHelper.RANDOM.nextInt(dropChance) == 0) { + return Lists.newArrayList(new ItemStack(drop)); + } else { + return Lists.newArrayList(); + } + } + + @Override + public BCLRenderLayer getRenderLayer() { + return BCLRenderLayer.CUTOUT; + } + + static { + BOUNDING_SHAPES.put(Direction.UP, Shapes.box(0.0, 0.0, 0.0, 1.0, 0.5, 1.0)); + BOUNDING_SHAPES.put(Direction.DOWN, Shapes.box(0.0, 0.5, 0.0, 1.0, 1.0, 1.0)); + BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.0, 0.0, 0.5, 1.0, 1.0, 1.0)); + BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 0.5)); + BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.5, 0.0, 0.0, 1.0, 1.0, 1.0)); + BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.0, 0.0, 0.5, 1.0, 1.0)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/LitBaseBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/LitBaseBlock.java new file mode 100644 index 00000000..614b0c96 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/LitBaseBlock.java @@ -0,0 +1,27 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.BaseBlock; + +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.state.BlockState; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import org.jetbrains.annotations.Nullable; + +public class LitBaseBlock extends BaseBlock { + private static final String PATTERN = "{\"parent\":\"betterend:block/cube_noshade\",\"textures\":{\"texture\":\"betterend:block/name\"}}"; + + public LitBaseBlock(Properties settings) { + super(settings); + } + + @Nullable + @Override + @Environment(EnvType.CLIENT) + public BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { + return BlockModel.fromString(PATTERN.replace("name", resourceLocation.getPath())); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/LitPillarBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/LitPillarBlock.java new file mode 100644 index 00000000..a6a365b5 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/LitPillarBlock.java @@ -0,0 +1,25 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.BaseRotatedPillarBlock; + +import net.minecraft.resources.ResourceLocation; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import java.util.Optional; + +public class LitPillarBlock extends BaseRotatedPillarBlock { + private static final String PATTERN = "{\"parent\":\"betterend:block/pillar_noshade\",\"textures\":{\"end\":\"betterend:block/name_top\",\"side\":\"betterend:block/name_side\"}}"; + + public LitPillarBlock(Properties settings) { + super(settings); + } + + @Override + @Environment(EnvType.CLIENT) + protected Optional createBlockPattern(ResourceLocation blockId) { + String name = blockId.getPath(); + return Optional.of(PATTERN.replace("name", name)); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/PedestalBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/PedestalBlock.java new file mode 100644 index 00000000..69239cf0 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/PedestalBlock.java @@ -0,0 +1,471 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.BaseBlockNotFull; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.client.models.ModelsHelper; +import org.betterx.betterend.blocks.EndBlockProperties; +import org.betterx.betterend.blocks.EndBlockProperties.PedestalState; +import org.betterx.betterend.blocks.InfusionPedestal; +import org.betterx.betterend.blocks.entities.InfusionPedestalEntity; +import org.betterx.betterend.blocks.entities.PedestalBlockEntity; +import org.betterx.betterend.client.models.Patterns; +import org.betterx.betterend.rituals.InfusionRitual; + +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.BlockTags; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.awt.*; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.ToIntFunction; +import org.jetbrains.annotations.Nullable; + +public class PedestalBlock extends BaseBlockNotFull implements EntityBlock { + public final static EnumProperty STATE = EndBlockProperties.PEDESTAL_STATE; + public static final BooleanProperty HAS_ITEM = EndBlockProperties.HAS_ITEM; + public static final BooleanProperty HAS_LIGHT = BlockProperties.HAS_LIGHT; + + private static final VoxelShape SHAPE_DEFAULT; + private static final VoxelShape SHAPE_COLUMN; + private static final VoxelShape SHAPE_PILLAR; + private static final VoxelShape SHAPE_PEDESTAL_TOP; + private static final VoxelShape SHAPE_COLUMN_TOP; + private static final VoxelShape SHAPE_BOTTOM; + + protected final Block parent; + protected float height = 1.0F; + + public PedestalBlock(Block parent) { + super(FabricBlockSettings.copyOf(parent).luminance(getLuminance(parent.defaultBlockState()))); + this.registerDefaultState( + stateDefinition + .any() + .setValue(STATE, PedestalState.DEFAULT) + .setValue(HAS_ITEM, false) + .setValue(HAS_LIGHT, false) + ); + this.parent = parent; + } + + private static ToIntFunction getLuminance(BlockState parent) { + final int light = parent.getLightEmission(); + if (light > 0) { + return state -> light; + } + return state -> state.getValue(HAS_LIGHT) ? 12 : 0; + } + + public float getHeight(BlockState state) { + if (state.getBlock() instanceof PedestalBlock && state.getValue(STATE) == PedestalState.PEDESTAL_TOP) { + return this.height - 0.2F; + } + return this.height; + } + + @Override + @SuppressWarnings("deprecation") + public InteractionResult use( + BlockState state, + Level level, + BlockPos pos, + Player player, + InteractionHand hand, + BlockHitResult hit + ) { + if (!state.is(this) || !isPlaceable(state)) { + return InteractionResult.PASS; + } + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof PedestalBlockEntity) { + PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity; + if (pedestal.isEmpty()) { + ItemStack itemStack = player.getItemInHand(hand); + if (itemStack.isEmpty()) return InteractionResult.CONSUME; + pedestal.setItem(0, itemStack); + level.blockEntityChanged(pos); + checkRitual(level, player, pos); + return InteractionResult.sidedSuccess(level.isClientSide()); + } else { + ItemStack itemStack = pedestal.getItem(0); + if (player.addItem(itemStack)) { + pedestal.removeItemNoUpdate(0); + level.blockEntityChanged(pos); + checkRitual(level, player, pos); + return InteractionResult.sidedSuccess(level.isClientSide()); + } + return InteractionResult.FAIL; + } + } + return InteractionResult.PASS; + } + + @Override + public void destroy(LevelAccessor levelAccessor, BlockPos blockPos, BlockState blockState) { + MutableBlockPos posMutable = new MutableBlockPos(); + for (Point point : InfusionRitual.getMap()) { + posMutable.set(blockPos).move(point.x, 0, point.y); + BlockState state = levelAccessor.getBlockState(posMutable); + if (state.getBlock() instanceof InfusionPedestal) { + BlockEntity blockEntity = levelAccessor.getBlockEntity(posMutable); + if (blockEntity instanceof InfusionPedestalEntity) { + InfusionPedestalEntity pedestal = (InfusionPedestalEntity) blockEntity; + if (pedestal.hasRitual()) { + pedestal.getRitual().setDirty(); + } + } + break; + } + } + } + + public void checkRitual(Level world, Player player, BlockPos pos) { + MutableBlockPos posMutable = new MutableBlockPos(); + for (Point point : InfusionRitual.getMap()) { + posMutable.set(pos).move(point.x, 0, point.y); + BlockState state = world.getBlockState(posMutable); + if (state.getBlock() instanceof InfusionPedestal) { + ((InfusionPedestal) state.getBlock()).checkRitual(world, player, posMutable); + break; + } + } + } + + @Override + @Nullable + public BlockState getStateForPlacement(BlockPlaceContext context) { + Level world = context.getLevel(); + BlockPos pos = context.getClickedPos(); + BlockState upState = world.getBlockState(pos.above()); + BlockState downState = world.getBlockState(pos.below()); + boolean upSideSolid = upState.isFaceSturdy(world, pos.above(), Direction.DOWN) || upState.is(BlockTags.WALLS); + boolean hasPedestalOver = upState.getBlock() instanceof PedestalBlock; + boolean hasPedestalUnder = downState.getBlock() instanceof PedestalBlock; + if (!hasPedestalOver && hasPedestalUnder && upSideSolid) { + return defaultBlockState().setValue(STATE, PedestalState.COLUMN_TOP); + } else if (!hasPedestalOver && !hasPedestalUnder && upSideSolid) { + return defaultBlockState().setValue(STATE, PedestalState.COLUMN); + } else if (hasPedestalUnder && hasPedestalOver) { + return defaultBlockState().setValue(STATE, PedestalState.PILLAR); + } else if (hasPedestalUnder) { + return defaultBlockState().setValue(STATE, PedestalState.PEDESTAL_TOP); + } else if (hasPedestalOver) { + return defaultBlockState().setValue(STATE, PedestalState.BOTTOM); + } + return defaultBlockState(); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState updateShape( + BlockState state, + Direction direction, + BlockState newState, + LevelAccessor world, + BlockPos pos, + BlockPos posFrom + ) { + BlockState updated = getUpdatedState(state, direction, newState, world, pos, posFrom); + if (!updated.is(this)) return updated; + if (!isPlaceable(updated)) { + moveStoredStack(world, updated, pos); + } + return updated; + } + + private BlockState getUpdatedState( + BlockState state, + Direction direction, + BlockState newState, + LevelAccessor world, + BlockPos pos, + BlockPos posFrom + ) { + if (!state.is(this)) return state.updateShape(direction, newState, world, pos, posFrom); + if (direction != Direction.UP && direction != Direction.DOWN) return state; + BlockState upState = world.getBlockState(pos.above()); + BlockState downState = world.getBlockState(pos.below()); + boolean upSideSolid = upState.isFaceSturdy(world, pos.above(), Direction.DOWN) || upState.is(BlockTags.WALLS); + boolean hasPedestalOver = upState.getBlock() instanceof PedestalBlock; + boolean hasPedestalUnder = downState.getBlock() instanceof PedestalBlock; + if (direction == Direction.UP) { + upSideSolid = newState.isFaceSturdy(world, posFrom, Direction.DOWN) || newState.is(BlockTags.WALLS); + hasPedestalOver = newState.getBlock() instanceof PedestalBlock; + } else { + hasPedestalUnder = newState.getBlock() instanceof PedestalBlock; + } + BlockState updatedState; + if (!hasPedestalOver && hasPedestalUnder && upSideSolid) { + updatedState = state.setValue(STATE, PedestalState.COLUMN_TOP); + } else if (!hasPedestalOver && !hasPedestalUnder && upSideSolid) { + updatedState = state.setValue(STATE, PedestalState.COLUMN); + } else if (hasPedestalUnder && hasPedestalOver) { + updatedState = state.setValue(STATE, PedestalState.PILLAR); + } else if (hasPedestalUnder) { + updatedState = state.setValue(STATE, PedestalState.PEDESTAL_TOP); + } else if (hasPedestalOver) { + updatedState = state.setValue(STATE, PedestalState.BOTTOM); + } else { + updatedState = state.setValue(STATE, PedestalState.DEFAULT); + } + if (!isPlaceable(updatedState)) { + updatedState = updatedState.setValue(HAS_ITEM, false).setValue(HAS_LIGHT, false); + } + return updatedState; + } + + @Override + public List getDrops(BlockState state, LootContext.Builder builder) { + List drop = Lists.newArrayList(super.getDrops(state, builder)); + if (state.is(this)) { + if (isPlaceable(state)) { + BlockEntity blockEntity = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY); + if (blockEntity instanceof PedestalBlockEntity) { + PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity; + if (!pedestal.isEmpty()) { + drop.add(pedestal.getItem(0)); + } + } + } else { + return drop; + } + } + return drop; + } + + private void moveStoredStack(LevelAccessor world, BlockState state, BlockPos pos) { + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof PedestalBlockEntity && state.is(this)) { + PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity; + ItemStack stack = pedestal.removeItemNoUpdate(0); + if (!stack.isEmpty()) { + moveStoredStack(blockEntity, world, stack, pos.above()); + } + } + } + + private void moveStoredStack(BlockEntity blockEntity, LevelAccessor world, ItemStack stack, BlockPos pos) { + BlockState state = world.getBlockState(pos); + if (!state.is(this)) { + dropStoredStack(blockEntity, stack, pos); + } else if (state.getValue(STATE).equals(PedestalState.PILLAR)) { + moveStoredStack(blockEntity, world, stack, pos.above()); + } else if (!isPlaceable(state)) { + dropStoredStack(blockEntity, stack, pos); + } else if (blockEntity instanceof PedestalBlockEntity) { + PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity; + if (pedestal.isEmpty()) { + pedestal.setItem(0, stack); + } else { + dropStoredStack(blockEntity, stack, pos); + } + } else { + dropStoredStack(blockEntity, stack, pos); + } + } + + private void dropStoredStack(BlockEntity blockEntity, ItemStack stack, BlockPos pos) { + if (blockEntity != null && blockEntity.getLevel() != null) { + Level world = blockEntity.getLevel(); + Block.popResource(world, getDropPos(world, pos), stack); + } + } + + private BlockPos getDropPos(LevelAccessor world, BlockPos pos) { + BlockPos dropPos; + if (world.getBlockState(pos).isAir()) { + return pos; + } + if (world.getBlockState(pos.above()).isAir()) { + return pos.above(); + } + for (int i = 2; i < Direction.values().length; i++) { + dropPos = pos.relative(Direction.from3DDataValue(i)); + if (world.getBlockState(dropPos).isAir()) { + return dropPos.immutable(); + } + } + return getDropPos(world, pos.above()); + } + + public boolean isPlaceable(BlockState state) { + if (!state.is(this)) return false; + PedestalState currentState = state.getValue(STATE); + return currentState == PedestalState.DEFAULT || currentState == PedestalState.PEDESTAL_TOP; + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + if (state.is(this)) { + switch (state.getValue(STATE)) { + case BOTTOM: { + return SHAPE_BOTTOM; + } + case PEDESTAL_TOP: { + return SHAPE_PEDESTAL_TOP; + } + case COLUMN_TOP: { + return SHAPE_COLUMN_TOP; + } + case PILLAR: { + return SHAPE_PILLAR; + } + case COLUMN: { + return SHAPE_COLUMN; + } + default: { + return SHAPE_DEFAULT; + } + } + } + return super.getShape(state, world, pos, context); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(STATE, HAS_ITEM, HAS_LIGHT); + } + + @Override + public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { + return new PedestalBlockEntity(blockPos, blockState); + } + + public boolean hasUniqueEntity() { + return false; + } + + @Override + @SuppressWarnings("deprecation") + public boolean hasAnalogOutputSignal(BlockState state) { + return state.getBlock() instanceof PedestalBlock; + } + + @Override + @SuppressWarnings("deprecation") + public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) { + return state.getValue(HAS_ITEM) ? 15 : 0; + } + + @Override + @Environment(EnvType.CLIENT) + public BlockModel getItemModel(ResourceLocation blockId) { + return getBlockModel(blockId, defaultBlockState()); + } + + @Override + @Environment(EnvType.CLIENT) + public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { + Map textures = createTexturesMap(); + PedestalState state = blockState.getValue(STATE); + Optional pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_DEFAULT, textures); + switch (state) { + case COLUMN_TOP: + pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_COLUMN_TOP, textures); + break; + case COLUMN: + pattern = Patterns.createJson(Patterns.BLOKC_PEDESTAL_COLUMN, textures); + break; + case PEDESTAL_TOP: + pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_TOP, textures); + break; + case BOTTOM: + pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_BOTTOM, textures); + break; + case PILLAR: + pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_PILLAR, textures); + break; + default: + break; + } + return ModelsHelper.fromPattern(pattern); + } + + @Override + @Environment(EnvType.CLIENT) + public UnbakedModel getModelVariant( + ResourceLocation stateId, + BlockState blockState, + Map modelCache + ) { + PedestalState state = blockState.getValue(STATE); + ResourceLocation modelId = new ResourceLocation( + stateId.getNamespace(), + "block/" + stateId.getPath() + "_" + state + ); + registerBlockModel(stateId, modelId, blockState, modelCache); + return ModelsHelper.createBlockSimple(modelId); + } + + protected Map createTexturesMap() { + ResourceLocation blockId = Registry.BLOCK.getKey(parent); + String name = blockId.getPath(); + Map textures = Maps.newHashMap(); + textures.put("%mod%", blockId.getNamespace()); + textures.put("%top%", name + "_top"); + textures.put("%base%", name + "_base"); + textures.put("%pillar%", name + "_pillar"); + textures.put("%bottom%", name + "_bottom"); + return textures; + } + + static { + VoxelShape basinUp = Block.box(2, 3, 2, 14, 4, 14); + VoxelShape basinDown = Block.box(0, 0, 0, 16, 3, 16); + VoxelShape columnTopUp = Block.box(1, 14, 1, 15, 16, 15); + VoxelShape columnTopDown = Block.box(2, 13, 2, 14, 14, 14); + VoxelShape pedestalTop = Block.box(1, 8, 1, 15, 10, 15); + VoxelShape pedestalDefault = Block.box(1, 12, 1, 15, 14, 15); + VoxelShape pillar = Block.box(3, 0, 3, 13, 8, 13); + VoxelShape pillarDefault = Block.box(3, 0, 3, 13, 12, 13); + VoxelShape columnTop = Shapes.or(columnTopDown, columnTopUp); + VoxelShape basin = Shapes.or(basinDown, basinUp); + SHAPE_PILLAR = Block.box(3, 0, 3, 13, 16, 13); + SHAPE_DEFAULT = Shapes.or(basin, pillarDefault, pedestalDefault); + SHAPE_PEDESTAL_TOP = Shapes.or(pillar, pedestalTop); + SHAPE_COLUMN_TOP = Shapes.or(SHAPE_PILLAR, columnTop); + SHAPE_COLUMN = Shapes.or(basin, SHAPE_PILLAR, columnTop); + SHAPE_BOTTOM = Shapes.or(basin, SHAPE_PILLAR); + } + + /*@Override + @Nullable + public BlockEntityTicker getTicker(Level level, BlockState blockState, BlockEntityType blockEntityType) { + return level.isClientSide() ? PedestalBlockEntity::tick : null; + }*/ +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/PottableCropBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/PottableCropBlock.java new file mode 100644 index 00000000..5f114ec0 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/PottableCropBlock.java @@ -0,0 +1,31 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.BaseCropBlock; +import org.betterx.betterend.interfaces.PottablePlant; + +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; + +public class PottableCropBlock extends BaseCropBlock implements PottablePlant { + private final Block[] terrain; + + public PottableCropBlock(Item drop, Block... terrain) { + super(drop, terrain); + this.terrain = terrain; + } + + @Override + public boolean canPlantOn(Block block) { + for (Block ter : terrain) { + if (block == ter) { + return true; + } + } + return false; + } + + @Override + public String getPottedState() { + return "age=3"; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/PottableFeatureSapling.java b/src/main/java/org/betterx/betterend/blocks/basis/PottableFeatureSapling.java new file mode 100644 index 00000000..1f8f4dfd --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/PottableFeatureSapling.java @@ -0,0 +1,18 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.FeatureSaplingBlock; +import org.betterx.betterend.interfaces.PottablePlant; + +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; + +public abstract class PottableFeatureSapling, FC extends FeatureConfiguration> extends FeatureSaplingBlock implements PottablePlant { + + public PottableFeatureSapling(FeatureSupplier featureSupplier) { + super(featureSupplier); + } + + public PottableFeatureSapling(int light, FeatureSupplier featureSupplier) { + super(light, featureSupplier); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/PottableLeavesBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/PottableLeavesBlock.java new file mode 100644 index 00000000..805b518f --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/PottableLeavesBlock.java @@ -0,0 +1,26 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.blocks.BaseLeavesBlock; +import org.betterx.betterend.interfaces.PottablePlant; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.material.MaterialColor; + +public class PottableLeavesBlock extends BaseLeavesBlock implements PottablePlant { + + public PottableLeavesBlock(Block sapling, MaterialColor color) { + super(sapling, color); + } + + public PottableLeavesBlock(Block sapling, MaterialColor color, int light) { + super(sapling, color, light); + } + + @Override + public boolean canPlantOn(Block block) { + if (sapling instanceof PottablePlant) { + return ((PottablePlant) sapling).canPlantOn(block); + } + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/basis/StoneLanternBlock.java b/src/main/java/org/betterx/betterend/blocks/basis/StoneLanternBlock.java new file mode 100644 index 00000000..0d7f6b20 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/basis/StoneLanternBlock.java @@ -0,0 +1,63 @@ +package org.betterx.betterend.blocks.basis; + +import org.betterx.bclib.client.models.ModelsHelper; +import org.betterx.bclib.interfaces.CustomColorProvider; +import org.betterx.betterend.client.models.Patterns; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.item.ItemColor; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import java.util.Optional; +import org.jetbrains.annotations.Nullable; + +public class StoneLanternBlock extends EndLanternBlock implements CustomColorProvider { + private static final VoxelShape SHAPE_CEIL = box(3, 1, 3, 13, 16, 13); + private static final VoxelShape SHAPE_FLOOR = box(3, 0, 3, 13, 15, 13); + + public StoneLanternBlock(Block source) { + super(FabricBlockSettings.copyOf(source).luminance(15)); + } + + @Override + public BlockColor getProvider() { + return ((CustomColorProvider) EndBlocks.AURORA_CRYSTAL).getProvider(); + } + + @Override + public ItemColor getItemProvider() { + return ((CustomColorProvider) EndBlocks.AURORA_CRYSTAL).getItemProvider(); + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + return state.getValue(IS_FLOOR) ? SHAPE_FLOOR : SHAPE_CEIL; + } + + @Override + @Environment(EnvType.CLIENT) + public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { + String blockName = resourceLocation.getPath(); + Optional pattern = blockState.getValue(IS_FLOOR) + ? Patterns.createJson( + Patterns.BLOCK_STONE_LANTERN_FLOOR, + blockName, + blockName + ) + : Patterns.createJson(Patterns.BLOCK_STONE_LANTERN_CEIL, blockName, blockName); + return ModelsHelper.fromPattern(pattern); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/entities/BlockEntityHydrothermalVent.java b/src/main/java/org/betterx/betterend/blocks/entities/BlockEntityHydrothermalVent.java new file mode 100644 index 00000000..336bca43 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/entities/BlockEntityHydrothermalVent.java @@ -0,0 +1,98 @@ +package org.betterx.betterend.blocks.entities; + +import org.betterx.betterend.blocks.HydrothermalVentBlock; +import org.betterx.betterend.registry.EndBlockEntities; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.betterend.util.GlobalState; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ElytraItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; + +import net.fabricmc.fabric.api.entity.event.v1.FabricElytraItem; + +import java.util.List; + +public class BlockEntityHydrothermalVent extends BlockEntity { + private final static Vec3 POSITIVE_Y = new Vec3(0.0f, 1.0f, 0.0f); + + public BlockEntityHydrothermalVent(BlockPos blockPos, BlockState blockState) { + super(EndBlockEntities.HYDROTHERMAL_VENT, blockPos, blockState); + } + + public static void tick( + Level level, + BlockPos worldPosition, + BlockState state, + T uncastedEntity + ) { + if (level != null && uncastedEntity instanceof BlockEntityHydrothermalVent && state.is(EndBlocks.HYDROTHERMAL_VENT)) { + BlockEntityHydrothermalVent blockEntity = (BlockEntityHydrothermalVent) uncastedEntity; + if (level.isClientSide()) { + clientTick(level, worldPosition, state, blockEntity); + } + //else { + serverTick(level, worldPosition, state, blockEntity); + //} + } + } + + private static void clientTick( + Level level, + BlockPos worldPosition, + BlockState state, + BlockEntityHydrothermalVent blockEntity + ) { + boolean active = state.getValue(HydrothermalVentBlock.ACTIVATED); + if (active && level.random.nextInt(20) == 0 && state.getValue(HydrothermalVentBlock.WATERLOGGED)) { + double x = worldPosition.getX() + level.random.nextDouble(); + double y = worldPosition.getY() + 0.9 + level.random.nextDouble() * 0.3; + double z = worldPosition.getZ() + level.random.nextDouble(); + level.addParticle(EndParticles.GEYSER_PARTICLE, x, y, z, 0, 0, 0); + } + } + + private static void serverTick( + Level level, + BlockPos worldPosition, + BlockState state, + BlockEntityHydrothermalVent blockEntity + ) { + final MutableBlockPos POS = GlobalState.stateForThread().POS; + boolean active = state.getValue(HydrothermalVentBlock.ACTIVATED); + POS.set(worldPosition).move(Direction.UP); + int height = active ? 85 : 25; + AABB box = new AABB(POS.offset(-1, 0, -1), POS.offset(1, height, 1)); + List entities = level.getEntitiesOfClass(LivingEntity.class, box); + if (entities.size() > 0) { + while (POS.getY() < box.maxY) { + BlockState blockState = level.getBlockState(POS); + if (blockState.isSolidRender(level, POS)) break; + if (blockState.isAir()) { + double mult = active ? 3.0 : 5.0; + float force = (float) ((1.0 - (POS.getY() / box.maxY)) / mult); + entities.stream() + .filter(entity -> (int) entity.getY() == POS.getY() && blockEntity.hasElytra(entity) && entity + .isFallFlying()) + .forEach(entity -> entity.moveRelative(force, POSITIVE_Y)); + } + POS.move(Direction.UP); + } + } + } + + private boolean hasElytra(LivingEntity entity) { + Item item = entity.getItemBySlot(EquipmentSlot.CHEST).getItem(); + return item instanceof ElytraItem /*|| item instanceof ElytraModelProvider*/ || item instanceof FabricElytraItem; + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/entities/EndStoneSmelterBlockEntity.java b/src/main/java/org/betterx/betterend/blocks/entities/EndStoneSmelterBlockEntity.java new file mode 100644 index 00000000..ae372e01 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/entities/EndStoneSmelterBlockEntity.java @@ -0,0 +1,493 @@ +package org.betterx.betterend.blocks.entities; + +import org.betterx.bclib.recipes.AlloyingRecipe; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.EndStoneSmelter; +import org.betterx.betterend.client.gui.EndStoneSmelterMenu; +import org.betterx.betterend.registry.EndBlockEntities; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.NonNullList; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import net.minecraft.world.ContainerHelper; +import net.minecraft.world.WorldlyContainer; +import net.minecraft.world.entity.ExperienceOrb; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.player.StackedContents; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ContainerData; +import net.minecraft.world.inventory.RecipeHolder; +import net.minecraft.world.inventory.StackedContentsCompatible; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.BlastingRecipe; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity; +import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; + +import net.fabricmc.fabric.api.registry.FuelRegistry; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class EndStoneSmelterBlockEntity extends BaseContainerBlockEntity implements WorldlyContainer, RecipeHolder, StackedContentsCompatible { + private static final int[] TOP_SLOTS = new int[]{ + EndStoneSmelterMenu.INGREDIENT_SLOT_A, + EndStoneSmelterMenu.INGREDIENT_SLOT_B + }; + private static final int[] JUST_A = new int[]{ + EndStoneSmelterMenu.INGREDIENT_SLOT_A, + }; + private static final int[] BOTTOM_SLOTS = new int[]{EndStoneSmelterMenu.FUEL_SLOT, EndStoneSmelterMenu.RESULT_SLOT}; + private static final int[] SIDE_SLOTS = new int[]{ + EndStoneSmelterMenu.FUEL_SLOT + }; + private static final Map AVAILABLE_FUELS = Maps.newHashMap(); + + private final Object2IntOpenHashMap recipesUsed; + protected NonNullList inventory; + protected final ContainerData propertyDelegate; + private Recipe lastRecipe; + private int smeltTimeTotal; + private int smeltTime; + private int burnTime; + private int fuelTime; + + public EndStoneSmelterBlockEntity(BlockPos blockPos, BlockState blockState) { + super(EndBlockEntities.END_STONE_SMELTER, blockPos, blockState); + this.inventory = NonNullList.withSize(EndStoneSmelterMenu.SLOT_COUNT, ItemStack.EMPTY); + this.recipesUsed = new Object2IntOpenHashMap<>(); + this.propertyDelegate = new ContainerData() { + public int get(int index) { + switch (index) { + case 0: + return EndStoneSmelterBlockEntity.this.burnTime; + case 1: + return EndStoneSmelterBlockEntity.this.fuelTime; + case 2: + return EndStoneSmelterBlockEntity.this.smeltTime; + case 3: + return EndStoneSmelterBlockEntity.this.smeltTimeTotal; + default: + return 0; + } + } + + public void set(int index, int value) { + switch (index) { + case 0: + EndStoneSmelterBlockEntity.this.burnTime = value; + break; + case 1: + EndStoneSmelterBlockEntity.this.fuelTime = value; + break; + case 2: + EndStoneSmelterBlockEntity.this.smeltTime = value; + break; + case 3: + EndStoneSmelterBlockEntity.this.smeltTimeTotal = value; + } + } + + public int getCount() { + return 4; + } + }; + } + + private boolean isBurning() { + return burnTime > 0; + } + + @Override + public int getContainerSize() { + return inventory.size(); + } + + @Override + public boolean isEmpty() { + Iterator iterator = inventory.iterator(); + ItemStack itemStack; + do { + if (!iterator.hasNext()) { + return true; + } + itemStack = iterator.next(); + } while (itemStack.isEmpty()); + + return false; + } + + @Override + public ItemStack getItem(int slot) { + return inventory.get(slot); + } + + @Override + public ItemStack removeItem(int slot, int amount) { + return ContainerHelper.removeItem(inventory, slot, amount); + } + + @Override + public ItemStack removeItemNoUpdate(int slot) { + return ContainerHelper.takeItem(inventory, slot); + } + + @Override + public void setItem(int slot, ItemStack stack) { + ItemStack itemStack = inventory.get(slot); + boolean stackValid = !stack.isEmpty() && stack.sameItem(itemStack) && ItemStack.tagMatches(stack, itemStack); + inventory.set(slot, stack); + if (stack.getCount() > getMaxStackSize()) { + stack.setCount(getMaxStackSize()); + } + if ((slot == EndStoneSmelterMenu.INGREDIENT_SLOT_A || slot == EndStoneSmelterMenu.INGREDIENT_SLOT_B) && !stackValid) { + smeltTimeTotal = getSmeltTime(); + smeltTime = 0; + setChanged(); + } + } + + protected int getSmeltTime() { + if (level == null) return 200; + int smeltTime = level.getRecipeManager() + .getRecipeFor(AlloyingRecipe.TYPE, this, level) + .map(AlloyingRecipe::getSmeltTime) + .orElse(0); + if (smeltTime == 0) { + smeltTime = level.getRecipeManager() + .getRecipeFor(RecipeType.BLASTING, this, level) + .map(BlastingRecipe::getCookingTime) + .orElse(200); + smeltTime /= 1.5; + } + return smeltTime; + } + + public void dropExperience(Player player) { + if (level == null) return; + List> list = Lists.newArrayList(); + for (Entry entry : recipesUsed.object2IntEntrySet()) { + level.getRecipeManager().byKey(entry.getKey()).ifPresent((recipe) -> { + list.add(recipe); + if (recipe instanceof AlloyingRecipe) { + AlloyingRecipe alloying = (AlloyingRecipe) recipe; + dropExperience(player.level, player.position(), entry.getIntValue(), alloying.getExperience()); + } else { + BlastingRecipe blasting = (BlastingRecipe) recipe; + dropExperience(player.level, player.position(), entry.getIntValue(), blasting.getExperience()); + } + }); + } + player.awardRecipes(list); + recipesUsed.clear(); + } + + private void dropExperience(Level world, Vec3 vec3d, int count, float amount) { + int expTotal = Mth.floor(count * amount); + float g = Mth.frac(count * amount); + if (g != 0.0F && Math.random() < g) { + expTotal++; + } + + while (expTotal > 0) { + int expVal = ExperienceOrb.getExperienceValue(expTotal); + expTotal -= expVal; + world.addFreshEntity(new ExperienceOrb(world, vec3d.x, vec3d.y, vec3d.z, expVal)); + } + } + + @Override + public boolean stillValid(Player player) { + if (level != null && level.getBlockEntity(worldPosition) != this) { + return false; + } + return player.distanceToSqr( + worldPosition.getX() + 0.5D, + worldPosition.getY() + 0.5D, + worldPosition.getZ() + 0.5D + ) <= 64.0D; + } + + @Override + public void clearContent() { + inventory.clear(); + } + + @Override + protected Component getDefaultName() { + return Component.translatable(String.format("block.%s.%s", BetterEnd.MOD_ID, EndStoneSmelter.ID)); + } + + @Override + protected AbstractContainerMenu createMenu(int syncId, Inventory playerInventory) { + return new EndStoneSmelterMenu(syncId, playerInventory, this, propertyDelegate); + } + + public static void tick( + Level tickLevel, + BlockPos tickPos, + BlockState tickState, + EndStoneSmelterBlockEntity blockEntity + ) { + if (tickLevel == null) return; + + boolean initialBurning = blockEntity.isBurning(); + if (initialBurning) { + blockEntity.burnTime--; + } + + boolean burning = initialBurning; + if (!tickLevel.isClientSide) { + ItemStack fuel = blockEntity.inventory.get(EndStoneSmelterMenu.FUEL_SLOT); + if (!burning && (fuel.isEmpty() + || blockEntity.inventory.get(EndStoneSmelterMenu.INGREDIENT_SLOT_A).isEmpty() + && blockEntity.inventory.get(EndStoneSmelterMenu.INGREDIENT_SLOT_B).isEmpty()) + ) { + if (blockEntity.smeltTime > 0) { + blockEntity.smeltTime = Mth.clamp(blockEntity.smeltTime - 2, 0, blockEntity.smeltTimeTotal); + } + } else { + Recipe recipe = tickLevel.getRecipeManager() + .getRecipeFor(AlloyingRecipe.TYPE, blockEntity, tickLevel) + .orElse(null); + if (recipe == null) { + recipe = tickLevel.getRecipeManager() + .getRecipeFor(RecipeType.BLASTING, blockEntity, tickLevel) + .orElse(null); + } + boolean accepted = blockEntity.canAcceptRecipeOutput(recipe); + if (!burning && accepted) { + blockEntity.burnTime = EndStoneSmelterBlockEntity.getFuelTime(fuel); + blockEntity.fuelTime = blockEntity.burnTime; + burning = blockEntity.isBurning(); + if (burning) { + if (!fuel.isEmpty()) { + Item item = fuel.getItem(); + fuel.shrink(1); + if (fuel.isEmpty()) { + Item remainFuel = item.getCraftingRemainingItem(); + blockEntity.inventory.set( + EndStoneSmelterMenu.FUEL_SLOT, + remainFuel == null ? ItemStack.EMPTY : new ItemStack(remainFuel) + ); + } + } + blockEntity.setChanged(); + } + } + + if (burning && accepted) { + blockEntity.smeltTime++; + if (blockEntity.smeltTime == blockEntity.smeltTimeTotal) { + blockEntity.smeltTime = 0; + blockEntity.smeltTimeTotal = blockEntity.getSmeltTime(); + blockEntity.craftRecipe(recipe); + blockEntity.setChanged(); + } + } else { + blockEntity.smeltTime = 0; + } + } + burning = blockEntity.isBurning(); + if (initialBurning != burning) { + tickLevel.setBlock(tickPos, tickState.setValue(EndStoneSmelter.LIT, burning), 3); + blockEntity.setChanged(); + } + } + } + + protected boolean canAcceptRecipeOutput(Recipe recipe) { + if (recipe == null) return false; + boolean validInput; + if (recipe instanceof AlloyingRecipe) { + validInput = !inventory.get(EndStoneSmelterMenu.INGREDIENT_SLOT_A).isEmpty() + && !inventory.get(EndStoneSmelterMenu.INGREDIENT_SLOT_B).isEmpty(); + } else { + validInput = !inventory.get(EndStoneSmelterMenu.INGREDIENT_SLOT_A).isEmpty() + || !inventory.get(EndStoneSmelterMenu.INGREDIENT_SLOT_B).isEmpty(); + } + if (validInput) { + ItemStack result = recipe.getResultItem(); + if (result.isEmpty()) { + return false; + } + ItemStack output = this.inventory.get(EndStoneSmelterMenu.RESULT_SLOT); + int outCount = output.getCount(); + int total = outCount + result.getCount(); + if (output.isEmpty()) { + return true; + } + if (!output.sameItem(result)) { + return false; + } + if (outCount < getMaxStackSize() && outCount < output.getMaxStackSize()) { + return getMaxStackSize() >= total; + } + return output.getCount() < result.getMaxStackSize(); + } + return false; + } + + private void craftRecipe(Recipe recipe) { + if (recipe == null || !canAcceptRecipeOutput(recipe)) return; + + ItemStack result = recipe.getResultItem(); + ItemStack output = inventory.get(EndStoneSmelterMenu.RESULT_SLOT); + if (output.isEmpty()) { + inventory.set(EndStoneSmelterMenu.RESULT_SLOT, result.copy()); + } else if (output.getItem() == result.getItem()) { + output.grow(result.getCount()); + } + + assert this.level != null; + if (!this.level.isClientSide) { + setRecipeUsed(recipe); + } + + if (recipe instanceof AlloyingRecipe) { + inventory.get(EndStoneSmelterMenu.INGREDIENT_SLOT_A).shrink(1); + inventory.get(EndStoneSmelterMenu.INGREDIENT_SLOT_B).shrink(1); + } else { + if (!inventory.get(EndStoneSmelterMenu.INGREDIENT_SLOT_A).isEmpty()) { + inventory.get(EndStoneSmelterMenu.INGREDIENT_SLOT_A).shrink(1); + } else { + inventory.get(EndStoneSmelterMenu.INGREDIENT_SLOT_B).shrink(1); + } + } + } + + @Override + public void fillStackedContents(StackedContents finder) { + for (ItemStack itemStack : this.inventory) { + finder.accountStack(itemStack); + } + } + + @Override + public void setRecipeUsed(Recipe recipe) { + if (recipe != null) { + ResourceLocation recipeId = recipe.getId(); + recipesUsed.addTo(recipeId, 1); + lastRecipe = recipe; + } + } + + @Override + public Recipe getRecipeUsed() { + return this.lastRecipe; + } + + @Override + public int[] getSlotsForFace(Direction side) { +// var facing = getBlockState().getValue(EndStoneSmelter.FACING); +// if (side == facing) return JUST_A; + return switch (side) { + case DOWN -> BOTTOM_SLOTS; + case UP -> TOP_SLOTS; + default -> SIDE_SLOTS; + }; + } + + @Override + public boolean canPlaceItemThroughFace(int slot, ItemStack stack, Direction dir) { + return this.canPlaceItem(slot, stack); + } + + @Override + public boolean canTakeItemThroughFace(int slot, ItemStack stack, Direction dir) { + if (dir == Direction.DOWN && slot == EndStoneSmelterMenu.FUEL_SLOT) { + return stack.getItem() == Items.BUCKET; + } + return true; + } + + public static int getFuelTime(ItemStack fuel) { + if (fuel.isEmpty()) { + return 0; + } + Item item = fuel.getItem(); + return AVAILABLE_FUELS.getOrDefault(item, getFabricFuel(fuel)); + } + + @Override + public void load(CompoundTag tag) { + super.load(tag); + inventory = NonNullList.withSize(getContainerSize(), ItemStack.EMPTY); + ContainerHelper.loadAllItems(tag, inventory); + burnTime = tag.getShort("BurnTime"); + fuelTime = tag.getShort("FuelTime"); + smeltTime = tag.getShort("SmeltTime"); + smeltTimeTotal = tag.getShort("SmeltTimeTotal"); + CompoundTag compoundTag = tag.getCompound("RecipesUsed"); + for (String id : compoundTag.getAllKeys()) { + recipesUsed.put(new ResourceLocation(id), compoundTag.getInt(id)); + } + } + + @Override + public void saveAdditional(CompoundTag tag) { + super.saveAdditional(tag); + + tag.putShort("BurnTime", (short) burnTime); + tag.putShort("FuelTime", (short) fuelTime); + tag.putShort("SmeltTime", (short) smeltTime); + tag.putShort("SmeltTimeTotal", (short) smeltTimeTotal); + ContainerHelper.saveAllItems(tag, inventory); + CompoundTag usedRecipes = new CompoundTag(); + recipesUsed.forEach((identifier, integer) -> usedRecipes.putInt(identifier.toString(), integer)); + tag.put("RecipesUsed", usedRecipes); + } + + public boolean canPlaceItem(int slot, ItemStack stack) { + if (slot == EndStoneSmelterMenu.RESULT_SLOT) { + return false; + } else if (slot != EndStoneSmelterMenu.FUEL_SLOT) { + return true; + } + ItemStack itemStack = this.inventory.get(EndStoneSmelterMenu.FUEL_SLOT); + return canUseAsFuel(stack) || stack.getItem() == Items.BUCKET && itemStack.getItem() != Items.BUCKET; + } + + public static boolean canUseAsFuel(ItemStack stack) { + return AVAILABLE_FUELS.containsKey(stack.getItem()) || getFabricFuel(stack) > 2000; + } + + public static void registerFuel(ItemLike fuel, int time) { + AVAILABLE_FUELS.put(fuel.asItem(), time); + } + + public static Map availableFuels() { + return AVAILABLE_FUELS; + } + + private static int getFabricFuel(ItemStack stack) { + Integer ticks = FuelRegistry.INSTANCE.get(stack.getItem()); + return ticks == null ? 0 : ticks; + } + + static { + AbstractFurnaceBlockEntity.getFuel().forEach((item, time) -> { + if (time >= 2000) { + registerFuel(item, time); + } + }); + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/entities/EternalPedestalEntity.java b/src/main/java/org/betterx/betterend/blocks/entities/EternalPedestalEntity.java new file mode 100644 index 00000000..9dd3bbc9 --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/entities/EternalPedestalEntity.java @@ -0,0 +1,54 @@ +package org.betterx.betterend.blocks.entities; + +import org.betterx.betterend.registry.EndBlockEntities; +import org.betterx.betterend.rituals.EternalRitual; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; + +public class EternalPedestalEntity extends PedestalBlockEntity { + private EternalRitual linkedRitual; + + public EternalPedestalEntity(BlockPos blockPos, BlockState blockState) { + super(EndBlockEntities.ETERNAL_PEDESTAL, blockPos, blockState); + } + + public boolean hasRitual() { + return linkedRitual != null; + } + + public void linkRitual(EternalRitual ritual) { + this.linkedRitual = ritual; + } + + public EternalRitual getRitual() { + return linkedRitual; + } + + @Override + public void setLevel(Level level) { + super.setLevel(level); + if (hasRitual()) { + linkedRitual.setWorld(level); + } + } + + @Override + public void saveAdditional(CompoundTag tag) { + if (hasRitual()) { + tag.put("ritual", linkedRitual.toTag(new CompoundTag())); + } + super.saveAdditional(tag); + } + + @Override + protected void fromTag(CompoundTag tag) { + super.fromTag(tag); + if (tag.contains("ritual")) { + linkedRitual = new EternalRitual(level); + linkedRitual.fromTag(tag.getCompound("ritual")); + } + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/entities/InfusionPedestalEntity.java b/src/main/java/org/betterx/betterend/blocks/entities/InfusionPedestalEntity.java new file mode 100644 index 00000000..bc1d952e --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/entities/InfusionPedestalEntity.java @@ -0,0 +1,75 @@ +package org.betterx.betterend.blocks.entities; + +import org.betterx.betterend.registry.EndBlockEntities; +import org.betterx.betterend.rituals.InfusionRitual; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; + +public class InfusionPedestalEntity extends PedestalBlockEntity { + private InfusionRitual linkedRitual; + + public InfusionPedestalEntity(BlockPos blockPos, BlockState blockState) { + super(EndBlockEntities.INFUSION_PEDESTAL, blockPos, blockState); + } + + @Override + public void setLevel(Level world) { + super.setLevel(world); + if (hasRitual()) { + linkedRitual.setLocation(world, this.getBlockPos()); + } else { + linkRitual(this, world, this.getBlockPos()); + } + } + + public InfusionRitual linkRitual(InfusionPedestalEntity pedestal, Level world, BlockPos pos) { + linkedRitual = new InfusionRitual(pedestal, world, pos); + linkedRitual.configure(); + return linkedRitual; + } + + public InfusionRitual getRitual() { + return linkedRitual; + } + + public boolean hasRitual() { + return linkedRitual != null; + } + + @Override + public void saveAdditional(CompoundTag tag) { + if (hasRitual()) { + tag.put("ritual", linkedRitual.toTag(new CompoundTag())); + } + super.saveAdditional(tag); + } + + @Override + protected void fromTag(CompoundTag tag) { + super.fromTag(tag); + if (tag.contains("ritual")) { + linkedRitual = new InfusionRitual(this, level, worldPosition); + linkedRitual.fromTag(tag.getCompound("ritual")); + linkedRitual.configure(); + } + } + + public static void tickEnity( + Level level, + BlockPos blockPos, + BlockState blockState, + T uncastedEntity + ) { + if (uncastedEntity instanceof InfusionPedestalEntity) { + InfusionPedestalEntity blockEntity = (InfusionPedestalEntity) uncastedEntity; + if (blockEntity.hasRitual()) { + blockEntity.linkedRitual.tick(); + } + //PedestalBlockEntity.tick(level, blockPos, blockState, blockEntity); + } + } +} diff --git a/src/main/java/org/betterx/betterend/blocks/entities/PedestalBlockEntity.java b/src/main/java/org/betterx/betterend/blocks/entities/PedestalBlockEntity.java new file mode 100644 index 00000000..a9b9d0cc --- /dev/null +++ b/src/main/java/org/betterx/betterend/blocks/entities/PedestalBlockEntity.java @@ -0,0 +1,125 @@ +package org.betterx.betterend.blocks.entities; + +import org.betterx.betterend.blocks.basis.PedestalBlock; +import org.betterx.betterend.registry.EndBlockEntities; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.world.Container; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class PedestalBlockEntity extends BlockEntity implements Container { + private ItemStack activeItem = ItemStack.EMPTY; + + public PedestalBlockEntity(BlockPos blockPos, BlockState blockState) { + this(EndBlockEntities.PEDESTAL, blockPos, blockState); + } + + public PedestalBlockEntity(BlockEntityType blockEntityType, BlockPos blockPos, BlockState blockState) { + super(blockEntityType, blockPos, blockState); + } + + protected void toTag(CompoundTag tag) { + if (activeItem != ItemStack.EMPTY) { + tag.put("active_item", activeItem.save(new CompoundTag())); + } + } + + protected void fromTag(CompoundTag tag) { + if (tag.contains("active_item")) { + CompoundTag itemTag = tag.getCompound("active_item"); + activeItem = ItemStack.of(itemTag); + } + } + + @Override + public int getContainerSize() { + return 1; + } + + @Override + public boolean isEmpty() { + return activeItem.isEmpty(); + } + + @Override + public ItemStack getItem(int slot) { + return activeItem; + } + + @Override + public ItemStack removeItem(int slot, int amount) { + return removeItemNoUpdate(slot); + } + + @Override + public boolean canPlaceItem(int slot, ItemStack stack) { + return isEmpty(); + } + + @Override + public void clearContent() { + activeItem = ItemStack.EMPTY; + setChanged(); + } + + @Override + public ItemStack removeItemNoUpdate(int slot) { + ItemStack stored = activeItem; + clearContent(); + return stored; + } + + @Override + public void setItem(int slot, ItemStack stack) { + activeItem = stack.split(1); + setChanged(); + } + + @Override + public void setChanged() { + if (level != null && !level.isClientSide()) { + BlockState state = level.getBlockState(worldPosition); + if (state.getBlock() instanceof PedestalBlock) { + state = state.setValue(PedestalBlock.HAS_ITEM, !isEmpty()); + state = state.setValue(PedestalBlock.HAS_LIGHT, activeItem.getItem() == EndItems.ETERNAL_CRYSTAL); + } + level.setBlockAndUpdate(worldPosition, state); + level.blockEntityChanged(worldPosition); + } + super.setChanged(); + } + + @Override + public boolean stillValid(Player player) { + return true; + } + + @Override + public void load(CompoundTag tag) { + super.load(tag); + fromTag(tag); + } + + @Override + protected void saveAdditional(CompoundTag tag) { + super.saveAdditional(tag); + toTag(tag); + } + + @Override + public ClientboundBlockEntityDataPacket getUpdatePacket() { + return ClientboundBlockEntityDataPacket.create(this); + } + + @Override + public CompoundTag getUpdateTag() { + return this.saveWithoutMetadata(); + } +} diff --git a/src/main/java/org/betterx/betterend/client/BetterEndClient.java b/src/main/java/org/betterx/betterend/client/BetterEndClient.java new file mode 100644 index 00000000..ee948a2c --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/BetterEndClient.java @@ -0,0 +1,83 @@ +package org.betterx.betterend.client; + +import org.betterx.bclib.BCLib; +import org.betterx.bclib.util.TranslationHelper; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.client.render.BetterEndSkyRenderer; +import org.betterx.betterend.events.ItemTooltipCallback; +import org.betterx.betterend.interfaces.MultiModelItem; +import org.betterx.betterend.item.CrystaliteArmor; +import org.betterx.betterend.registry.*; +import org.betterx.betterend.world.generator.GeneratorOptions; + +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.Style; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.Level; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry; +import net.fabricmc.fabric.api.client.rendering.v1.DimensionRenderingRegistry; + +public class BetterEndClient implements ClientModInitializer { + @Override + public void onInitializeClient() { + EndBlockEntityRenders.register(); + EndScreens.register(); + EndParticles.register(); + EndEntitiesRenders.register(); + EndModelProviders.register(); + MultiModelItem.register(); + ClientOptions.init(); + registerTooltips(); + + if (BCLib.isDevEnvironment()) { + TranslationHelper.printMissingEnNames(BetterEnd.MOD_ID); + TranslationHelper.printMissingNames(BetterEnd.MOD_ID, "ru_ru"); + } + + ResourceLocation checkFlowerId = new ResourceLocation("item/chorus_flower"); + ResourceLocation checkPlantId = new ResourceLocation("item/chorus_plant"); + ResourceLocation toLoadFlowerId = new ResourceLocation("betterend", "item/custom_chorus_flower"); + ResourceLocation toLoadPlantId = new ResourceLocation("betterend", "item/custom_chorus_plant"); + ModelLoadingRegistry.INSTANCE.registerResourceProvider(manager -> (resourceId, context) -> { + if (GeneratorOptions.changeChorusPlant()) { + if (resourceId.equals(checkFlowerId)) { + return context.loadModel(toLoadFlowerId); + } else if (resourceId.equals(checkPlantId)) { + return context.loadModel(toLoadPlantId); + } + } + return null; + }); + + if (ClientOptions.isCustomSky()) { + DimensionRenderingRegistry.registerSkyRenderer(Level.END, new BetterEndSkyRenderer()); + } + + if (BetterEnd.RUNS_TRINKETS) { + org.betterx.betterend.integration.trinkets.ElytraClient.register(); + } + } + + public static void registerTooltips() { + ItemTooltipCallback.EVENT.register((player, stack, context, lines) -> { + if (stack.getItem() instanceof CrystaliteArmor) { + boolean hasSet = false; + if (player != null) { + hasSet = CrystaliteArmor.hasFullSet(player); + } + MutableComponent setDesc = Component.translatable("tooltip.armor.crystalite_set"); + + setDesc.setStyle(Style.EMPTY.applyFormats( + hasSet ? ChatFormatting.BLUE : ChatFormatting.DARK_GRAY, + ChatFormatting.ITALIC + )); + lines.add(Component.empty()); + lines.add(setDesc); + } + }); + } +} diff --git a/src/main/java/org/betterx/betterend/client/ClientOptions.java b/src/main/java/org/betterx/betterend/client/ClientOptions.java new file mode 100644 index 00000000..3443883f --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/ClientOptions.java @@ -0,0 +1,50 @@ +package org.betterx.betterend.client; + +import org.betterx.betterend.config.Configs; + +public class ClientOptions { + private static boolean customSky; + private static boolean useFogDensity; + private static boolean blendBiomeMusic; + private static boolean sulfurWaterColor; + + public static void init() { + customSky = Configs.CLENT_CONFIG.getBooleanRoot("customSky", true); + useFogDensity = Configs.CLENT_CONFIG.getBooleanRoot("useFogDensity", true); + blendBiomeMusic = Configs.CLENT_CONFIG.getBooleanRoot("blendBiomeMusic", true); + sulfurWaterColor = Configs.CLENT_CONFIG.getBooleanRoot("sulfurWaterColor", true); + Configs.CLENT_CONFIG.saveChanges(); + } + + public static boolean isCustomSky() { + return customSky; + } + + public static void setCustomSky(boolean customSky) { + ClientOptions.customSky = customSky; + } + + public static boolean useFogDensity() { + return useFogDensity; + } + + public static void setUseFogDensity(boolean useFogDensity) { + ClientOptions.useFogDensity = useFogDensity; + } + + public static boolean blendBiomeMusic() { + return blendBiomeMusic; + } + + public static void setBlendBiomeMusic(boolean blendBiomeMusic) { + ClientOptions.blendBiomeMusic = blendBiomeMusic; + } + + public static boolean useSulfurWaterColor() { + return sulfurWaterColor; + } + + public static void setSulfurWaterColor(boolean sulfurWaterColor) { + ClientOptions.sulfurWaterColor = sulfurWaterColor; + } +} diff --git a/src/main/java/org/betterx/betterend/client/gui/EndStoneSmelterMenu.java b/src/main/java/org/betterx/betterend/client/gui/EndStoneSmelterMenu.java new file mode 100644 index 00000000..485f8a1a --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/gui/EndStoneSmelterMenu.java @@ -0,0 +1,205 @@ +package org.betterx.betterend.client.gui; + +import org.betterx.bclib.recipes.AlloyingRecipe; +import org.betterx.betterend.blocks.entities.EndStoneSmelterBlockEntity; +import org.betterx.betterend.client.gui.slot.SmelterFuelSlot; +import org.betterx.betterend.client.gui.slot.SmelterOutputSlot; +import org.betterx.betterend.registry.EndMenuTypes; + +import net.minecraft.world.Container; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.player.StackedContents; +import net.minecraft.world.inventory.*; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.level.Level; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import org.anti_ad.mc.ipn.api.IPNIgnore; + +@IPNIgnore +public class EndStoneSmelterMenu extends RecipeBookMenu { + public static final int INGREDIENT_SLOT_A = 0; + public static final int INGREDIENT_SLOT_B = 1; + public static final int FUEL_SLOT = 2; + public static final int RESULT_SLOT = 3; + + public static final int SLOT_COUNT = 4; + private static final int INV_SLOT_START = SLOT_COUNT; + private static final int INV_SLOT_END = INV_SLOT_START + 3 * 9; + private static final int USE_ROW_SLOT_START = INV_SLOT_END; + private static final int USE_ROW_SLOT_END = USE_ROW_SLOT_START + 9; + + private final Container inventory; + private final ContainerData propertyDelegate; + protected final Level world; + + public EndStoneSmelterMenu(int syncId, Inventory playerInventory) { + this(syncId, playerInventory, new SimpleContainer(SLOT_COUNT), new SimpleContainerData(4)); + } + + public EndStoneSmelterMenu( + int syncId, + Inventory playerInventory, + Container inventory, + ContainerData propertyDelegate + ) { + super(EndMenuTypes.END_STONE_SMELTER, syncId); + this.inventory = inventory; + this.propertyDelegate = propertyDelegate; + this.world = playerInventory.player.level; + + addDataSlots(propertyDelegate); + addSlot(new Slot(inventory, INGREDIENT_SLOT_A, 45, 17)); + addSlot(new Slot(inventory, INGREDIENT_SLOT_B, 67, 17)); + addSlot(new SmelterFuelSlot(this, inventory, FUEL_SLOT, 56, 53)); + addSlot(new SmelterOutputSlot(playerInventory.player, inventory, RESULT_SLOT, 129, 35)); + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + } + } + for (int i = 0; i < 9; ++i) { + addSlot(new Slot(playerInventory, i, 8 + i * 18, 142)); + } + } + + @Override + public MenuType getType() { + return EndMenuTypes.END_STONE_SMELTER; + } + + @Override + public void fillCraftSlotsStackedContents(StackedContents finder) { + if (inventory instanceof StackedContentsCompatible) { + ((StackedContentsCompatible) inventory).fillStackedContents(finder); + } + } + + @Override + public void clearCraftingContent() { + this.getSlot(INGREDIENT_SLOT_A).set(ItemStack.EMPTY); + this.getSlot(INGREDIENT_SLOT_B).set(ItemStack.EMPTY); + this.getSlot(RESULT_SLOT).set(ItemStack.EMPTY); + } + + @Override + public boolean recipeMatches(Recipe recipe) { + return recipe.matches(inventory, world); + } + + @Override + public int getResultSlotIndex() { + return RESULT_SLOT; + } + + @Override + public int getGridWidth() { + return 2; + } + + @Override + public int getGridHeight() { + return 1; + } + + @Override + public int getSize() { + return SLOT_COUNT; + } + + @Override + public RecipeBookType getRecipeBookType() { + return RecipeBookType.BLAST_FURNACE; + } + + @Override + public boolean shouldMoveToInventory(int i) { + return i != FUEL_SLOT; + } + + @Override + public boolean stillValid(Player player) { + return inventory.stillValid(player); + } + + protected boolean isSmeltable(ItemStack itemStack) { + return world.getRecipeManager() + .getRecipeFor(AlloyingRecipe.TYPE, new SimpleContainer(itemStack), world) + .isPresent(); + } + + public boolean isFuel(ItemStack itemStack) { + return EndStoneSmelterBlockEntity.canUseAsFuel(itemStack); + } + + @Override + public ItemStack quickMoveStack(Player player, int index) { + Slot slot = slots.get(index); + if (slot == null || !slot.hasItem()) return ItemStack.EMPTY; + + ItemStack slotStack = slot.getItem(); + ItemStack itemStack = slotStack.copy(); + if (index == RESULT_SLOT) { + if (!moveItemStackTo(slotStack, INV_SLOT_START, USE_ROW_SLOT_END, true)) { + return ItemStack.EMPTY; + } + slot.onQuickCraft(slotStack, itemStack); + } else if (((index == FUEL_SLOT) || (index == INGREDIENT_SLOT_A) || (index == INGREDIENT_SLOT_B)) + ? !this.moveItemStackTo(slotStack, USE_ROW_SLOT_START, USE_ROW_SLOT_END, false) + : (this.isSmeltable(slotStack) + ? !this.moveItemStackTo(slotStack, INGREDIENT_SLOT_A, FUEL_SLOT, false) + : (this.isFuel(slotStack) + ? !this.moveItemStackTo(slotStack, FUEL_SLOT, RESULT_SLOT, false) + : (((index >= INV_SLOT_START) && (index < INV_SLOT_END)) + ? !this.moveItemStackTo(slotStack, USE_ROW_SLOT_START, USE_ROW_SLOT_END, false) + : ((index >= USE_ROW_SLOT_START) && (index < USE_ROW_SLOT_END) && !this.moveItemStackTo( + slotStack, + INV_SLOT_START, + INV_SLOT_END, + false + )))))) { + return ItemStack.EMPTY; + } + + if (slotStack.isEmpty()) { + slot.set(ItemStack.EMPTY); + } else { + slot.setChanged(); + } + + if (slotStack.getCount() == itemStack.getCount()) { + return ItemStack.EMPTY; + } + + slot.onTake(player, slotStack); + + return itemStack; + } + + @Environment(EnvType.CLIENT) + public int getSmeltProgress() { + int time = propertyDelegate.get(2); + int timeTotal = propertyDelegate.get(3); + return timeTotal != 0 && time != 0 ? time * 24 / timeTotal : 0; + } + + @Environment(EnvType.CLIENT) + public int getFuelProgress() { + int fuelTime = propertyDelegate.get(1); + if (fuelTime == 0) { + fuelTime = 200; + } + return propertyDelegate.get(0) * 13 / fuelTime; + } + + @Environment(EnvType.CLIENT) + public boolean isBurning() { + return propertyDelegate.get(0) > 0; + } +} diff --git a/src/main/java/org/betterx/betterend/client/gui/EndStoneSmelterRecipeBookScreen.java b/src/main/java/org/betterx/betterend/client/gui/EndStoneSmelterRecipeBookScreen.java new file mode 100644 index 00000000..feb0905f --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/gui/EndStoneSmelterRecipeBookScreen.java @@ -0,0 +1,66 @@ +package org.betterx.betterend.client.gui; + +import org.betterx.betterend.blocks.entities.EndStoneSmelterBlockEntity; + +import net.minecraft.client.gui.screens.recipebook.BlastingRecipeBookComponent; +import net.minecraft.core.NonNullList; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +@Environment(EnvType.CLIENT) +public class EndStoneSmelterRecipeBookScreen extends BlastingRecipeBookComponent { + private Ingredient fuels; + private Slot fuelSlot; + + @Override + protected Set getFuelItems() { + return EndStoneSmelterBlockEntity.availableFuels().keySet(); + } + + @Override + public void slotClicked(Slot slot) { + super.slotClicked(slot); + if (slot != null && slot.index < this.menu.getSize()) { + this.fuelSlot = null; + } + } + + @Override + public void setupGhostRecipe(Recipe recipe, List slots) { + this.ghostRecipe.clear(); + ItemStack result = recipe.getResultItem(); + this.ghostRecipe.setRecipe(recipe); + this.ghostRecipe.addIngredient(Ingredient.of(result), (slots.get(3)).x, (slots.get(3)).y); + NonNullList inputs = recipe.getIngredients(); + + this.fuelSlot = slots.get(2); + if (fuelSlot.getItem().isEmpty()) { + if (this.fuels == null) { + this.fuels = Ingredient.of(this.getFuelItems().stream().map(ItemStack::new)); + } + this.ghostRecipe.addIngredient(this.fuels, fuelSlot.x, fuelSlot.y); + } + + Iterator iterator = inputs.iterator(); + for (int i = 0; i < 2; i++) { + if (!iterator.hasNext()) { + return; + } + Ingredient ingredient = iterator.next(); + if (!ingredient.isEmpty()) { + Slot slot = slots.get(i); + this.ghostRecipe.addIngredient(ingredient, slot.x, slot.y); + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/client/gui/EndStoneSmelterScreen.java b/src/main/java/org/betterx/betterend/client/gui/EndStoneSmelterScreen.java new file mode 100644 index 00000000..81432380 --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/gui/EndStoneSmelterScreen.java @@ -0,0 +1,148 @@ +package org.betterx.betterend.client.gui; + +import org.betterx.betterend.BetterEnd; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.gui.components.ImageButton; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; +import net.minecraft.client.gui.screens.recipebook.RecipeUpdateListener; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.inventory.Slot; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class EndStoneSmelterScreen extends AbstractContainerScreen implements RecipeUpdateListener { + + private final static ResourceLocation RECIPE_BUTTON_TEXTURE = new ResourceLocation("textures/gui/recipe_button.png"); + private final static ResourceLocation BACKGROUND_TEXTURE = BetterEnd.makeID("textures/gui/smelter_gui.png"); + + public final EndStoneSmelterRecipeBookScreen recipeBook; + private boolean narrow; + + public EndStoneSmelterScreen(EndStoneSmelterMenu handler, Inventory inventory, Component title) { + super(handler, inventory, title); + recipeBook = new EndStoneSmelterRecipeBookScreen(); + } + + public void init() { + super.init(); + narrow = width < 379; + recipeBook.init(width, height, minecraft, narrow, menu); + leftPos = recipeBook.updateScreenPosition(width, imageWidth); + addRenderableWidget(new ImageButton( + leftPos + 20, + height / 2 - 49, + 20, + 18, + 0, + 0, + 19, + RECIPE_BUTTON_TEXTURE, + (buttonWidget) -> { + recipeBook.initVisuals(); + recipeBook.toggleVisibility(); + leftPos = recipeBook.updateScreenPosition(width, imageWidth); + ((ImageButton) buttonWidget).setPosition(leftPos + 20, height / 2 - 49); + } + )); + titleLabelX = (imageWidth - font.width(title)) / 2; + } + + @Override + public void containerTick() { + super.containerTick(); + recipeBook.tick(); + } + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + renderBackground(matrices); + if (recipeBook.isVisible() && narrow) { + renderBg(matrices, delta, mouseX, mouseY); + recipeBook.render(matrices, mouseX, mouseY, delta); + } else { + recipeBook.render(matrices, mouseX, mouseY, delta); + super.render(matrices, mouseX, mouseY, delta); + recipeBook.renderGhostRecipe(matrices, leftPos, topPos, true, delta); + } + renderTooltip(matrices, mouseX, mouseY); + recipeBook.renderTooltip(matrices, leftPos, topPos, mouseX, mouseY); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (this.recipeBook.mouseClicked(mouseX, mouseY, button)) { + return true; + } else { + return narrow && recipeBook.isVisible() || super.mouseClicked(mouseX, mouseY, button); + } + } + + @Override + protected void slotClicked(Slot slot, int invSlot, int clickData, ClickType actionType) { + super.slotClicked(slot, invSlot, clickData, actionType); + this.recipeBook.slotClicked(slot); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + return !recipeBook.keyPressed(keyCode, scanCode, modifiers) && super.keyPressed(keyCode, scanCode, modifiers); + } + + @Override + protected boolean hasClickedOutside(double mouseX, double mouseY, int left, int top, int button) { + boolean isMouseOut = mouseX < left || mouseY < top || mouseX >= (left + imageWidth) || mouseY >= (top + imageHeight); + return this.recipeBook.hasClickedOutside( + mouseX, + mouseY, + leftPos, + topPos, + imageWidth, + imageHeight, + button + ) && isMouseOut; + } + + @Override + public boolean charTyped(char chr, int keyCode) { + return recipeBook.charTyped(chr, keyCode) || super.charTyped(chr, keyCode); + } + + @Override + public void recipesUpdated() { + recipeBook.recipesUpdated(); + } + + @Override + public RecipeBookComponent getRecipeBookComponent() { + return recipeBook; + } + + @Override + protected void renderBg(PoseStack matrices, float delta, int mouseX, int mouseY) { + if (minecraft == null) return; + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.setShaderTexture(0, BACKGROUND_TEXTURE); + blit(matrices, leftPos, topPos, 0, 0, imageWidth, imageHeight); + int progress; + if (menu.isBurning()) { + progress = menu.getFuelProgress(); + blit(matrices, leftPos + 56, topPos + 36 + 12 - progress, 176, 12 - progress, 14, progress + 1); + } + progress = menu.getSmeltProgress(); + blit(matrices, leftPos + 92, topPos + 34, 176, 14, progress + 1, 16); + } + + @Override + public void removed() { + recipeBook.removed(); + super.removed(); + } +} diff --git a/src/main/java/org/betterx/betterend/client/gui/slot/SmelterFuelSlot.java b/src/main/java/org/betterx/betterend/client/gui/slot/SmelterFuelSlot.java new file mode 100644 index 00000000..1449219c --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/gui/slot/SmelterFuelSlot.java @@ -0,0 +1,26 @@ +package org.betterx.betterend.client.gui.slot; + +import org.betterx.betterend.client.gui.EndStoneSmelterMenu; + +import net.minecraft.world.Container; +import net.minecraft.world.inventory.FurnaceFuelSlot; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; + +public class SmelterFuelSlot extends Slot { + + private final EndStoneSmelterMenu handler; + + public SmelterFuelSlot(EndStoneSmelterMenu handler, Container inventory, int index, int x, int y) { + super(inventory, index, x, y); + this.handler = handler; + } + + public boolean mayPlace(ItemStack stack) { + return this.handler.isFuel(stack) || FurnaceFuelSlot.isBucket(stack); + } + + public int getMaxStackSize(ItemStack stack) { + return FurnaceFuelSlot.isBucket(stack) ? 1 : super.getMaxStackSize(stack); + } +} diff --git a/src/main/java/org/betterx/betterend/client/gui/slot/SmelterOutputSlot.java b/src/main/java/org/betterx/betterend/client/gui/slot/SmelterOutputSlot.java new file mode 100644 index 00000000..d8858d57 --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/gui/slot/SmelterOutputSlot.java @@ -0,0 +1,49 @@ +package org.betterx.betterend.client.gui.slot; + +import org.betterx.betterend.blocks.entities.EndStoneSmelterBlockEntity; + +import net.minecraft.world.Container; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; + +public class SmelterOutputSlot extends Slot { + + private final Player player; + private int amount; + + public SmelterOutputSlot(Player player, Container inventory, int index, int x, int y) { + super(inventory, index, x, y); + this.player = player; + } + + public boolean mayPlace(ItemStack stack) { + return false; + } + + public ItemStack remove(int amount) { + if (this.hasItem()) { + this.amount += Math.min(amount, this.getItem().getCount()); + } + + return super.remove(amount); + } + + public void onTake(Player player, ItemStack stack) { + this.checkTakeAchievements(stack); + super.onTake(player, stack); + } + + protected void onQuickCraft(ItemStack stack, int amount) { + this.amount += amount; + this.checkTakeAchievements(stack); + } + + protected void checkTakeAchievements(ItemStack stack) { + stack.onCraftedBy(this.player.level, this.player, this.amount); + if (!this.player.level.isClientSide && this.container instanceof EndStoneSmelterBlockEntity) { + ((EndStoneSmelterBlockEntity) this.container).dropExperience(player); + } + this.amount = 0; + } +} diff --git a/src/main/java/org/betterx/betterend/client/models/Patterns.java b/src/main/java/org/betterx/betterend/client/models/Patterns.java new file mode 100644 index 00000000..0a46225f --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/models/Patterns.java @@ -0,0 +1,151 @@ +package org.betterx.betterend.client.models; + +import org.betterx.betterend.BetterEnd; + +import net.minecraft.client.Minecraft; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.ResourceManager; + +import com.google.common.collect.Maps; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.stream.Collectors; + +public class Patterns { + //Block Models + public final static ResourceLocation BLOCK_EMPTY = BetterEnd.makeID("patterns/block/empty.json"); + public final static ResourceLocation BLOCK_BASE = BetterEnd.makeID("patterns/block/block.json"); + public final static ResourceLocation BLOCK_SIDED = BetterEnd.makeID("patterns/block/block_sided.json"); + public final static ResourceLocation BLOCK_BOTTOM_TOP = BetterEnd.makeID("patterns/block/block_bottom_top.json"); + public final static ResourceLocation BLOCK_SLAB = BetterEnd.makeID("patterns/block/slab.json"); + public final static ResourceLocation BLOCK_STAIR = BetterEnd.makeID("patterns/block/stairs.json"); + public final static ResourceLocation BLOCK_STAIR_INNER = BetterEnd.makeID("patterns/block/inner_stairs.json"); + public final static ResourceLocation BLOCK_STAIR_OUTER = BetterEnd.makeID("patterns/block/outer_stairs.json"); + public final static ResourceLocation BLOCK_WALL_POST = BetterEnd.makeID("patterns/block/wall_post.json"); + public final static ResourceLocation BLOCK_WALL_SIDE = BetterEnd.makeID("patterns/block/wall_side.json"); + public final static ResourceLocation BLOCK_WALL_SIDE_TALL = BetterEnd.makeID("patterns/block/wall_side_tall.json"); + public final static ResourceLocation BLOCK_FENCE_POST = BetterEnd.makeID("patterns/block/fence_post.json"); + public final static ResourceLocation BLOCK_FENCE_SIDE = BetterEnd.makeID("patterns/block/fence_side.json"); + public final static ResourceLocation BLOCK_BUTTON = BetterEnd.makeID("patterns/block/button.json"); + public final static ResourceLocation BLOCK_BUTTON_PRESSED = BetterEnd.makeID("patterns/block/button_pressed.json"); + public final static ResourceLocation BLOCK_PILLAR = BetterEnd.makeID("patterns/block/pillar.json"); + public final static ResourceLocation BLOCK_PLATE_UP = BetterEnd.makeID("patterns/block/pressure_plate_up.json"); + public final static ResourceLocation BLOCK_PLATE_DOWN = BetterEnd.makeID("patterns/block/pressure_plate_down.json"); + public final static ResourceLocation BLOCK_DOOR_TOP = BetterEnd.makeID("patterns/block/door_top.json"); + public final static ResourceLocation BLOCK_DOOR_TOP_HINGE = BetterEnd.makeID("patterns/block/door_top_hinge.json"); + public final static ResourceLocation BLOCK_DOOR_BOTTOM = BetterEnd.makeID("patterns/block/door_bottom.json"); + public final static ResourceLocation BLOCK_DOOR_BOTTOM_HINGE = BetterEnd.makeID( + "patterns/block/door_bottom_hinge.json"); + public final static ResourceLocation BLOCK_CROSS = BetterEnd.makeID("patterns/block/cross.json"); + public final static ResourceLocation BLOCK_CROSS_SHADED = BetterEnd.makeID("patterns/block/cross_shaded.json"); + public final static ResourceLocation BLOCK_GATE_CLOSED = BetterEnd.makeID("patterns/block/fence_gate_closed.json"); + public final static ResourceLocation BLOCK_GATE_CLOSED_WALL = BetterEnd.makeID( + "patterns/block/wall_gate_closed.json"); + public final static ResourceLocation BLOCK_GATE_OPEN = BetterEnd.makeID("patterns/block/fence_gate_open.json"); + public final static ResourceLocation BLOCK_GATE_OPEN_WALL = BetterEnd.makeID("patterns/block/wall_gate_open.json"); + public final static ResourceLocation BLOCK_TRAPDOOR = BetterEnd.makeID("patterns/block/trapdoor.json"); + public final static ResourceLocation BLOCK_LADDER = BetterEnd.makeID("patterns/block/ladder.json"); + public final static ResourceLocation BLOCK_BARREL_OPEN = BetterEnd.makeID("patterns/block/barrel_open.json"); + public final static ResourceLocation BLOCK_PEDESTAL_DEFAULT = BetterEnd.makeID( + "patterns/block/pedestal_default.json"); + public final static ResourceLocation BLOKC_PEDESTAL_COLUMN = BetterEnd.makeID("patterns/block/pedestal_column.json"); + public final static ResourceLocation BLOCK_PEDESTAL_COLUMN_TOP = BetterEnd.makeID( + "patterns/block/pedestal_column_top.json"); + public final static ResourceLocation BLOCK_PEDESTAL_TOP = BetterEnd.makeID("patterns/block/pedestal_top.json"); + public final static ResourceLocation BLOCK_PEDESTAL_BOTTOM = BetterEnd.makeID("patterns/block/pedestal_bottom.json"); + public final static ResourceLocation BLOCK_PEDESTAL_PILLAR = BetterEnd.makeID("patterns/block/pedestal_pillar.json"); + public final static ResourceLocation BLOCK_BOOKSHELF = BetterEnd.makeID("patterns/block/bookshelf.json"); + public final static ResourceLocation BLOCK_STONE_LANTERN_CEIL = BetterEnd.makeID( + "patterns/block/stone_lantern_ceil.json"); + public final static ResourceLocation BLOCK_STONE_LANTERN_FLOOR = BetterEnd.makeID( + "patterns/block/stone_lantern_floor.json"); + public final static ResourceLocation BLOCK_BULB_LANTERN_FLOOR = BetterEnd.makeID( + "patterns/block/bulb_lantern_floor.json"); + public final static ResourceLocation BLOCK_BULB_LANTERN_CEIL = BetterEnd.makeID( + "patterns/block/bulb_lantern_ceil.json"); + public final static ResourceLocation BLOCK_PETAL_COLORED = BetterEnd.makeID("models/block/block_petal_colored.json"); + public final static ResourceLocation BLOCK_COMPOSTER = BetterEnd.makeID("patterns/block/composter.json"); + public final static ResourceLocation BLOCK_COLORED = BetterEnd.makeID("patterns/block/block_colored.json"); + public final static ResourceLocation BLOCK_BARS_POST = BetterEnd.makeID("patterns/block/bars_post.json"); + public final static ResourceLocation BLOCK_BARS_SIDE = BetterEnd.makeID("patterns/block/bars_side.json"); + public final static ResourceLocation BLOCK_ANVIL = BetterEnd.makeID("patterns/block/anvil.json"); + public final static ResourceLocation BLOCK_CHAIN = BetterEnd.makeID("patterns/block/chain.json"); + public final static ResourceLocation BLOCK_CHANDELIER_FLOOR = BetterEnd.makeID( + "patterns/block/chandelier_floor.json"); + public final static ResourceLocation BLOCK_CHANDELIER_WALL = BetterEnd.makeID("patterns/block/chandelier_wall.json"); + public final static ResourceLocation BLOCK_CHANDELIER_CEIL = BetterEnd.makeID("patterns/block/chandelier_ceil.json"); + public final static ResourceLocation BLOCK_FURNACE = BetterEnd.makeID("patterns/block/furnace.json"); + public final static ResourceLocation BLOCK_FURNACE_LIT = BetterEnd.makeID("patterns/block/furnace_glow.json"); + public final static ResourceLocation BLOCK_TOP_SIDE_BOTTOM = BetterEnd.makeID("patterns/block/top_side_bottom.json"); + public final static ResourceLocation BLOCK_PATH = BetterEnd.makeID("patterns/block/path.json"); + public final static ResourceLocation BLOCK_FLOWER_POT = BetterEnd.makeID("patterns/block/flower_pot.json"); + public final static ResourceLocation BLOCK_FLOWER_POT_SOIL = BetterEnd.makeID("patterns/block/flower_pot_soil.json"); + public final static ResourceLocation BLOCK_POTTED_LEAVES = BetterEnd.makeID("patterns/block/potted_leaves.json"); + + //Item Models + public final static ResourceLocation ITEM_WALL = BetterEnd.makeID("patterns/item/pattern_wall.json"); + public final static ResourceLocation ITEM_FENCE = BetterEnd.makeID("patterns/item/pattern_fence.json"); + public final static ResourceLocation ITEM_BUTTON = BetterEnd.makeID("patterns/item/pattern_button.json"); + public final static ResourceLocation ITEM_CHEST = BetterEnd.makeID("patterns/item/pattern_chest.json"); + public final static ResourceLocation ITEM_BLOCK = BetterEnd.makeID("patterns/item/pattern_block_item.json"); + public final static ResourceLocation ITEM_GENERATED = BetterEnd.makeID("patterns/item/pattern_item_generated.json"); + public final static ResourceLocation ITEM_HANDHELD = BetterEnd.makeID("patterns/item/pattern_item_handheld.json"); + public final static ResourceLocation ITEM_SPAWN_EGG = BetterEnd.makeID("patterns/item/pattern_item_spawn_egg.json"); + + public static Optional createItemGenerated(String name) { + return createJson(ITEM_GENERATED, name); + } + + public static Optional createBlockSimple(String name) { + return Patterns.createJson(Patterns.BLOCK_BASE, name, name); + } + + public static Optional createBlockPillar(String name) { + return Patterns.createJson(Patterns.BLOCK_PILLAR, name, name); + } + + public static String createJson(Reader data, String parent, String block) { + try (BufferedReader buffer = new BufferedReader(data)) { + return buffer.lines().collect(Collectors.joining()).replace("%parent%", parent).replace("%block%", block); + } catch (Exception ex) { + return null; + } + } + + public static Optional createJson(ResourceLocation patternId, String parent, String block) { + ResourceManager resourceManager = Minecraft.getInstance().getResourceManager(); + try (InputStream input = resourceManager.getResource(patternId).get().open()) { + return Optional.ofNullable(createJson(new InputStreamReader(input, StandardCharsets.UTF_8), parent, block)); + } catch (Exception ex) { + return Optional.empty(); + } + } + + public static Optional createJson(ResourceLocation patternId, String texture) { + Map textures = Maps.newHashMap(); + textures.put("%texture%", texture); + return createJson(patternId, textures); + } + + public static Optional createJson(ResourceLocation patternId, Map textures) { + ResourceManager resourceManager = Minecraft.getInstance().getResourceManager(); + try (InputStream input = resourceManager.getResource(patternId).get().open()) { + String json = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)).lines() + .collect(Collectors.joining()); + for (Entry texture : textures.entrySet()) { + json = json.replace(texture.getKey(), texture.getValue()); + } + return Optional.of(json); + } catch (Exception ex) { + return Optional.empty(); + } + } + +} diff --git a/src/main/java/org/betterx/betterend/client/render/ArmoredElytraLayer.java b/src/main/java/org/betterx/betterend/client/render/ArmoredElytraLayer.java new file mode 100644 index 00000000..aebe0650 --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/render/ArmoredElytraLayer.java @@ -0,0 +1,75 @@ +package org.betterx.betterend.client.render; + +import org.betterx.bclib.items.elytra.BCLElytraItem; +import org.betterx.bclib.items.elytra.BCLElytraUtils; +import org.betterx.betterend.item.model.ArmoredElytraModel; +import org.betterx.betterend.registry.EndEntitiesRenders; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.geom.EntityModelSet; +import net.minecraft.client.player.AbstractClientPlayer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.renderer.entity.RenderLayerParent; +import net.minecraft.client.renderer.entity.layers.ElytraLayer; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.PlayerModelPart; +import net.minecraft.world.item.ItemStack; + +public class ArmoredElytraLayer> extends ElytraLayer { + private final ArmoredElytraModel elytraModel; + + public ArmoredElytraLayer(RenderLayerParent renderLayerParent, EntityModelSet entityModelSet) { + super(renderLayerParent, entityModelSet); + elytraModel = new ArmoredElytraModel<>(entityModelSet.bakeLayer(EndEntitiesRenders.ARMORED_ELYTRA)); + } + + public void render( + PoseStack poseStack, + MultiBufferSource multiBufferSource, + int i, + T livingEntity, + float f, + float g, + float h, + float j, + float k, + float l + ) { + ItemStack itemStack = (BCLElytraUtils.slotProvider == null) + ? livingEntity.getItemBySlot(EquipmentSlot.CHEST) + : BCLElytraUtils.slotProvider.getElytra(livingEntity, livingEntity::getItemBySlot); + + if (itemStack != null && itemStack.getItem() instanceof BCLElytraItem) { + ResourceLocation wingsTexture = ((BCLElytraItem) itemStack.getItem()).getModelTexture(); + if (livingEntity instanceof AbstractClientPlayer) { + AbstractClientPlayer abstractClientPlayer = (AbstractClientPlayer) livingEntity; + if (abstractClientPlayer.isElytraLoaded() && abstractClientPlayer.getElytraTextureLocation() != null) { + wingsTexture = abstractClientPlayer.getElytraTextureLocation(); + } else if (abstractClientPlayer.isCapeLoaded() && abstractClientPlayer.getCloakTextureLocation() != null && abstractClientPlayer + .isModelPartShown(PlayerModelPart.CAPE)) { + wingsTexture = abstractClientPlayer.getCloakTextureLocation(); + } + } + + poseStack.pushPose(); + poseStack.translate(0.0D, 0.0D, 0.125D); + getParentModel().copyPropertiesTo(elytraModel); + elytraModel.setupAnim(livingEntity, f, g, j, k, l); + VertexConsumer vertexConsumer = ItemRenderer.getArmorFoilBuffer( + multiBufferSource, + RenderType.armorCutoutNoCull(wingsTexture), + false, + itemStack.hasFoil() + ); + elytraModel.renderToBuffer(poseStack, vertexConsumer, i, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); + poseStack.popPose(); + } + } +} diff --git a/src/main/java/org/betterx/betterend/client/render/BeamRenderer.java b/src/main/java/org/betterx/betterend/client/render/BeamRenderer.java new file mode 100644 index 00000000..13b92566 --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/render/BeamRenderer.java @@ -0,0 +1,245 @@ +package org.betterx.betterend.client.render; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Matrix3f; +import com.mojang.math.Matrix4f; +import com.mojang.math.Vector3f; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; + +public class BeamRenderer { + private static final ResourceLocation BEAM_TEXTURE = new ResourceLocation("textures/entity/end_gateway_beam.png"); + + public static void renderLightBeam( + PoseStack matrices, + MultiBufferSource vertexConsumers, + int age, + float tick, + int minY, + int maxY, + float[] colors, + float alpha, + float beamIn, + float beamOut + ) { + float red = colors[0]; + float green = colors[1]; + float blue = colors[2]; + + int maxBY = minY + maxY; + float delta = maxY < 0 ? tick : -tick; + float fractDelta = Mth.frac(delta * 0.2F - (float) Mth.floor(delta * 0.1F)); + float xIn = -beamIn; + float minV = Mth.clamp(fractDelta - 1.0F, 0.0F, 1.0F); + float maxV = (float) maxY * (0.5F / beamIn) + minV; + float rotation = (age + tick) / 25.0F + 6.0F; + + VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderType.beaconBeam(BEAM_TEXTURE, true)); + + matrices.pushPose(); + matrices.mulPose(Vector3f.YP.rotation(-rotation)); + renderBeam( + matrices, + vertexConsumer, + red, + green, + blue, + alpha, + minY, + maxBY, + beamIn, + 0.0F, + 0.0F, + beamIn, + 0.0F, + xIn, + xIn, + 0.0F, + 0.0F, + 1.0F, + minV, + maxV + ); + + float xOut = -beamOut; + maxV = (float) maxY + minV; + renderBeam( + matrices, + vertexConsumer, + red, + green, + blue, + alpha, + minY, + maxBY, + xOut, + xOut, + beamOut, + xOut, + xOut, + beamOut, + beamOut, + beamOut, + 0.0F, + 1.0F, + minV, + maxV + ); + matrices.popPose(); + } + + private static void renderBeam( + PoseStack matrices, + VertexConsumer vertexConsumer, + float red, + float green, + float blue, + float alpha, + int minY, + int maxY, + float x1, + float d1, + float x2, + float d2, + float x3, + float d3, + float x4, + float d4, + float minU, + float maxU, + float minV, + float maxV + ) { + PoseStack.Pose entry = matrices.last(); + Matrix4f matrix4f = entry.pose(); + Matrix3f matrix3f = entry.normal(); + renderBeam( + matrix4f, + matrix3f, + vertexConsumer, + red, + green, + blue, + alpha, + maxY, + minY, + x1, + d1, + x2, + d2, + minU, + maxU, + minV, + maxV + ); + renderBeam( + matrix4f, + matrix3f, + vertexConsumer, + red, + green, + blue, + alpha, + maxY, + minY, + x4, + d4, + x3, + d3, + minU, + maxU, + minV, + maxV + ); + renderBeam( + matrix4f, + matrix3f, + vertexConsumer, + red, + green, + blue, + alpha, + maxY, + minY, + x2, + d2, + x4, + d4, + minU, + maxU, + minV, + maxV + ); + renderBeam( + matrix4f, + matrix3f, + vertexConsumer, + red, + green, + blue, + alpha, + maxY, + minY, + x3, + d3, + x1, + d1, + minU, + maxU, + minV, + maxV + ); + } + + private static void renderBeam( + Matrix4f matrix4f, + Matrix3f matrix3f, + VertexConsumer vertexConsumer, + float red, + float green, + float blue, + float alpha, + int minY, + int maxY, + float minX, + float minD, + float maxX, + float maxD, + float minU, + float maxU, + float minV, + float maxV + ) { + addVertex(matrix4f, matrix3f, vertexConsumer, red, green, blue, alpha, maxX, minY, maxD, maxU, minV); + addVertex(matrix4f, matrix3f, vertexConsumer, red, green, blue, alpha, maxX, maxY, maxD, maxU, maxV); + addVertex(matrix4f, matrix3f, vertexConsumer, red, green, blue, alpha, minX, maxY, minD, minU, maxV); + addVertex(matrix4f, matrix3f, vertexConsumer, red, green, blue, alpha, minX, minY, minD, minU, minV); + } + + private static void addVertex( + Matrix4f matrix4f, + Matrix3f matrix3f, + VertexConsumer vertexConsumer, + float red, + float green, + float blue, + float alpha, + float x, + float y, + float d, + float u, + float v + ) { + vertexConsumer.vertex(matrix4f, x, y, d) + .color(red, green, blue, alpha) + .uv(u, v) + .overlayCoords(OverlayTexture.NO_OVERLAY) + .uv2(15728880) + .normal(matrix3f, 0.0F, 1.0F, 0.0F) + .endVertex(); + } +} diff --git a/src/main/java/org/betterx/betterend/client/render/BetterEndSkyRenderer.java b/src/main/java/org/betterx/betterend/client/render/BetterEndSkyRenderer.java new file mode 100644 index 00000000..eb2b85fa --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/render/BetterEndSkyRenderer.java @@ -0,0 +1,442 @@ +package org.betterx.betterend.client.render; + +import org.betterx.bclib.util.BackgroundInfo; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.BetterEnd; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.*; +import com.mojang.math.Matrix4f; +import com.mojang.math.Quaternion; +import com.mojang.math.Vector3f; +import net.minecraft.client.renderer.FogRenderer; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.levelgen.LegacyRandomSource; + +import net.fabricmc.fabric.api.client.rendering.v1.DimensionRenderingRegistry; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; + +public class BetterEndSkyRenderer implements DimensionRenderingRegistry.SkyRenderer { + @FunctionalInterface + interface BufferFunction { + void make(BufferBuilder bufferBuilder, double minSize, double maxSize, int count, long seed); + } + + private static final ResourceLocation NEBULA_1 = BetterEnd.makeID("textures/sky/nebula_2.png"); + private static final ResourceLocation NEBULA_2 = BetterEnd.makeID("textures/sky/nebula_3.png"); + private static final ResourceLocation HORIZON = BetterEnd.makeID("textures/sky/nebula_1.png"); + private static final ResourceLocation STARS = BetterEnd.makeID("textures/sky/stars.png"); + private static final ResourceLocation FOG = BetterEnd.makeID("textures/sky/fog.png"); + + private VertexBuffer nebula1; + private VertexBuffer nebula2; + private VertexBuffer horizon; + private VertexBuffer stars1; + private VertexBuffer stars2; + private VertexBuffer stars3; + private VertexBuffer stars4; + private VertexBuffer fog; + private Vector3f axis1; + private Vector3f axis2; + private Vector3f axis3; + private Vector3f axis4; + + private boolean initialised; + + private void initialise() { + if (!initialised) { + initStars(); + RandomSource random = new LegacyRandomSource(131); + axis1 = new Vector3f(random.nextFloat(), random.nextFloat(), random.nextFloat()); + axis2 = new Vector3f(random.nextFloat(), random.nextFloat(), random.nextFloat()); + axis3 = new Vector3f(random.nextFloat(), random.nextFloat(), random.nextFloat()); + axis4 = new Vector3f(random.nextFloat(), random.nextFloat(), random.nextFloat()); + axis1.normalize(); + axis2.normalize(); + axis3.normalize(); + axis4.normalize(); + initialised = true; + } + } + + @Override + public void render(WorldRenderContext context) { + if (context.world() == null || context.matrixStack() == null) { + return; + } + + initialise(); + + Matrix4f projectionMatrix = context.projectionMatrix(); + PoseStack matrices = context.matrixStack(); + + float time = ((context.world().getDayTime() + context.tickDelta()) % 360000) * 0.000017453292F; + float time2 = time * 2; + float time3 = time * 3; + + FogRenderer.levelFogColor(); + RenderSystem.depthMask(false); + RenderSystem.enableTexture(); + RenderSystem.enableBlend(); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + + float blindA = 1F - BackgroundInfo.blindness; + float blind02 = blindA * 0.2F; + float blind06 = blindA * 0.6F; + + if (blindA > 0) { + matrices.pushPose(); + matrices.mulPose(new Quaternion(0, time, 0, false)); + RenderSystem.setShaderTexture(0, HORIZON); + renderBuffer( + matrices, + projectionMatrix, + horizon, + DefaultVertexFormat.POSITION_TEX, + 0.77F, + 0.31F, + 0.73F, + 0.7F * blindA + ); + matrices.popPose(); + + matrices.pushPose(); + matrices.mulPose(new Quaternion(0, -time, 0, false)); + RenderSystem.setShaderTexture(0, NEBULA_1); + renderBuffer( + matrices, + projectionMatrix, + nebula1, + DefaultVertexFormat.POSITION_TEX, + 0.77F, + 0.31F, + 0.73F, + blind02 + ); + matrices.popPose(); + + matrices.pushPose(); + matrices.mulPose(new Quaternion(0, time2, 0, false)); + RenderSystem.setShaderTexture(0, NEBULA_2); + renderBuffer( + matrices, + projectionMatrix, + nebula2, + DefaultVertexFormat.POSITION_TEX, + 0.77F, + 0.31F, + 0.73F, + blind02 + ); + matrices.popPose(); + + RenderSystem.setShaderTexture(0, STARS); + + matrices.pushPose(); + matrices.mulPose(axis3.rotation(time)); + renderBuffer( + matrices, + projectionMatrix, + stars3, + DefaultVertexFormat.POSITION_TEX, + 0.77F, + 0.31F, + 0.73F, + blind06 + ); + matrices.popPose(); + + matrices.pushPose(); + matrices.mulPose(axis4.rotation(time2)); + renderBuffer(matrices, projectionMatrix, stars4, DefaultVertexFormat.POSITION_TEX, 1F, 1F, 1F, blind06); + matrices.popPose(); + } + + float a = (BackgroundInfo.fogDensity - 1F); + if (a > 0) { + if (a > 1) a = 1; + RenderSystem.setShaderTexture(0, FOG); + renderBuffer( + matrices, + projectionMatrix, + fog, + DefaultVertexFormat.POSITION_TEX, + BackgroundInfo.fogColorRed, + BackgroundInfo.fogColorGreen, + BackgroundInfo.fogColorBlue, + a + ); + } + + RenderSystem.disableTexture(); + + if (blindA > 0) { + matrices.pushPose(); + matrices.mulPose(axis1.rotation(time3)); + renderBuffer(matrices, projectionMatrix, stars1, DefaultVertexFormat.POSITION, 1, 1, 1, blind06); + matrices.popPose(); + + matrices.pushPose(); + matrices.mulPose(axis2.rotation(time2)); + renderBuffer( + matrices, + projectionMatrix, + stars2, + DefaultVertexFormat.POSITION, + 0.95F, + 0.64F, + 0.93F, + blind06 + ); + matrices.popPose(); + } + + RenderSystem.enableTexture(); + RenderSystem.depthMask(true); + RenderSystem.defaultBlendFunc(); + RenderSystem.disableBlend(); + } + + private void renderBuffer( + PoseStack matrices, + Matrix4f matrix4f, + VertexBuffer buffer, + VertexFormat format, + float r, + float g, + float b, + float a + ) { + RenderSystem.setShaderColor(r, g, b, a); + buffer.bind(); + if (format == DefaultVertexFormat.POSITION) { + buffer.drawWithShader(matrices.last().pose(), matrix4f, GameRenderer.getPositionShader()); + } else { + buffer.drawWithShader(matrices.last().pose(), matrix4f, GameRenderer.getPositionTexShader()); + } + VertexBuffer.unbind(); + } + + private void initStars() { + BufferBuilder buffer = Tesselator.getInstance().getBuilder(); + stars1 = buildBuffer(buffer, stars1, 0.1, 0.30, 3500, 41315, this::makeStars); + stars2 = buildBuffer(buffer, stars2, 0.1, 0.35, 2000, 35151, this::makeStars); + stars3 = buildBuffer(buffer, stars3, 0.4, 1.2, 1000, 61354, this::makeUVStars); + stars4 = buildBuffer(buffer, stars4, 0.4, 1.2, 1000, 61355, this::makeUVStars); + nebula1 = buildBuffer(buffer, nebula1, 40, 60, 30, 11515, this::makeFarFog); + nebula2 = buildBuffer(buffer, nebula2, 40, 60, 10, 14151, this::makeFarFog); + horizon = buildBufferHorizon(buffer, horizon); + fog = buildBufferFog(buffer, fog); + } + + private VertexBuffer buildBuffer( + BufferBuilder bufferBuilder, + VertexBuffer buffer, + double minSize, + double maxSize, + int count, + long seed, + BufferFunction fkt + ) { + if (buffer != null) { + buffer.close(); + } + + buffer = new VertexBuffer(); + fkt.make(bufferBuilder, minSize, maxSize, count, seed); + BufferBuilder.RenderedBuffer renderedBuffer = bufferBuilder.end(); + buffer.bind(); + buffer.upload(renderedBuffer); + + return buffer; + } + + + private VertexBuffer buildBufferHorizon(BufferBuilder bufferBuilder, VertexBuffer buffer) { + return buildBuffer( + bufferBuilder, buffer, 0, 0, 0, 0, + (_builder, _minSize, _maxSize, _count, _seed) -> makeCylinder(_builder, 16, 50, 100) + ); + + } + + private VertexBuffer buildBufferFog(BufferBuilder bufferBuilder, VertexBuffer buffer) { + return buildBuffer( + bufferBuilder, buffer, 0, 0, 0, 0, + (_builder, _minSize, _maxSize, _count, _seed) -> makeCylinder(_builder, 16, 50, 70) + ); + } + + private void makeStars(BufferBuilder buffer, double minSize, double maxSize, int count, long seed) { + RandomSource random = new LegacyRandomSource(seed); + RenderSystem.setShader(GameRenderer::getPositionShader); + buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION); + + for (int i = 0; i < count; ++i) { + double posX = random.nextDouble() * 2.0 - 1.0; + double posY = random.nextDouble() * 2.0 - 1.0; + double posZ = random.nextDouble() * 2.0 - 1.0; + double size = MHelper.randRange(minSize, maxSize, random); + double length = posX * posX + posY * posY + posZ * posZ; + + if (length < 1.0 && length > 0.001) { + length = 1.0 / Math.sqrt(length); + posX *= length; + posY *= length; + posZ *= length; + + double px = posX * 100.0; + double py = posY * 100.0; + double pz = posZ * 100.0; + + double angle = Math.atan2(posX, posZ); + double sin1 = Math.sin(angle); + double cos1 = Math.cos(angle); + angle = Math.atan2(Math.sqrt(posX * posX + posZ * posZ), posY); + double sin2 = Math.sin(angle); + double cos2 = Math.cos(angle); + angle = random.nextDouble() * Math.PI * 2.0; + double sin3 = Math.sin(angle); + double cos3 = Math.cos(angle); + + for (int index = 0; index < 4; ++index) { + double x = (double) ((index & 2) - 1) * size; + double y = (double) ((index + 1 & 2) - 1) * size; + double aa = x * cos3 - y * sin3; + double ab = y * cos3 + x * sin3; + double dy = aa * sin2 + 0.0 * cos2; + double ae = 0.0 * sin2 - aa * cos2; + double dx = ae * sin1 - ab * cos1; + double dz = ab * sin1 + ae * cos1; + buffer.vertex(px + dx, py + dy, pz + dz).endVertex(); + } + } + } + } + + private void makeUVStars(BufferBuilder buffer, double minSize, double maxSize, int count, long seed) { + RandomSource random = new LegacyRandomSource(seed); + RenderSystem.setShader(GameRenderer::getPositionTexShader); + buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX); + + for (int i = 0; i < count; ++i) { + double posX = random.nextDouble() * 2.0 - 1.0; + double posY = random.nextDouble() * 2.0 - 1.0; + double posZ = random.nextDouble() * 2.0 - 1.0; + double size = MHelper.randRange(minSize, maxSize, random); + double length = posX * posX + posY * posY + posZ * posZ; + + if (length < 1.0 && length > 0.001) { + length = 1.0 / Math.sqrt(length); + posX *= length; + posY *= length; + posZ *= length; + + double px = posX * 100.0; + double py = posY * 100.0; + double pz = posZ * 100.0; + + double angle = Math.atan2(posX, posZ); + double sin1 = Math.sin(angle); + double cos1 = Math.cos(angle); + angle = Math.atan2(Math.sqrt(posX * posX + posZ * posZ), posY); + double sin2 = Math.sin(angle); + double cos2 = Math.cos(angle); + angle = random.nextDouble() * Math.PI * 2.0; + double sin3 = Math.sin(angle); + double cos3 = Math.cos(angle); + + float minV = random.nextInt(4) / 4F; + for (int index = 0; index < 4; ++index) { + double x = (double) ((index & 2) - 1) * size; + double y = (double) ((index + 1 & 2) - 1) * size; + double aa = x * cos3 - y * sin3; + double ab = y * cos3 + x * sin3; + double dy = aa * sin2 + 0.0 * cos2; + double ae = 0.0 * sin2 - aa * cos2; + double dx = ae * sin1 - ab * cos1; + double dz = ab * sin1 + ae * cos1; + float texU = (index >> 1) & 1; + float texV = (((index + 1) >> 1) & 1) / 4F + minV; + buffer.vertex(px + dx, py + dy, pz + dz).uv(texU, texV).endVertex(); + } + } + } + } + + private void makeFarFog(BufferBuilder buffer, double minSize, double maxSize, int count, long seed) { + RandomSource random = new LegacyRandomSource(seed); + RenderSystem.setShader(GameRenderer::getPositionTexShader); + buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX); + + for (int i = 0; i < count; ++i) { + double posX = random.nextDouble() * 2.0 - 1.0; + double posY = random.nextDouble() - 0.5; + double posZ = random.nextDouble() * 2.0 - 1.0; + double size = MHelper.randRange(minSize, maxSize, random); + double length = posX * posX + posY * posY + posZ * posZ; + double distance = 2.0; + + if (length < 1.0 && length > 0.001) { + length = distance / Math.sqrt(length); + size *= distance; + posX *= length; + posY *= length; + posZ *= length; + + double px = posX * 100.0; + double py = posY * 100.0; + double pz = posZ * 100.0; + + double angle = Math.atan2(posX, posZ); + double sin1 = Math.sin(angle); + double cos1 = Math.cos(angle); + angle = Math.atan2(Math.sqrt(posX * posX + posZ * posZ), posY); + double sin2 = Math.sin(angle); + double cos2 = Math.cos(angle); + angle = random.nextDouble() * Math.PI * 2.0; + double sin3 = Math.sin(angle); + double cos3 = Math.cos(angle); + + for (int index = 0; index < 4; ++index) { + double x = (double) ((index & 2) - 1) * size; + double y = (double) ((index + 1 & 2) - 1) * size; + double aa = x * cos3 - y * sin3; + double ab = y * cos3 + x * sin3; + double dy = aa * sin2 + 0.0 * cos2; + double ae = 0.0 * sin2 - aa * cos2; + double dx = ae * sin1 - ab * cos1; + double dz = ab * sin1 + ae * cos1; + float texU = (index >> 1) & 1; + float texV = ((index + 1) >> 1) & 1; + buffer.vertex(px + dx, py + dy, pz + dz).uv(texU, texV).endVertex(); + } + } + } + } + + private void makeCylinder(BufferBuilder buffer, int segments, double height, double radius) { + RenderSystem.setShader(GameRenderer::getPositionTexShader); + buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX); + for (int i = 0; i < segments; i++) { + double a1 = (double) i * Math.PI * 2.0 / (double) segments; + double a2 = (double) (i + 1) * Math.PI * 2.0 / (double) segments; + double px1 = Math.sin(a1) * radius; + double pz1 = Math.cos(a1) * radius; + double px2 = Math.sin(a2) * radius; + double pz2 = Math.cos(a2) * radius; + + float u0 = (float) i / (float) segments; + float u1 = (float) (i + 1) / (float) segments; + + buffer.vertex(px1, -height, pz1).uv(u0, 0).endVertex(); + buffer.vertex(px1, height, pz1).uv(u0, 1).endVertex(); + buffer.vertex(px2, height, pz2).uv(u1, 1).endVertex(); + buffer.vertex(px2, -height, pz2).uv(u1, 0).endVertex(); + } + } +} diff --git a/src/main/java/org/betterx/betterend/client/render/EndCrystalRenderer.java b/src/main/java/org/betterx/betterend/client/render/EndCrystalRenderer.java new file mode 100644 index 00000000..0e79848f --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/render/EndCrystalRenderer.java @@ -0,0 +1,85 @@ +package org.betterx.betterend.client.render; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Quaternion; +import com.mojang.math.Vector3f; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; + +public class EndCrystalRenderer { + private static final ResourceLocation CRYSTAL_TEXTURE = new ResourceLocation( + "textures/entity/end_crystal/end_crystal.png"); + private static final ResourceLocation CRYSTAL_BEAM_TEXTURE = new ResourceLocation( + "textures/entity/end_crystal/end_crystal_beam.png"); + private static final RenderType END_CRYSTAL; + private static final ModelPart CORE; + private static final ModelPart FRAME; + private static final int AGE_CYCLE = 240; + private static final float SINE_45_DEGREES; + + public static void render( + int age, + int maxAge, + float tickDelta, + PoseStack matrices, + MultiBufferSource vertexConsumerProvider, + int light + ) { + float k = (float) AGE_CYCLE / maxAge; + float rotation = (age * k + tickDelta) * 3.0F; + VertexConsumer vertexConsumer = vertexConsumerProvider.getBuffer(END_CRYSTAL); + matrices.pushPose(); + matrices.scale(0.8F, 0.8F, 0.8F); + matrices.translate(0.0D, -0.5D, 0.0D); + matrices.mulPose(Vector3f.YP.rotationDegrees(rotation)); + matrices.translate(0.0D, 0.8F, 0.0D); + matrices.mulPose(new Quaternion(new Vector3f(SINE_45_DEGREES, 0.0F, SINE_45_DEGREES), 60.0F, true)); + FRAME.render(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY); + matrices.scale(0.875F, 0.875F, 0.875F); + matrices.mulPose(new Quaternion(new Vector3f(SINE_45_DEGREES, 0.0F, SINE_45_DEGREES), 60.0F, true)); + matrices.mulPose(Vector3f.YP.rotationDegrees(rotation)); + FRAME.render(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY); + matrices.scale(0.875F, 0.875F, 0.875F); + matrices.mulPose(new Quaternion(new Vector3f(SINE_45_DEGREES, 0.0F, SINE_45_DEGREES), 60.0F, true)); + matrices.mulPose(Vector3f.YP.rotationDegrees(rotation)); + CORE.render(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY); + matrices.popPose(); + } + + public static LayerDefinition getTexturedModelData() { + MeshDefinition modelData = new MeshDefinition(); + PartDefinition modelPartData = modelData.getRoot(); + modelPartData.addOrReplaceChild( + "FRAME", + CubeListBuilder.create().texOffs(0, 0).addBox(-4.0f, -4.0f, -4.0f, 8.0f, 8.0f, 8.0f), + PartPose.ZERO + ); + + modelPartData.addOrReplaceChild( + "CORE", + CubeListBuilder.create().texOffs(32, 0).addBox(-4.0f, -4.0f, -4.0f, 8.0f, 8.0f, 8.0f), + PartPose.ZERO + ); + + return LayerDefinition.create(modelData, 64, 32); + } + + static { + END_CRYSTAL = RenderType.entityCutoutNoCull(CRYSTAL_TEXTURE); + RenderType.entitySmoothCutout(CRYSTAL_BEAM_TEXTURE); + SINE_45_DEGREES = (float) Math.sin(0.7853981633974483D); + + ModelPart root = getTexturedModelData().bakeRoot(); + FRAME = root.getChild("FRAME"); + CORE = root.getChild("CORE"); + } +} diff --git a/src/main/java/org/betterx/betterend/client/render/EternalCrystalRenderer.java b/src/main/java/org/betterx/betterend/client/render/EternalCrystalRenderer.java new file mode 100644 index 00000000..80486ffe --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/render/EternalCrystalRenderer.java @@ -0,0 +1,137 @@ +package org.betterx.betterend.client.render; + +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.AuroraCrystalBlock; +import org.betterx.ui.ColorUtil; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Vector3f; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.core.Vec3i; +import net.minecraft.util.Mth; + +// TODO make crystals bright +public class EternalCrystalRenderer { + private static final RenderType RENDER_LAYER; + private static final ModelPart[] SHARDS; + private static final ModelPart CORE; + + public static void render( + int age, + float tickDelta, + PoseStack matrices, + MultiBufferSource vertexConsumerProvider, + int light + ) { + VertexConsumer vertexConsumer = vertexConsumerProvider.getBuffer(RENDER_LAYER); + float[] colors = colors(age); + float rotation = (age + tickDelta) / 25.0F + 6.0F; + matrices.pushPose(); + matrices.scale(0.6F, 0.6F, 0.6F); + matrices.mulPose(Vector3f.YP.rotation(rotation)); + CORE.render( + matrices, + vertexConsumer, + light, + OverlayTexture.NO_OVERLAY, + colors[0], + colors[1], + colors[2], + colors[3] + ); + + for (int i = 0; i < 4; i++) { + matrices.pushPose(); + float offset = Mth.sin(rotation * 2 + i) * 0.15F; + matrices.translate(0, offset, 0); + SHARDS[i].render( + matrices, + vertexConsumer, + light, + OverlayTexture.NO_OVERLAY, + colors[0], + colors[1], + colors[2], + colors[3] + ); + matrices.popPose(); + } + + matrices.popPose(); + } + + public static float[] colors(int age) { + double delta = age * 0.01; + int index = MHelper.floor(delta); + int index2 = (index + 1) & 3; + delta -= index; + index &= 3; + + Vec3i color1 = AuroraCrystalBlock.COLORS[index]; + Vec3i color2 = AuroraCrystalBlock.COLORS[index2]; + + int r = MHelper.floor(Mth.lerp(delta, color1.getX(), color2.getX())); + int g = MHelper.floor(Mth.lerp(delta, color1.getY(), color2.getY())); + int b = MHelper.floor(Mth.lerp(delta, color1.getZ(), color2.getZ())); + + return ColorUtil.toFloatArray(ColorUtil.color(r, g, b)); + } + + public static LayerDefinition getTexturedModelData() { + MeshDefinition modelData = new MeshDefinition(); + PartDefinition modelPartData = modelData.getRoot(); + modelPartData.addOrReplaceChild( + "SHARDS_0", + CubeListBuilder.create().texOffs(2, 4).addBox(-5.0f, 1.0f, -3.0f, 2.0f, 8.0f, 2.0f), + PartPose.ZERO + ); + + modelPartData.addOrReplaceChild( + "SHARDS_1", + CubeListBuilder.create().texOffs(2, 4).addBox(3.0f, -1.0f, -1.0f, 2.0f, 8.0f, 2.0f), + PartPose.ZERO + ); + + modelPartData.addOrReplaceChild( + "SHARDS_2", + CubeListBuilder.create().texOffs(2, 4).addBox(-1.0f, 0.0f, -5.0f, 2.0f, 4.0f, 2.0f), + PartPose.ZERO + ); + + modelPartData.addOrReplaceChild( + "SHARDS_3", + CubeListBuilder.create().texOffs(2, 4).addBox(0.0f, 3.0f, 4.0f, 2.0f, 6.0f, 2.0f), + PartPose.ZERO + ); + + modelPartData.addOrReplaceChild( + "CORE", + CubeListBuilder.create().texOffs(0, 0).addBox(-2.0f, -2.0f, -2.0f, 4.0f, 12.0f, 4.0f), + PartPose.ZERO + ); + + return LayerDefinition.create(modelData, 16, 16); + } + + static { + RENDER_LAYER = RenderType.itemEntityTranslucentCull(BetterEnd.makeID("textures/entity/eternal_crystal.png")); + SHARDS = new ModelPart[4]; + + ModelPart root = getTexturedModelData().bakeRoot(); + SHARDS[0] = root.getChild("SHARDS_0"); + SHARDS[1] = root.getChild("SHARDS_1"); + SHARDS[2] = root.getChild("SHARDS_2"); + SHARDS[3] = root.getChild("SHARDS_3"); + CORE = root.getChild("CORE"); + } +} diff --git a/src/main/java/org/betterx/betterend/client/render/PedestalItemRenderer.java b/src/main/java/org/betterx/betterend/client/render/PedestalItemRenderer.java new file mode 100644 index 00000000..e247acda --- /dev/null +++ b/src/main/java/org/betterx/betterend/client/render/PedestalItemRenderer.java @@ -0,0 +1,102 @@ +package org.betterx.betterend.client.render; + +import org.betterx.betterend.blocks.EternalPedestal; +import org.betterx.betterend.blocks.basis.PedestalBlock; +import org.betterx.betterend.blocks.entities.PedestalBlockEntity; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Vector3f; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.util.Mth; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class PedestalItemRenderer implements BlockEntityRenderer { + public PedestalItemRenderer(BlockEntityRendererProvider.Context ctx) { + super(); + } + + @Override + public void render( + T blockEntity, + float tickDelta, + PoseStack matrices, + MultiBufferSource vertexConsumers, + int light, + int overlay + ) { + Level world = blockEntity.getLevel(); + if (world == null || blockEntity.isEmpty()) return; + + BlockState state = world.getBlockState(blockEntity.getBlockPos()); + if (!(state.getBlock() instanceof PedestalBlock)) return; + + ItemStack activeItem = blockEntity.getItem(0); + + matrices.pushPose(); + Minecraft minecraft = Minecraft.getInstance(); + BakedModel model = minecraft.getItemRenderer().getModel(activeItem, world, null, 0); + Vector3f translate = model.getTransforms().ground.translation; + PedestalBlock pedestal = (PedestalBlock) state.getBlock(); + matrices.translate(translate.x() + 0.5, translate.y() + pedestal.getHeight(state), translate.z() + 0.5); + if (activeItem.getItem() instanceof BlockItem) { + matrices.scale(1.5F, 1.5F, 1.5F); + } else { + matrices.scale(1.25F, 1.25F, 1.25F); + } + int age = (int) (minecraft.level.getGameTime() % 314); + if (state.is(EndBlocks.ETERNAL_PEDESTAL) && state.getValue(EternalPedestal.ACTIVATED)) { + float[] colors = EternalCrystalRenderer.colors(age); + int y = blockEntity.getBlockPos().getY(); + + BeamRenderer.renderLightBeam( + matrices, + vertexConsumers, + age, + tickDelta, + -y, + 1024 - y, + colors, + 0.25F, + 0.13F, + 0.16F + ); + float altitude = Mth.sin((age + tickDelta) / 10.0F) * 0.1F + 0.1F; + matrices.translate(0.0D, altitude, 0.0D); + } + if (activeItem.getItem() == Items.END_CRYSTAL) { + EndCrystalRenderer.render(age, 314, tickDelta, matrices, vertexConsumers, light); + } else if (activeItem.getItem() == EndItems.ETERNAL_CRYSTAL) { + EternalCrystalRenderer.render(age, tickDelta, matrices, vertexConsumers, light); + } else { + float rotation = (age + tickDelta) / 25.0F + 6.0F; + matrices.mulPose(Vector3f.YP.rotation(rotation)); + minecraft.getItemRenderer() + .render( + activeItem, + ItemTransforms.TransformType.GROUND, + false, + matrices, + vertexConsumers, + light, + overlay, + model + ); + } + matrices.popPose(); + } +} diff --git a/src/main/java/org/betterx/betterend/commands/CommandRegistry.java b/src/main/java/org/betterx/betterend/commands/CommandRegistry.java new file mode 100644 index 00000000..8abf738d --- /dev/null +++ b/src/main/java/org/betterx/betterend/commands/CommandRegistry.java @@ -0,0 +1,211 @@ +package org.betterx.betterend.commands; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.poi.BCLPoiType; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.registry.EndBiomes; +import org.betterx.betterend.registry.EndPoiTypes; +import org.betterx.betterend.world.biome.EndBiome; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; +import com.mojang.datafixers.util.Either; +import com.mojang.datafixers.util.Pair; +import com.mojang.math.Vector3d; +import net.minecraft.ChatFormatting; +import net.minecraft.commands.CommandBuildContext; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.commands.arguments.ResourceOrTagLocationArgument; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Holder; +import net.minecraft.data.BuiltinRegistries; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.commands.LocateCommand; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; + +import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; + +import java.util.*; + +public class CommandRegistry { + public static void register() { + CommandRegistrationCallback.EVENT.register(CommandRegistry::register); + } + + private static void register( + CommandDispatcher dispatcher, + CommandBuildContext commandBuildContext, + Commands.CommandSelection commandSelection + ) { + dispatcher.register( + Commands.literal("be") + .requires(source -> source.hasPermission(Commands.LEVEL_OWNERS)) + .then(Commands.literal("locate_portal") + .requires(source -> source.hasPermission(Commands.LEVEL_OWNERS)) + .executes(ctx -> find_poi(ctx, EndPoiTypes.ETERNAL_PORTAL_INACTIVE)) + ) + .then(Commands.literal("tpnext") + .requires(source -> source.hasPermission(Commands.LEVEL_OWNERS)) + .executes(ctx -> teleportToNextBiome(ctx)) + ) + ); + } + + private static final Map, BlockState> biomeMap = new HashMap<>(); + private static final int biomeMapIdx = 0; + private static final BlockState[] states = { + Blocks.RED_STAINED_GLASS.defaultBlockState(), + Blocks.BLUE_STAINED_GLASS.defaultBlockState(), + Blocks.YELLOW_STAINED_GLASS.defaultBlockState(), + Blocks.LIME_STAINED_GLASS.defaultBlockState(), + Blocks.PINK_STAINED_GLASS.defaultBlockState(), + Blocks.GREEN_STAINED_GLASS.defaultBlockState(), + Blocks.WHITE_STAINED_GLASS.defaultBlockState(), + Blocks.BLACK_STAINED_GLASS.defaultBlockState(), + Blocks.ORANGE_STAINED_GLASS.defaultBlockState(), + Blocks.LIGHT_BLUE_STAINED_GLASS.defaultBlockState() + }; + private static final BlockState[] states2 = { + Blocks.RED_CONCRETE.defaultBlockState(), + Blocks.BLUE_CONCRETE.defaultBlockState(), + Blocks.YELLOW_CONCRETE.defaultBlockState(), + Blocks.LIME_CONCRETE.defaultBlockState(), + Blocks.PINK_CONCRETE.defaultBlockState(), + Blocks.GREEN_CONCRETE.defaultBlockState(), + Blocks.WHITE_CONCRETE.defaultBlockState(), + Blocks.BLACK_CONCRETE.defaultBlockState(), + Blocks.ORANGE_CONCRETE.defaultBlockState(), + Blocks.LIGHT_BLUE_CONCRETE.defaultBlockState() + }; + + + private static int find_poi(CommandContext ctx, BCLPoiType poi) throws CommandSyntaxException { + final CommandSourceStack source = ctx.getSource(); + final ServerPlayer player = source.getPlayerOrException(); + Vec3 pos = source.getPosition(); + final ServerLevel level = source.getLevel(); + MutableBlockPos mPos = new BlockPos(pos).mutable(); + System.out.println("Searching POI: " + poi.key); + Optional found = poi.findPoiAround(level, mPos, false, level.getWorldBorder()); + System.out.println("Found at: " + found.orElse(null)); + if (found.isPresent()) { + BlocksHelper.setWithoutUpdate(level, found.get(), Blocks.YELLOW_CONCRETE); + BlocksHelper.setWithoutUpdate(level, mPos, Blocks.LIGHT_BLUE_CONCRETE); + } else { + BlocksHelper.setWithoutUpdate(level, mPos, Blocks.RED_CONCRETE); + } + return Command.SINGLE_SUCCESS; + } + + + private static int biomeIndex = 0; + private static final int MAX_SEARCH_RADIUS = 6400 * 2; + private static final int SAMPLE_RESOLUTION_HORIZONTAL = 32; + private static final int SAMPLE_RESOLUTION_VERTICAL = 64; + private static final DynamicCommandExceptionType ERROR_BIOME_NOT_FOUND = new DynamicCommandExceptionType( + (object) -> { + return Component.literal("The next biome (" + object + ") was not found."); + }); + + private static int teleportToNextBiome(CommandContext ctx) throws CommandSyntaxException { + final CommandSourceStack source = ctx.getSource(); + List biomes = EndBiomes.ALL_BE_BIOMES; + + if (biomeIndex < 0 || biomeIndex >= biomes.size()) { + source.sendFailure(Component.literal("Failed to find the next Biome...") + .setStyle(Style.EMPTY.withColor(ChatFormatting.RED))); + return 0; + } + final BCLBiome biome = biomes.get(biomeIndex); + source.sendSuccess(Component.literal("Locating Biome " + biome) + .setStyle(Style.EMPTY.withColor(ChatFormatting.DARK_GREEN)), false); + biomeIndex = (biomeIndex + 1) % biomes.size(); + + final BlockPos currentPosition = new BlockPos(source.getPosition()); + final BlockPos biomePosition = source.getLevel() + .findClosestBiome3d( + b -> b.unwrapKey().orElseThrow().location().equals(biome.getID()), + currentPosition, + MAX_SEARCH_RADIUS, + SAMPLE_RESOLUTION_HORIZONTAL, + SAMPLE_RESOLUTION_VERTICAL + ) + .getFirst(); + final String biomeName = biome.toString(); + + if (biomePosition == null) { + throw ERROR_BIOME_NOT_FOUND.create(biomeName); + } else { + final ServerPlayer player = source.getPlayerOrException(); + BlockState state; + BlockPos target; + double yPos = source.getPosition().y(); + boolean didWrap = false; + do { + target = new BlockPos(biomePosition.getX(), yPos, biomePosition.getZ()); + state = player.level.getBlockState(target); + yPos--; + if (yPos <= player.level.getMinBuildHeight() + 1) { + if (didWrap) break; + yPos = 127; + didWrap = true; + } + } while (!state.isAir() && yPos > player.level.getMinBuildHeight() && yPos < player.level.getMaxBuildHeight()); + Vector3d targetPlayerPos = new Vector3d(target.getX() + 0.5, target.getY() - 1, target.getZ() + 0.5); + + player.connection.teleport( + targetPlayerPos.x, + targetPlayerPos.y, + targetPlayerPos.z, + 0, + 0, + Collections.EMPTY_SET + ); + ResourceOrTagLocationArgument.Result result = new ResourceOrTagLocationArgument.Result() { + @Override + public Either unwrap() { + return Either.left(biome.getBiomeKey()); + } + + @Override + public Optional cast(ResourceKey resourceKey) { + return Optional.empty(); + } + + @Override + public String asPrintable() { + return biomeName; + } + + @Override + public boolean test(Object o) { + return false; + } + }; + ResourceKey a = biome.getBiomeKey(); + Holder h = BuiltinRegistries.BIOME.getHolder(a).orElseThrow(); + return LocateCommand.showLocateResult( + source, + result, + currentPosition, + new Pair<>(biomePosition, h), + "commands.locatebiome.success", + false + ); + } + } +} + diff --git a/src/main/java/org/betterx/betterend/complexmaterials/ColoredMaterial.java b/src/main/java/org/betterx/betterend/complexmaterials/ColoredMaterial.java new file mode 100644 index 00000000..f1b643c9 --- /dev/null +++ b/src/main/java/org/betterx/betterend/complexmaterials/ColoredMaterial.java @@ -0,0 +1,80 @@ +package org.betterx.betterend.complexmaterials; + +import org.betterx.bclib.recipes.GridRecipe; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.Registry; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.DyeItem; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +import com.google.common.collect.Maps; + +import java.util.Map; +import java.util.function.Function; + +public class ColoredMaterial { + private static final Map DYES = Maps.newHashMap(); + private static final Map COLORS = Maps.newHashMap(); + private final Map colors = Maps.newHashMap(); + + public ColoredMaterial(Function constructor, Block source, boolean craftEight) { + this(constructor, source, COLORS, DYES, craftEight); + } + + public ColoredMaterial( + Function constructor, + Block source, + Map colors, + Map dyes, + boolean craftEight + ) { + String id = Registry.BLOCK.getKey(source).getPath(); + colors.forEach((color, name) -> { + String blockName = id + "_" + name; + Block block = constructor.apply(FabricBlockSettings.copyOf(source).mapColor(MaterialColor.COLOR_BLACK)); + EndBlocks.registerBlock(blockName, block); + if (craftEight) { + GridRecipe.make(BetterEnd.MOD_ID, blockName, block) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(8) + .setShape("###", "#D#", "###") + .addMaterial('#', source) + .addMaterial('D', dyes.get(color)) + .build(); + } else { + GridRecipe.make(BetterEnd.MOD_ID, blockName, block) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#D") + .addMaterial('#', source) + .addMaterial('D', dyes.get(color)) + .build(); + } + this.colors.put(color, block); + BlocksHelper.addBlockColor(block, color); + }); + } + + public Block getByColor(DyeColor color) { + return colors.get(color.getMaterialColor().col); + } + + public Block getByColor(int color) { + return colors.get(color); + } + + static { + for (DyeColor color : DyeColor.values()) { + int colorRGB = color.getMaterialColor().col; + COLORS.put(colorRGB, color.getName()); + DYES.put(colorRGB, DyeItem.byColor(color)); + } + } +} diff --git a/src/main/java/org/betterx/betterend/complexmaterials/CrystalSubblocksMaterial.java b/src/main/java/org/betterx/betterend/complexmaterials/CrystalSubblocksMaterial.java new file mode 100644 index 00000000..d2c10b2b --- /dev/null +++ b/src/main/java/org/betterx/betterend/complexmaterials/CrystalSubblocksMaterial.java @@ -0,0 +1,135 @@ +package org.betterx.betterend.complexmaterials; + +import org.betterx.bclib.blocks.BaseSlabBlock; +import org.betterx.bclib.blocks.BaseStairsBlock; +import org.betterx.bclib.blocks.BaseWallBlock; +import org.betterx.bclib.recipes.GridRecipe; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.EndPedestal; +import org.betterx.betterend.blocks.basis.LitBaseBlock; +import org.betterx.betterend.blocks.basis.LitPillarBlock; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.recipe.CraftingRecipes; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.TagManager; + +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.level.block.Block; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class CrystalSubblocksMaterial { + public final Block polished; + public final Block tiles; + public final Block pillar; + public final Block stairs; + public final Block slab; + public final Block wall; + public final Block pedestal; + public final Block bricks; + public final Block brick_stairs; + public final Block brick_slab; + public final Block brick_wall; + + public CrystalSubblocksMaterial(String name, Block source) { + FabricBlockSettings material = FabricBlockSettings.copyOf(source); + polished = EndBlocks.registerBlock(name + "_polished", new LitBaseBlock(material)); + tiles = EndBlocks.registerBlock(name + "_tiles", new LitBaseBlock(material)); + pillar = EndBlocks.registerBlock(name + "_pillar", new LitPillarBlock(material)); + stairs = EndBlocks.registerBlock(name + "_stairs", new BaseStairsBlock(source)); + slab = EndBlocks.registerBlock(name + "_slab", new BaseSlabBlock(source)); + wall = EndBlocks.registerBlock(name + "_wall", new BaseWallBlock(source)); + pedestal = EndBlocks.registerBlock(name + "_pedestal", new EndPedestal(source)); + bricks = EndBlocks.registerBlock(name + "_bricks", new LitBaseBlock(material)); + brick_stairs = EndBlocks.registerBlock(name + "_bricks_stairs", new BaseStairsBlock(bricks)); + brick_slab = EndBlocks.registerBlock(name + "_bricks_slab", new BaseSlabBlock(bricks)); + brick_wall = EndBlocks.registerBlock(name + "_bricks_wall", new BaseWallBlock(bricks)); + + // Recipes // + GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks", bricks) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setShape("##", "##") + .addMaterial('#', source) + .setGroup("end_bricks") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_polished", polished) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setShape("##", "##") + .addMaterial('#', bricks) + .setGroup("end_tile") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_tiles", tiles) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setShape("##", "##") + .addMaterial('#', polished) + .setGroup("end_small_tile") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_pillar", pillar) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("#", "#") + .addMaterial('#', slab) + .setGroup("end_pillar") + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, name + "_stairs", stairs) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setShape("# ", "## ", "###") + .addMaterial('#', source) + .setGroup("end_stone_stairs") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_slab", slab) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(6) + .setShape("###") + .addMaterial('#', source) + .setGroup("end_stone_slabs") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks_stairs", brick_stairs) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setShape("# ", "## ", "###") + .addMaterial('#', bricks) + .setGroup("end_stone_stairs") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks_slab", brick_slab) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(6) + .setShape("###") + .addMaterial('#', bricks) + .setGroup("end_stone_slabs") + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, name + "_wall", wall) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(6) + .setShape("###", "###") + .addMaterial('#', source) + .setGroup("end_wall") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks_wall", brick_wall) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(6) + .setShape("###", "###") + .addMaterial('#', bricks) + .setGroup("end_wall") + .build(); + + CraftingRecipes.registerPedestal(name + "_pedestal", pedestal, slab, pillar); + + // Item Tags // + TagManager.ITEMS.add(ItemTags.SLABS, slab.asItem(), brick_slab.asItem()); + TagManager.ITEMS.add(ItemTags.STONE_BRICKS, bricks.asItem()); + TagManager.ITEMS.add(ItemTags.STONE_CRAFTING_MATERIALS, source.asItem()); + TagManager.ITEMS.add(ItemTags.STONE_TOOL_MATERIALS, source.asItem()); + + // Block Tags // + TagManager.BLOCKS.add(BlockTags.STONE_BRICKS, bricks); + TagManager.BLOCKS.add(BlockTags.WALLS, wall, brick_wall); + TagManager.BLOCKS.add(BlockTags.SLABS, slab, brick_slab); + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/complexmaterials/EndWoodenComplexMaterial.java b/src/main/java/org/betterx/betterend/complexmaterials/EndWoodenComplexMaterial.java new file mode 100644 index 00000000..beae71f7 --- /dev/null +++ b/src/main/java/org/betterx/betterend/complexmaterials/EndWoodenComplexMaterial.java @@ -0,0 +1,50 @@ +package org.betterx.betterend.complexmaterials; + +import org.betterx.bclib.complexmaterials.WoodenComplexMaterial; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.MaterialColor; + +public class EndWoodenComplexMaterial extends WoodenComplexMaterial { + private Block bark; + private Block log; + + public EndWoodenComplexMaterial(String name, MaterialColor woodColor, MaterialColor planksColor) { + super(BetterEnd.MOD_ID, name, name, woodColor, planksColor); + } + + public EndWoodenComplexMaterial init() { + return (EndWoodenComplexMaterial) super.init( + EndBlocks.getBlockRegistry(), + EndItems.getItemRegistry(), + Configs.RECIPE_CONFIG + ); + } + + public boolean isTreeLog(Block block) { + return block == getLog() || block == getBark(); + } + + public boolean isTreeLog(BlockState state) { + return isTreeLog(state.getBlock()); + } + + public Block getLog() { + if (log == null) { + log = getBlock("log"); + } + return log; + } + + public Block getBark() { + if (bark == null) { + bark = getBlock("bark"); + } + return bark; + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/complexmaterials/MetalMaterial.java b/src/main/java/org/betterx/betterend/complexmaterials/MetalMaterial.java new file mode 100644 index 00000000..14c0092f --- /dev/null +++ b/src/main/java/org/betterx/betterend/complexmaterials/MetalMaterial.java @@ -0,0 +1,532 @@ +package org.betterx.betterend.complexmaterials; + +import org.betterx.bclib.blocks.*; +import org.betterx.bclib.items.ModelProviderItem; +import org.betterx.bclib.items.tool.BaseAxeItem; +import org.betterx.bclib.items.tool.BaseHoeItem; +import org.betterx.bclib.items.tool.BaseShovelItem; +import org.betterx.bclib.items.tool.BaseSwordItem; +import org.betterx.bclib.recipes.AnvilRecipe; +import org.betterx.bclib.recipes.FurnaceRecipe; +import org.betterx.bclib.recipes.GridRecipe; +import org.betterx.bclib.recipes.SmithingTableRecipe; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.BulbVineLanternBlock; +import org.betterx.betterend.blocks.BulbVineLanternColoredBlock; +import org.betterx.betterend.blocks.ChandelierBlock; +import org.betterx.betterend.blocks.basis.EndAnvilBlock; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.item.EndArmorItem; +import org.betterx.betterend.item.tool.EndHammerItem; +import org.betterx.betterend.item.tool.EndPickaxe; +import org.betterx.betterend.recipe.builders.AlloyingRecipeBuilder; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; +import org.betterx.worlds.together.tag.v3.TagManager; + +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.ItemTags; +import net.minecraft.tags.TagKey; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ArmorMaterial; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Item.Properties; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.Tier; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class MetalMaterial { + public final Block ore; + public final Block block; + public final Block tile; + public final Block bars; + public final Block pressurePlate; + public final Block door; + public final Block trapdoor; + public final Block chain; + public final Block stairs; + public final Block slab; + + public final Block chandelier; + public final Block bulb_lantern; + public final ColoredMaterial bulb_lantern_colored; + + public final Block anvilBlock; + + public final Item rawOre; + public final Item nugget; + public final Item ingot; + + public final Item shovelHead; + public final Item pickaxeHead; + public final Item axeHead; + public final Item hoeHead; + public final Item swordBlade; + public final Item swordHandle; + + public final Item shovel; + public final Item sword; + public final Item pickaxe; + public final Item axe; + public final Item hoe; + public final Item hammer; + + public final Item forgedPlate; + public final Item helmet; + public final Item chestplate; + public final Item leggings; + public final Item boots; + + public final TagKey alloyingOre; + + public static MetalMaterial makeNormal( + String name, + MaterialColor color, + Tier material, + ArmorMaterial armor, + int anvilAndToolLevel + ) { + return new MetalMaterial( + name, + true, + FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).mapColor(color), + EndItems.makeEndItemSettings(), + material, + armor, + anvilAndToolLevel + ); + } + + public static MetalMaterial makeNormal( + String name, + MaterialColor color, + float hardness, + float resistance, + Tier material, + ArmorMaterial armor, + int anvilAndToolLevel + ) { + return new MetalMaterial( + name, + true, + FabricBlockSettings.copyOf(Blocks.IRON_BLOCK) + .mapColor(color) + .hardness(hardness) + .resistance(resistance), + EndItems.makeEndItemSettings(), + material, + armor, + anvilAndToolLevel + ); + } + + public static MetalMaterial makeOreless( + String name, + MaterialColor color, + Tier material, + ArmorMaterial armor, + int anvilAndToolLevel + ) { + return new MetalMaterial( + name, + false, + FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).mapColor(color), + EndItems.makeEndItemSettings(), + material, + armor, + anvilAndToolLevel + ); + } + + public static MetalMaterial makeOreless( + String name, + MaterialColor color, + float hardness, + float resistance, + Tier material, + ArmorMaterial armor, + int anvilAndToolLevel + ) { + return new MetalMaterial( + name, + false, + FabricBlockSettings.copyOf(Blocks.IRON_BLOCK) + .mapColor(color) + .hardness(hardness) + .resistance(resistance), + EndItems.makeEndItemSettings(), + material, + armor, + anvilAndToolLevel + ); + } + + private MetalMaterial( + String name, + boolean hasOre, + FabricBlockSettings settings, + Properties itemSettings, + Tier material, + ArmorMaterial armor, + int anvilAndToolLevel + ) { + BlockBehaviour.Properties lanternProperties = FabricBlockSettings.copyOf(settings) + .hardness(1) + .resistance(1) + .luminance(15) + .sound(SoundType.LANTERN); + final int level = material.getLevel(); + + rawOre = hasOre ? EndItems.registerEndItem(name + "_raw", new ModelProviderItem(itemSettings)) : null; + ore = hasOre ? EndBlocks.registerBlock(name + "_ore", new BaseOreBlock(() -> rawOre, 1, 3, 1)) : null; + alloyingOre = hasOre ? TagManager.ITEMS.makeTag(BetterEnd.MOD_ID, name + "_alloying") : null; + if (hasOre) { + TagManager.ITEMS.add(alloyingOre, ore.asItem(), rawOre); + } + + block = EndBlocks.registerBlock(name + "_block", new BaseBlock(settings)); + tile = EndBlocks.registerBlock(name + "_tile", new BaseBlock(settings)); + stairs = EndBlocks.registerBlock(name + "_stairs", new BaseStairsBlock(tile)); + slab = EndBlocks.registerBlock(name + "_slab", new BaseSlabBlock(tile)); + door = EndBlocks.registerBlock(name + "_door", new BaseDoorBlock(block)); + trapdoor = EndBlocks.registerBlock(name + "_trapdoor", new BaseTrapdoorBlock(block)); + bars = EndBlocks.registerBlock(name + "_bars", new BaseMetalBarsBlock(block)); + chain = EndBlocks.registerBlock(name + "_chain", new BaseChainBlock(block.defaultMaterialColor())); + pressurePlate = EndBlocks.registerBlock(name + "_plate", new WoodenPressurePlateBlock(block)); + + chandelier = EndBlocks.registerBlock(name + "_chandelier", new ChandelierBlock(block)); + bulb_lantern = EndBlocks.registerBlock(name + "_bulb_lantern", new BulbVineLanternBlock(lanternProperties)); + bulb_lantern_colored = new ColoredMaterial(BulbVineLanternColoredBlock::new, bulb_lantern, false); + + nugget = EndItems.registerEndItem(name + "_nugget", new ModelProviderItem(itemSettings)); + ingot = EndItems.registerEndItem(name + "_ingot", new ModelProviderItem(itemSettings)); + + shovelHead = EndItems.registerEndItem(name + "_shovel_head"); + pickaxeHead = EndItems.registerEndItem(name + "_pickaxe_head"); + axeHead = EndItems.registerEndItem(name + "_axe_head"); + hoeHead = EndItems.registerEndItem(name + "_hoe_head"); + swordBlade = EndItems.registerEndItem(name + "_sword_blade"); + swordHandle = EndItems.registerEndItem(name + "_sword_handle"); + + shovel = EndItems.registerEndTool(name + "_shovel", new BaseShovelItem(material, 1.5F, -3.0F, itemSettings)); + sword = EndItems.registerEndTool(name + "_sword", new BaseSwordItem(material, 3, -2.4F, itemSettings)); + pickaxe = EndItems.registerEndTool(name + "_pickaxe", new EndPickaxe(material, 1, -2.8F, itemSettings)); + axe = EndItems.registerEndTool(name + "_axe", new BaseAxeItem(material, 6.0F, -3.0F, itemSettings)); + hoe = EndItems.registerEndTool(name + "_hoe", new BaseHoeItem(material, -3, 0.0F, itemSettings)); + hammer = EndItems.registerEndTool( + name + "_hammer", + new EndHammerItem(material, 5.0F, -3.2F, 0.3D, itemSettings) + ); + + forgedPlate = EndItems.registerEndItem(name + "_forged_plate"); + helmet = EndItems.registerEndItem(name + "_helmet", new EndArmorItem(armor, EquipmentSlot.HEAD, itemSettings)); + chestplate = EndItems.registerEndItem( + name + "_chestplate", + new EndArmorItem(armor, EquipmentSlot.CHEST, itemSettings) + ); + leggings = EndItems.registerEndItem( + name + "_leggings", + new EndArmorItem(armor, EquipmentSlot.LEGS, itemSettings) + ); + boots = EndItems.registerEndItem(name + "_boots", new EndArmorItem(armor, EquipmentSlot.FEET, itemSettings)); + + anvilBlock = EndBlocks.registerBlock( + name + "_anvil", + new EndAnvilBlock(this, block.defaultMaterialColor(), anvilAndToolLevel) + ); + + if (hasOre) { + FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_ingot_furnace_ore", ore, ingot) + .checkConfig(Configs.RECIPE_CONFIG) + .setGroup("end_ingot") + .buildWithBlasting(); + FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_ingot_furnace_raw", rawOre, ingot) + .checkConfig(Configs.RECIPE_CONFIG) + .setGroup("end_ingot") + .buildWithBlasting(); + AlloyingRecipeBuilder.create(name + "_ingot_alloy") + .setInput(alloyingOre, alloyingOre) + .setOutput(ingot, 3) + .setExpiriense(2.1F) + .build(); + } + + // Basic recipes + GridRecipe.make(BetterEnd.MOD_ID, name + "_ingot_from_nuggets", ingot) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("###", "###", "###") + .addMaterial('#', nugget) + .setGroup("end_metal_ingots_nug") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_nuggets_from_ingot", nugget) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(9) + .setList("#") + .addMaterial('#', ingot) + .setGroup("end_metal_nuggets_ing") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_block", block) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("###", "###", "###") + .addMaterial('#', ingot) + .setGroup("end_metal_blocks") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_ingot_from_block", ingot) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(9) + .setList("#") + .addMaterial('#', block) + .setGroup("end_metal_ingots") + .build(); + + // Block recipes + GridRecipe.make(BetterEnd.MOD_ID, name + "_tile", tile) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setShape("##", "##") + .addMaterial('#', block) + .setGroup("end_metal_tiles") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_bars", bars) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(16) + .setShape("###", "###") + .addMaterial('#', ingot) + .setGroup("end_metal_bars") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_pressure_plate", pressurePlate) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("##") + .addMaterial('#', ingot) + .setGroup("end_metal_plates") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_door", door) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(3) + .setShape("##", "##", "##") + .addMaterial('#', ingot) + .setGroup("end_metal_doors") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_trapdoor", trapdoor) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("##", "##") + .addMaterial('#', ingot) + .setGroup("end_metal_trapdoors") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_stairs", stairs) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setShape("# ", "## ", "###") + .addMaterial('#', block, tile) + .setGroup("end_metal_stairs") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_slab", slab) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(6) + .setShape("###") + .addMaterial('#', block, tile) + .setGroup("end_metal_slabs") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_chain", chain) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("N", "#", "N") + .addMaterial('#', ingot) + .addMaterial('N', nugget) + .setGroup("end_metal_chain") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_anvil", anvilBlock) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("###", " I ", "III") + .addMaterial('#', block, tile) + .addMaterial('I', ingot) + .setGroup("end_metal_anvil") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_bulb_lantern", bulb_lantern) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("C", "I", "#") + .addMaterial('C', chain) + .addMaterial('I', ingot) + .addMaterial('#', EndItems.GLOWING_BULB) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, name + "_chandelier", chandelier) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("I#I", " # ") + .addMaterial('#', ingot) + .addMaterial('I', EndItems.LUMECORN_ROD) + .setGroup("end_metal_chandelier") + .build(); + + // Tools & armor into nuggets + FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_axe_nugget", axe, nugget) + .checkConfig(Configs.RECIPE_CONFIG) + .setGroup("end_nugget") + .buildWithBlasting(); + FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_hoe_nugget", hoe, nugget) + .checkConfig(Configs.RECIPE_CONFIG) + .setGroup("end_nugget") + .buildWithBlasting(); + FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_pickaxe_nugget", pickaxe, nugget) + .checkConfig(Configs.RECIPE_CONFIG) + .setGroup("end_nugget") + .buildWithBlasting(); + FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_sword_nugget", sword, nugget) + .checkConfig(Configs.RECIPE_CONFIG) + .setGroup("end_nugget") + .buildWithBlasting(); + FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_hammer_nugget", hammer, nugget) + .checkConfig(Configs.RECIPE_CONFIG) + .setGroup("end_nugget") + .buildWithBlasting(); + FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_helmet_nugget", helmet, nugget) + .checkConfig(Configs.RECIPE_CONFIG) + .setGroup("end_nugget") + .buildWithBlasting(); + FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_chestplate_nugget", chestplate, nugget) + .checkConfig(Configs.RECIPE_CONFIG) + .setGroup("end_nugget") + .buildWithBlasting(); + FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_leggings_nugget", leggings, nugget) + .checkConfig(Configs.RECIPE_CONFIG) + .setGroup("end_nugget") + .buildWithBlasting(); + FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_boots_nugget", boots, nugget) + .checkConfig(Configs.RECIPE_CONFIG) + .setGroup("end_nugget") + .buildWithBlasting(); + + // Tool parts from ingots + AnvilRecipe.create(name + "_shovel_head") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(ingot) + .setOutput(shovelHead) + .setAnvilLevel(anvilAndToolLevel) + .setToolLevel(level) + .setDamage(level) + .build(); + AnvilRecipe.create(name + "_pickaxe_head") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(ingot) + .setInputCount(3) + .setOutput(pickaxeHead) + .setAnvilLevel(anvilAndToolLevel) + .setToolLevel(level) + .setDamage(level) + .build(); + AnvilRecipe.create(name + "_axe_head") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(ingot) + .setInputCount(3) + .setOutput(axeHead) + .setAnvilLevel(anvilAndToolLevel) + .setToolLevel(level) + .setDamage(level) + .build(); + AnvilRecipe.create(name + "_hoe_head") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(ingot) + .setInputCount(2) + .setOutput(hoeHead) + .setAnvilLevel(anvilAndToolLevel) + .setToolLevel(level) + .setDamage(level) + .build(); + AnvilRecipe.create(name + "_sword_blade") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(ingot) + .setOutput(swordBlade) + .setAnvilLevel(anvilAndToolLevel) + .setToolLevel(level) + .setDamage(level) + .build(); + AnvilRecipe.create(name + "_forged_plate") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(ingot) + .setOutput(forgedPlate) + .setAnvilLevel(anvilAndToolLevel) + .setToolLevel(level) + .setDamage(level) + .build(); + + // Tools from parts + SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_hammer") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(hammer) + .setBase(block) + .setAddition(Items.STICK) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_axe") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(axe) + .setBase(axeHead) + .setAddition(Items.STICK) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_pickaxe") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(pickaxe) + .setBase(pickaxeHead) + .setAddition(Items.STICK) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_hoe") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(hoe) + .setBase(hoeHead) + .setAddition(Items.STICK) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_sword_handle") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(swordHandle) + .setBase(ingot) + .setAddition(Items.STICK) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_sword") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(sword) + .setBase(swordBlade) + .setAddition(swordHandle) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_shovel") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(shovel) + .setBase(shovelHead) + .setAddition(Items.STICK) + .build(); + + // Armor crafting + GridRecipe.make(BetterEnd.MOD_ID, name + "_helmet", helmet) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("###", "# #") + .addMaterial('#', forgedPlate) + .setGroup("end_metal_helmets") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_chestplate", chestplate) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("# #", "###", "###") + .addMaterial('#', forgedPlate) + .setGroup("end_metal_chestplates") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_leggings", leggings) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("###", "# #", "# #") + .addMaterial('#', forgedPlate) + .setGroup("end_metal_leggings") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_boots", boots) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("# #", "# #") + .addMaterial('#', forgedPlate) + .setGroup("end_metal_boots") + .build(); + + TagManager.BLOCKS.add(BlockTags.ANVIL, anvilBlock); + TagManager.BLOCKS.add(BlockTags.BEACON_BASE_BLOCKS, block); + TagManager.ITEMS.add(ItemTags.BEACON_PAYMENT_ITEMS, ingot); + TagManager.BLOCKS.add(BlockTags.DRAGON_IMMUNE, ore, bars); + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/complexmaterials/StoneMaterial.java b/src/main/java/org/betterx/betterend/complexmaterials/StoneMaterial.java new file mode 100644 index 00000000..9e6cbdaf --- /dev/null +++ b/src/main/java/org/betterx/betterend/complexmaterials/StoneMaterial.java @@ -0,0 +1,199 @@ +package org.betterx.betterend.complexmaterials; + +import org.betterx.bclib.blocks.*; +import org.betterx.bclib.recipes.GridRecipe; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.EndPedestal; +import org.betterx.betterend.blocks.FlowerPotBlock; +import org.betterx.betterend.blocks.basis.StoneLanternBlock; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.recipe.CraftingRecipes; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; +import org.betterx.worlds.together.tag.v3.CommonItemTags; +import org.betterx.worlds.together.tag.v3.TagManager; + +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; + +public class StoneMaterial { + public final Block stone; + + public final Block polished; + public final Block tiles; + public final Block pillar; + public final Block stairs; + public final Block slab; + public final Block wall; + public final Block button; + public final Block pressurePlate; + public final Block pedestal; + public final Block lantern; + + public final Block bricks; + public final Block brickStairs; + public final Block brickSlab; + public final Block brickWall; + public final Block furnace; + public final Block flowerPot; + + public static FabricBlockSettings createMaterial(MaterialColor color) { + return FabricBlockSettings.copyOf(Blocks.END_STONE).mapColor(color); + } + + public StoneMaterial(String name, MaterialColor color) { + FabricBlockSettings material = createMaterial(color); + + stone = EndBlocks.registerBlock(name, new BaseBlock(material)); + polished = EndBlocks.registerBlock(name + "_polished", new BaseBlock(material)); + tiles = EndBlocks.registerBlock(name + "_tiles", new BaseBlock(material)); + pillar = EndBlocks.registerBlock(name + "_pillar", new BaseRotatedPillarBlock(material)); + stairs = EndBlocks.registerBlock(name + "_stairs", new BaseStairsBlock(stone)); + slab = EndBlocks.registerBlock(name + "_slab", new BaseSlabBlock(stone)); + wall = EndBlocks.registerBlock(name + "_wall", new BaseWallBlock(stone)); + button = EndBlocks.registerBlock(name + "_button", new BaseStoneButtonBlock(stone)); + pressurePlate = EndBlocks.registerBlock(name + "_plate", new StonePressurePlateBlock(stone)); + pedestal = EndBlocks.registerBlock(name + "_pedestal", new EndPedestal(stone)); + lantern = EndBlocks.registerBlock(name + "_lantern", new StoneLanternBlock(stone)); + + bricks = EndBlocks.registerBlock(name + "_bricks", new BaseBlock(material)); + brickStairs = EndBlocks.registerBlock(name + "_bricks_stairs", new BaseStairsBlock(bricks)); + brickSlab = EndBlocks.registerBlock(name + "_bricks_slab", new BaseSlabBlock(bricks)); + brickWall = EndBlocks.registerBlock(name + "_bricks_wall", new BaseWallBlock(bricks)); + furnace = EndBlocks.registerBlock(name + "_furnace", new BaseFurnaceBlock(bricks)); + flowerPot = EndBlocks.registerBlock(name + "_flower_pot", new FlowerPotBlock(bricks)); + + // Recipes // + GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks", bricks) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setShape("##", "##") + .addMaterial('#', stone) + .setGroup("end_bricks") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_polished", polished) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setShape("##", "##") + .addMaterial('#', bricks) + .setGroup("end_tile") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_tiles", tiles) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setShape("##", "##") + .addMaterial('#', polished) + .setGroup("end_small_tile") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_pillar", pillar) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("#", "#") + .addMaterial('#', slab) + .setGroup("end_pillar") + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, name + "_stairs", stairs) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setShape("# ", "## ", "###") + .addMaterial('#', stone) + .setGroup("end_stone_stairs") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_slab", slab) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(6) + .setShape("###") + .addMaterial('#', stone) + .setGroup("end_stone_slabs") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks_stairs", brickStairs) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setShape("# ", "## ", "###") + .addMaterial('#', bricks) + .setGroup("end_stone_stairs") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks_slab", brickSlab) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(6) + .setShape("###") + .addMaterial('#', bricks) + .setGroup("end_stone_slabs") + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, name + "_wall", wall) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(6) + .setShape("###", "###") + .addMaterial('#', stone) + .setGroup("end_wall") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks_wall", brickWall) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(6) + .setShape("###", "###") + .addMaterial('#', bricks) + .setGroup("end_wall") + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, name + "_button", button) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', stone) + .setGroup("end_stone_buttons") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_pressure_plate", pressurePlate) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("##") + .addMaterial('#', stone) + .setGroup("end_stone_plates") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_lantern", lantern) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("S", "#", "S") + .addMaterial('#', EndItems.CRYSTAL_SHARDS) + .addMaterial('S', slab, brickSlab) + .setGroup("end_stone_lanterns") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_furnace", furnace) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("###", "# #", "###") + .addMaterial('#', stone) + .setGroup("end_stone_ITEM_FURNACES") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, name + "_flower_pot", flowerPot) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(3) + .setShape("# #", " # ") + .addMaterial('#', bricks) + .setGroup("end_pots") + .build(); + + CraftingRecipes.registerPedestal(name + "_pedestal", pedestal, slab, pillar); + + // Item Tags // + TagManager.ITEMS.add(ItemTags.SLABS, slab.asItem(), brickSlab.asItem()); + TagManager.ITEMS.add(ItemTags.STONE_BRICKS, bricks.asItem()); + TagManager.ITEMS.add(ItemTags.STONE_CRAFTING_MATERIALS, stone.asItem()); + TagManager.ITEMS.add(ItemTags.STONE_TOOL_MATERIALS, stone.asItem()); + TagManager.ITEMS.add(CommonItemTags.FURNACES, furnace.asItem()); + + // Block Tags // + TagManager.BLOCKS.add(BlockTags.STONE_BRICKS, bricks); + TagManager.BLOCKS.add(BlockTags.WALLS, wall, brickWall); + TagManager.BLOCKS.add(BlockTags.SLABS, slab, brickSlab); + TagManager.BLOCKS.add(pressurePlate, BlockTags.PRESSURE_PLATES, BlockTags.STONE_PRESSURE_PLATES); + TagManager.BLOCKS.add(CommonBlockTags.END_STONES, stone); + + TagManager.BLOCKS.add(BlockTags.DRAGON_IMMUNE, stone, stairs, slab, wall); + + TagManager.BLOCKS.add(CommonBlockTags.END_STONES, stone); + TagManager.BLOCKS.add(CommonBlockTags.END_STONES, stone); + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/config/Configs.java b/src/main/java/org/betterx/betterend/config/Configs.java new file mode 100644 index 00000000..d8fb7c11 --- /dev/null +++ b/src/main/java/org/betterx/betterend/config/Configs.java @@ -0,0 +1,37 @@ +package org.betterx.betterend.config; + +import org.betterx.bclib.BCLib; +import org.betterx.bclib.config.EntryConfig; +import org.betterx.bclib.config.IdConfig; +import org.betterx.bclib.config.PathConfig; +import org.betterx.betterend.BetterEnd; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class Configs { + public static final PathConfig ENTITY_CONFIG = new PathConfig(BetterEnd.MOD_ID, "entities"); + public static final PathConfig BLOCK_CONFIG = new PathConfig(BetterEnd.MOD_ID, "blocks"); + public static final PathConfig ITEM_CONFIG = new PathConfig(BetterEnd.MOD_ID, "items"); + public static final IdConfig BIOME_CONFIG = new EntryConfig(BetterEnd.MOD_ID, "biomes"); + public static final PathConfig GENERATOR_CONFIG = new PathConfig(BetterEnd.MOD_ID, "generator", false); + public static final PathConfig RECIPE_CONFIG = new PathConfig(BetterEnd.MOD_ID, "recipes"); + public static final PathConfig ENCHANTMENT_CONFIG = new PathConfig(BetterEnd.MOD_ID, "enchantments"); + + @Environment(value = EnvType.CLIENT) + public static final PathConfig CLENT_CONFIG = new PathConfig(BetterEnd.MOD_ID, "client", false); + + public static void saveConfigs() { + ENTITY_CONFIG.saveChanges(); + BLOCK_CONFIG.saveChanges(); + BIOME_CONFIG.saveChanges(); + ITEM_CONFIG.saveChanges(); + GENERATOR_CONFIG.saveChanges(); + RECIPE_CONFIG.saveChanges(); + ENCHANTMENT_CONFIG.saveChanges(); + + if (BCLib.isClient()) { + CLENT_CONFIG.saveChanges(); + } + } +} diff --git a/src/main/java/org/betterx/betterend/effects/EndPotions.java b/src/main/java/org/betterx/betterend/effects/EndPotions.java new file mode 100644 index 00000000..8b301875 --- /dev/null +++ b/src/main/java/org/betterx/betterend/effects/EndPotions.java @@ -0,0 +1,32 @@ +package org.betterx.betterend.effects; + +import org.betterx.bclib.mixin.common.PotionBrewingAccessor; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.core.Registry; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.alchemy.Potion; +import net.minecraft.world.item.alchemy.Potions; + +public class EndPotions { + public final static Potion END_VEIL = registerPotion("end_veil", EndStatusEffects.END_VEIL, 3600); + public final static Potion LONG_END_VEIL = registerPotion("long_end_veil", EndStatusEffects.END_VEIL, 9600); + + public static Potion registerPotion(String name, MobEffect effect, int duration) { + return registerPotion(name, new Potion(name, new MobEffectInstance(effect, duration))); + } + + public static Potion registerPotion(String name, Potion potion) { + return Registry.register(Registry.POTION, BetterEnd.makeID(name), potion); + } + + public static void register() { + PotionBrewingAccessor.callAddMix(Potions.AWKWARD, EndItems.ENDER_DUST, END_VEIL); + PotionBrewingAccessor.callAddMix(END_VEIL, Items.REDSTONE, LONG_END_VEIL); + PotionBrewingAccessor.callAddMix(Potions.AWKWARD, EndBlocks.MURKWEED.asItem(), Potions.NIGHT_VISION); + } +} diff --git a/src/main/java/org/betterx/betterend/effects/EndStatusEffects.java b/src/main/java/org/betterx/betterend/effects/EndStatusEffects.java new file mode 100644 index 00000000..1b46e23d --- /dev/null +++ b/src/main/java/org/betterx/betterend/effects/EndStatusEffects.java @@ -0,0 +1,42 @@ +package org.betterx.betterend.effects; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.effects.status.EndVeilEffect; + +import net.minecraft.core.Registry; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; + +public class EndStatusEffects { + public final static MobEffectInstance CRYSTALITE_HEALTH_REGEN = new MobEffectInstance( + MobEffects.REGENERATION, + 80, + 0, + true, + false, + true + ); + public final static MobEffectInstance CRYSTALITE_DIG_SPEED = new MobEffectInstance( + MobEffects.DIG_SPEED, + 80, + 0, + true, + false, + true + ); + public final static MobEffectInstance CRYSTALITE_MOVE_SPEED = new MobEffectInstance( + MobEffects.MOVEMENT_SPEED, + 80, + 0, + true, + false, + true + ); + + public final static MobEffect END_VEIL = registerEffect("end_veil", new EndVeilEffect()); + + public static MobEffect registerEffect(String name, E effect) { + return Registry.register(Registry.MOB_EFFECT, BetterEnd.makeID(name), effect); + } +} diff --git a/src/main/java/org/betterx/betterend/effects/enchantment/EndVeilEnchantment.java b/src/main/java/org/betterx/betterend/effects/enchantment/EndVeilEnchantment.java new file mode 100644 index 00000000..6c554b46 --- /dev/null +++ b/src/main/java/org/betterx/betterend/effects/enchantment/EndVeilEnchantment.java @@ -0,0 +1,17 @@ +package org.betterx.betterend.effects.enchantment; + +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.EnchantmentCategory; + +public class EndVeilEnchantment extends Enchantment { + + public EndVeilEnchantment() { + super(Enchantment.Rarity.VERY_RARE, EnchantmentCategory.ARMOR_HEAD, new EquipmentSlot[]{EquipmentSlot.HEAD}); + } + + @Override + public boolean isDiscoverable() { + return false; + } +} diff --git a/src/main/java/org/betterx/betterend/effects/status/EndVeilEffect.java b/src/main/java/org/betterx/betterend/effects/status/EndVeilEffect.java new file mode 100644 index 00000000..3ac183aa --- /dev/null +++ b/src/main/java/org/betterx/betterend/effects/status/EndVeilEffect.java @@ -0,0 +1,16 @@ +package org.betterx.betterend.effects.status; + +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectCategory; + +public class EndVeilEffect extends MobEffect { + + public EndVeilEffect() { + super(MobEffectCategory.BENEFICIAL, 0x0D554A); + } + + @Override + public boolean isDurationEffectTick(int duration, int amplifier) { + return false; + } +} diff --git a/src/main/java/org/betterx/betterend/entity/CubozoaEntity.java b/src/main/java/org/betterx/betterend/entity/CubozoaEntity.java new file mode 100644 index 00000000..32059398 --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/CubozoaEntity.java @@ -0,0 +1,157 @@ +package org.betterx.betterend.entity; + +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.betterend.registry.EndBiomes; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.game.ClientboundGameEventPacket; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.DifficultyInstance; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.animal.AbstractSchoolingFish; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.ServerLevelAccessor; + +public class CubozoaEntity extends AbstractSchoolingFish { + public static final int VARIANTS = 2; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId( + CubozoaEntity.class, + EntityDataSerializers.BYTE + ); + private static final EntityDataAccessor SCALE = SynchedEntityData.defineId( + CubozoaEntity.class, + EntityDataSerializers.BYTE + ); + + public CubozoaEntity(EntityType entityType, Level world) { + super(entityType, world); + } + + @Override + public SpawnGroupData finalizeSpawn( + ServerLevelAccessor world, + DifficultyInstance difficulty, + MobSpawnType spawnReason, + SpawnGroupData entityData, + CompoundTag entityTag + ) { + SpawnGroupData data = super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityTag); + + if (BiomeAPI.getBiome(world.getBiome(blockPosition())) == EndBiomes.SULPHUR_SPRINGS) { + this.entityData.set(VARIANT, (byte) 1); + } + + if (entityTag != null) { + if (entityTag.contains("Variant")) { + this.entityData.set(VARIANT, entityTag.getByte("Variant")); + } + if (entityTag.contains("Scale")) { + this.entityData.set(SCALE, entityTag.getByte("Scale")); + } + } + + this.refreshDimensions(); + return data; + } + + @Override + protected void defineSynchedData() { + super.defineSynchedData(); + this.entityData.define(VARIANT, (byte) 0); + this.entityData.define(SCALE, (byte) this.getRandom().nextInt(16)); + } + + @Override + public void addAdditionalSaveData(CompoundTag tag) { + super.addAdditionalSaveData(tag); + tag.putByte("Variant", (byte) getVariant()); + tag.putByte("Scale", getByteScale()); + } + + @Override + public void readAdditionalSaveData(CompoundTag tag) { + super.readAdditionalSaveData(tag); + if (tag.contains("Variant")) { + this.entityData.set(VARIANT, tag.getByte("Variant")); + } + if (tag.contains("Scale")) { + this.entityData.set(SCALE, tag.getByte("Scale")); + } + } + + @Override + public ItemStack getBucketItemStack() { + ItemStack bucket = EndItems.BUCKET_CUBOZOA.getDefaultInstance(); + CompoundTag tag = bucket.getOrCreateTag(); + tag.putByte("Variant", entityData.get(VARIANT)); + tag.putByte("Scale", entityData.get(SCALE)); + return bucket; + } + + public static AttributeSupplier.Builder createMobAttributes() { + return LivingEntity + .createLivingAttributes() + .add(Attributes.MAX_HEALTH, 2.0) + .add(Attributes.FOLLOW_RANGE, 16.0) + .add(Attributes.MOVEMENT_SPEED, 0.5); + } + + public int getVariant() { + return (int) this.entityData.get(VARIANT); + } + + public byte getByteScale() { + return this.entityData.get(SCALE); + } + + public float getScale() { + return getByteScale() / 32F + 0.75F; + } + + protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) { + return dimensions.height * 0.5F; + } + + @Override + protected void dropFromLootTable(DamageSource source, boolean causedByPlayer) { + int count = random.nextInt(3); + if (count > 0) { + ItemEntity drop = new ItemEntity(level, getX(), getY(), getZ(), new ItemStack(EndItems.GELATINE, count)); + this.level.addFreshEntity(drop); + } + } + + @Override + protected SoundEvent getFlopSound() { + return SoundEvents.SALMON_FLOP; + } + + @Override + public void playerTouch(Player player) { + if (player instanceof ServerPlayer && player.hurt(DamageSource.mobAttack(this), 0.5F)) { + if (!this.isSilent()) { + ((ServerPlayer) player).connection.send(new ClientboundGameEventPacket( + ClientboundGameEventPacket.PUFFER_FISH_STING, + 0.0F + )); + } + if (random.nextBoolean()) { + player.addEffect(new MobEffectInstance(MobEffects.POISON, 20, 0)); + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/entity/DragonflyEntity.java b/src/main/java/org/betterx/betterend/entity/DragonflyEntity.java new file mode 100644 index 00000000..cbd5a882 --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/DragonflyEntity.java @@ -0,0 +1,214 @@ +package org.betterx.betterend.entity; + +import org.betterx.bclib.entity.DespawnableAnimal; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndEntities; +import org.betterx.betterend.registry.EndSounds; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.control.FlyingMoveControl; +import net.minecraft.world.entity.ai.control.LookControl; +import net.minecraft.world.entity.ai.goal.BreedGoal; +import net.minecraft.world.entity.ai.goal.FloatGoal; +import net.minecraft.world.entity.ai.goal.FollowParentGoal; +import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation; +import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.entity.ai.util.AirAndWaterRandomPos; +import net.minecraft.world.entity.ai.util.HoverRandomPos; +import net.minecraft.world.entity.animal.FlyingAnimal; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.pathfinder.BlockPathTypes; +import net.minecraft.world.level.pathfinder.Path; +import net.minecraft.world.phys.Vec3; + +import java.util.EnumSet; + +public class DragonflyEntity extends DespawnableAnimal implements FlyingAnimal { + public DragonflyEntity(EntityType entityType, Level world) { + super(entityType, world); + this.moveControl = new FlyingMoveControl(this, 20, true); + this.lookControl = new DragonflyLookControl(this); + this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); + this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, -1.0F); + this.xpReward = 1; + } + + public static AttributeSupplier.Builder createMobAttributes() { + return LivingEntity + .createLivingAttributes() + .add(Attributes.MAX_HEALTH, 8.0D) + .add(Attributes.FOLLOW_RANGE, 16.0D) + .add(Attributes.FLYING_SPEED, 1.0D) + .add(Attributes.MOVEMENT_SPEED, 0.1D); + } + + @Override + public boolean canBeLeashed(Player player) { + return false; + } + + @Override + protected PathNavigation createNavigation(Level world) { + FlyingPathNavigation birdNavigation = new FlyingPathNavigation(this, world) { + public boolean isStableDestination(BlockPos pos) { + BlockState state = this.level.getBlockState(pos); + return state.isAir() || !state.getMaterial().blocksMotion(); + } + + public void tick() { + super.tick(); + } + }; + birdNavigation.setCanOpenDoors(false); + birdNavigation.setCanFloat(false); + birdNavigation.setCanPassDoors(true); + return birdNavigation; + } + + @Override + public float getWalkTargetValue(BlockPos pos, LevelReader world) { + return world.getBlockState(pos).isAir() ? 10.0F : 0.0F; + } + + @Override + protected void registerGoals() { + this.goalSelector.addGoal(1, new FloatGoal(this)); + this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D)); + this.goalSelector.addGoal(3, new FollowParentGoal(this, 1.0D)); + this.goalSelector.addGoal(4, new WanderAroundGoal()); + } + + @Override + public boolean isPushable() { + return false; + } + + @Override + public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource) { + return false; + } + + @Override + protected Entity.MovementEmission getMovementEmission() { + return Entity.MovementEmission.EVENTS; + } + + @Override + public boolean isFlying() { + return !this.onGround; + } + + @Override + public boolean isNoGravity() { + return true; + } + + @Override + public SoundEvent getAmbientSound() { + return EndSounds.ENTITY_DRAGONFLY; + } + + @Override + protected float getSoundVolume() { + return MHelper.randRange(0.25F, 0.5F, random); + } + + class DragonflyLookControl extends LookControl { + DragonflyLookControl(Mob entity) { + super(entity); + } + + protected boolean resetXRotOnTick() { + return true; + } + } + + class WanderAroundGoal extends Goal { + WanderAroundGoal() { + this.setFlags(EnumSet.of(Goal.Flag.MOVE)); + } + + public boolean canUse() { + return DragonflyEntity.this.navigation.isDone() && DragonflyEntity.this.random.nextInt(10) == 0; + } + + public boolean canContinueToUse() { + return DragonflyEntity.this.navigation.isInProgress(); + } + + public void start() { + Vec3 vec3d = this.getRandomLocation(); + if (vec3d != null) { + BlockPos pos = new BlockPos(vec3d); + try { + Path path = DragonflyEntity.this.navigation.createPath(pos, 1); + if (path != null) { + DragonflyEntity.this.navigation.moveTo(path, 1.0D); + } + } catch (Exception e) { + } + } + super.start(); + } + + private Vec3 getRandomLocation() { + int h = BlocksHelper.downRay(DragonflyEntity.this.level, DragonflyEntity.this.blockPosition(), 16); + Vec3 rotation = DragonflyEntity.this.getViewVector(0.0F); + Vec3 airPos = HoverRandomPos.getPos(DragonflyEntity.this, 8, 7, rotation.x, rotation.z, 1.5707964F, 3, 1); + if (airPos != null) { + if (isInVoid(airPos)) { + for (int i = 0; i < 8; i++) { + airPos = HoverRandomPos.getPos( + DragonflyEntity.this, + 16, + 7, + rotation.x, + rotation.z, + MHelper.PI2, + 3, + 1 + ); + if (airPos != null && !isInVoid(airPos)) { + return airPos; + } + } + return null; + } + if (h > 5 && airPos.y() >= DragonflyEntity.this.blockPosition().getY()) { + airPos = new Vec3(airPos.x, airPos.y - h * 0.5, airPos.z); + } + return airPos; + } + return AirAndWaterRandomPos.getPos( + DragonflyEntity.this, + 8, + 4, + -2, + rotation.x, + rotation.z, + 1.5707963705062866D + ); + } + + private boolean isInVoid(Vec3 pos) { + int h = BlocksHelper.downRay(DragonflyEntity.this.level, new BlockPos(pos), 128); + return h > 100; + } + } + + @Override + public AgeableMob getBreedOffspring(ServerLevel world, AgeableMob entity) { + return EndEntities.DRAGONFLY.create(world); + } +} diff --git a/src/main/java/org/betterx/betterend/entity/EndFishEntity.java b/src/main/java/org/betterx/betterend/entity/EndFishEntity.java new file mode 100644 index 00000000..76566aa9 --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/EndFishEntity.java @@ -0,0 +1,177 @@ +package org.betterx.betterend.entity; + +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.betterend.registry.EndBiomes; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.DifficultyInstance; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.damagesource.EntityDamageSource; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.SpawnGroupData; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.animal.AbstractSchoolingFish; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.block.Blocks; + +public class EndFishEntity extends AbstractSchoolingFish { + public static final int VARIANTS_NORMAL = 5; + public static final int VARIANTS_SULPHUR = 3; + public static final int VARIANTS = VARIANTS_NORMAL + VARIANTS_SULPHUR; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId( + EndFishEntity.class, + EntityDataSerializers.BYTE + ); + private static final EntityDataAccessor SCALE = SynchedEntityData.defineId( + EndFishEntity.class, + EntityDataSerializers.BYTE + ); + + public EndFishEntity(EntityType entityType, Level world) { + super(entityType, world); + } + + @Override + public SpawnGroupData finalizeSpawn( + ServerLevelAccessor world, + DifficultyInstance difficulty, + MobSpawnType spawnReason, + SpawnGroupData entityData, + CompoundTag entityTag + ) { + SpawnGroupData data = super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityTag); + + if (BiomeAPI.getBiome(world.getBiome(blockPosition())) == EndBiomes.SULPHUR_SPRINGS) { + this.entityData.set(VARIANT, (byte) (random.nextInt(VARIANTS_SULPHUR) + VARIANTS_NORMAL)); + } + + if (entityTag != null) { + if (entityTag.contains("Variant")) { + this.entityData.set(VARIANT, entityTag.getByte("variant")); + } + if (entityTag.contains("Scale")) { + this.entityData.set(SCALE, entityTag.getByte("scale")); + } + } + + this.refreshDimensions(); + return data; + } + + @Override + protected void defineSynchedData() { + super.defineSynchedData(); + this.entityData.define(VARIANT, (byte) this.getRandom().nextInt(VARIANTS_NORMAL)); + this.entityData.define(SCALE, (byte) this.getRandom().nextInt(16)); + } + + @Override + public void addAdditionalSaveData(CompoundTag tag) { + super.addAdditionalSaveData(tag); + tag.putByte("Variant", (byte) getVariant()); + tag.putByte("Scale", getByteScale()); + } + + @Override + public void readAdditionalSaveData(CompoundTag tag) { + super.readAdditionalSaveData(tag); + if (tag.contains("Variant")) { + this.entityData.set(VARIANT, tag.getByte("Variant")); + } + if (tag.contains("Scale")) { + this.entityData.set(SCALE, tag.getByte("Scale")); + } + } + + @Override + public ItemStack getBucketItemStack() { + ItemStack bucket = EndItems.BUCKET_END_FISH.getDefaultInstance(); + CompoundTag tag = bucket.getOrCreateTag(); + tag.putByte("variant", entityData.get(VARIANT)); + tag.putByte("scale", entityData.get(SCALE)); + return bucket; + } + + @Override + protected SoundEvent getFlopSound() { + return SoundEvents.TROPICAL_FISH_FLOP; + } + + @Override + protected SoundEvent getAmbientSound() { + return SoundEvents.SALMON_AMBIENT; + } + + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.SALMON_DEATH; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return SoundEvents.SALMON_HURT; + } + + @Override + public void tick() { + super.tick(); + if (random.nextInt(8) == 0 && getFeetBlockState().is(Blocks.WATER)) { + double x = getX() + random.nextGaussian() * 0.2; + double y = getY() + random.nextGaussian() * 0.2; + double z = getZ() + random.nextGaussian() * 0.2; + level.addParticle(ParticleTypes.BUBBLE, x, y, z, 0, 0, 0); + } + } + + public static AttributeSupplier.Builder createMobAttributes() { + return LivingEntity + .createLivingAttributes() + .add(Attributes.MAX_HEALTH, 2.0) + .add(Attributes.FOLLOW_RANGE, 16.0) + .add(Attributes.MOVEMENT_SPEED, 0.75); + } + + public int getVariant() { + return (int) this.entityData.get(VARIANT); + } + + public byte getByteScale() { + return this.entityData.get(SCALE); + } + + public float getScale() { + return getByteScale() / 32F + 0.75F; + } + + @Override + protected void dropFromLootTable(DamageSource source, boolean causedByPlayer) { + Item item = source.isFire() ? EndItems.END_FISH_COOKED : EndItems.END_FISH_RAW; + if (causedByPlayer && source instanceof EntityDamageSource) { + EntityDamageSource damageSource = (EntityDamageSource) source; + ItemStack handItem = ((Player) damageSource.getEntity()).getItemInHand(InteractionHand.MAIN_HAND); + if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.FIRE_ASPECT, handItem) > 0) { + item = EndItems.END_FISH_COOKED; + } + } + ItemEntity drop = new ItemEntity(level, getX(), getY(), getZ(), new ItemStack(item)); + this.level.addFreshEntity(drop); + } +} diff --git a/src/main/java/org/betterx/betterend/entity/EndSlimeEntity.java b/src/main/java/org/betterx/betterend/entity/EndSlimeEntity.java new file mode 100644 index 00000000..8ab94993 --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/EndSlimeEntity.java @@ -0,0 +1,435 @@ +package org.betterx.betterend.entity; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.interfaces.ISlime; +import org.betterx.betterend.registry.EndBiomes; +import org.betterx.betterend.util.GlobalState; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.DifficultyInstance; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.SpawnGroupData; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.control.MoveControl; +import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; +import net.minecraft.world.entity.animal.IronGolem; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.monster.Slime; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.block.Blocks; + +import java.util.EnumSet; + +public class EndSlimeEntity extends Slime { + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId( + EndSlimeEntity.class, + EntityDataSerializers.BYTE + ); + + public EndSlimeEntity(EntityType entityType, Level world) { + super(entityType, world); + this.moveControl = new EndSlimeMoveControl(this); + } + + protected void registerGoals() { + this.goalSelector.addGoal(1, new SwimmingGoal()); + this.goalSelector.addGoal(2, new FaceTowardTargetGoal()); + this.goalSelector.addGoal(3, new RandomLookGoal()); + this.goalSelector.addGoal(5, new MoveGoal()); + this.targetSelector.addGoal( + 1, + new NearestAttackableTargetGoal(this, Player.class, 10, true, false, (livingEntity) -> { + return Math.abs(livingEntity.getY() - this.getY()) <= 4.0D; + }) + ); + this.targetSelector.addGoal(3, new NearestAttackableTargetGoal(this, IronGolem.class, true)); + } + + public static AttributeSupplier.Builder createMobAttributes() { + return LivingEntity + .createLivingAttributes() + .add(Attributes.MAX_HEALTH, 1.0D) + .add(Attributes.ATTACK_DAMAGE, 1.0D) + .add(Attributes.FOLLOW_RANGE, 16.0D) + .add(Attributes.MOVEMENT_SPEED, 0.15D); + } + + @Override + public SpawnGroupData finalizeSpawn( + ServerLevelAccessor world, + DifficultyInstance difficulty, + MobSpawnType spawnReason, + SpawnGroupData entityData, + CompoundTag entityTag + ) { + SpawnGroupData data = super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityTag); + BCLBiome biome = BiomeAPI.getBiome(world.getBiome(blockPosition())); + if (biome == EndBiomes.FOGGY_MUSHROOMLAND) { + this.setMossy(); + } else if (biome == EndBiomes.MEGALAKE || biome == EndBiomes.MEGALAKE_GROVE) { + this.setLake(); + } else if (biome == EndBiomes.AMBER_LAND) { + this.setAmber(true); + } + this.refreshDimensions(); + return data; + } + + @Override + protected void defineSynchedData() { + super.defineSynchedData(); + this.entityData.define(VARIANT, (byte) 0); + } + + @Override + public void addAdditionalSaveData(CompoundTag tag) { + super.addAdditionalSaveData(tag); + tag.putByte("Variant", (byte) getSlimeType()); + } + + @Override + public void readAdditionalSaveData(CompoundTag tag) { + super.readAdditionalSaveData(tag); + if (tag.contains("Variant")) { + this.entityData.set(VARIANT, tag.getByte("Variant")); + } + } + + @Override + protected ParticleOptions getParticleType() { + return ParticleTypes.PORTAL; + } + + @Override + public void remove(RemovalReason reason) { + int i = this.getSize(); + if (!this.level.isClientSide && i > 1 && this.isDeadOrDying()) { + Component text = this.getCustomName(); + boolean bl = this.isNoAi(); + float f = (float) i / 4.0F; + int j = i / 2; + int k = 2 + this.random.nextInt(3); + int type = this.getSlimeType(); + + for (int l = 0; l < k; ++l) { + float g = ((float) (l % 2) - 0.5F) * f; + float h = ((float) (l / 2) - 0.5F) * f; + EndSlimeEntity slimeEntity = (EndSlimeEntity) this.getType().create(this.level); + if (this.isPersistenceRequired()) { + slimeEntity.setPersistenceRequired(); + } + + slimeEntity.setSlimeType(type); + slimeEntity.setCustomName(text); + slimeEntity.setNoAi(bl); + slimeEntity.setInvulnerable(this.isInvulnerable()); + ((ISlime) slimeEntity).be_setSlimeSize(j, true); + slimeEntity.refreshDimensions(); + slimeEntity.moveTo( + this.getX() + (double) g, + this.getY() + 0.5D, + this.getZ() + (double) h, + this.random.nextFloat() * 360.0F, + 0.0F + ); + this.level.addFreshEntity(slimeEntity); + } + } + + ((ISlime) this).entityRemove(reason); + } + + @Override + protected void dropFromLootTable(DamageSource source, boolean causedByPlayer) { + int maxCount = this.getSize(); + int minCount = maxCount >> 1; + if (minCount < 1) { + minCount = 1; + } + if (causedByPlayer && this.lastHurtByPlayer != null) { + int looting = EnchantmentHelper.getMobLooting(this.lastHurtByPlayer); + minCount += looting; + } + int count = minCount < maxCount ? MHelper.randRange(minCount, maxCount, random) : maxCount; + ItemEntity drop = new ItemEntity(level, getX(), getY(), getZ(), new ItemStack(Items.SLIME_BALL, count)); + this.level.addFreshEntity(drop); + } + + public int getSlimeType() { + return this.entityData.get(VARIANT).intValue(); + } + + public void setSlimeType(int value) { + this.entityData.set(VARIANT, (byte) value); + } + + protected void setMossy() { + setSlimeType(1); + } + + public boolean isMossy() { + return getSlimeType() == 1; + } + + protected void setLake() { + setSlimeType(2); + } + + public boolean isLake() { + return getSlimeType() == 2; + } + + protected void setAmber(boolean mossy) { + this.entityData.set(VARIANT, (byte) 3); + } + + public boolean isAmber() { + return this.entityData.get(VARIANT) == 3; + } + + public boolean isChorus() { + return this.entityData.get(VARIANT) == 0; + } + + public static boolean canSpawn( + EntityType entityType, + LevelAccessor world, + MobSpawnType spawnType, + BlockPos pos, + RandomSource random + ) { + if (!world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES)) { + return false; + } + BCLBiome biome = BiomeAPI.getBiome(world.getBiome(pos)); + if (biome == EndBiomes.CHORUS_FOREST || biome == EndBiomes.MEGALAKE) { + return true; + } + if (biome == EndBiomes.MEGALAKE_GROVE && random.nextBoolean()) { + return true; + } + return random.nextInt(4) == 0 && isWaterNear(world, pos); + } + + private static boolean isWaterNear(LevelAccessor world, BlockPos pos) { + final MutableBlockPos POS = GlobalState.stateForThread().POS; + + for (int x = pos.getX() - 32; x <= pos.getX() + 32; x++) { + POS.setX(x); + for (int z = pos.getZ() - 32; z <= pos.getZ() + 32; z++) { + POS.setZ(z); + for (int y = pos.getY() - 8; y <= pos.getY() + 8; y++) { + POS.setY(y); + if (world.getBlockState(POS).getBlock() == Blocks.WATER) { + return true; + } + } + } + } + return false; + } + + class MoveGoal extends Goal { + public MoveGoal() { + this.setFlags(EnumSet.of(Goal.Flag.JUMP, Goal.Flag.MOVE)); + } + + public boolean canUse() { + if (EndSlimeEntity.this.isPassenger()) { + return false; + } + + float yaw = EndSlimeEntity.this.getYHeadRot(); + float speed = EndSlimeEntity.this.getSpeed(); + if (speed > 0.1) { + float dx = Mth.sin(-yaw * 0.017453292F); + float dz = Mth.cos(-yaw * 0.017453292F); + BlockPos pos = EndSlimeEntity.this.blockPosition().offset(dx * speed * 4, 0, dz * speed * 4); + int down = BlocksHelper.downRay(EndSlimeEntity.this.level, pos, 16); + return down < 5; + } + + return true; + } + + public void tick() { + ((EndSlimeMoveControl) EndSlimeEntity.this.getMoveControl()).move(1.0D); + } + } + + class SwimmingGoal extends Goal { + public SwimmingGoal() { + this.setFlags(EnumSet.of(Goal.Flag.JUMP, Goal.Flag.MOVE)); + EndSlimeEntity.this.getNavigation().setCanFloat(true); + } + + public boolean canUse() { + return (EndSlimeEntity.this.isInWater() || EndSlimeEntity.this.isInLava()) && EndSlimeEntity.this.getMoveControl() instanceof EndSlimeMoveControl; + } + + public void tick() { + if (EndSlimeEntity.this.getRandom().nextFloat() < 0.8F) { + EndSlimeEntity.this.getJumpControl().jump(); + } + + ((EndSlimeMoveControl) EndSlimeEntity.this.getMoveControl()).move(1.2D); + } + } + + class RandomLookGoal extends Goal { + private float targetYaw; + private int timer; + + public RandomLookGoal() { + this.setFlags(EnumSet.of(Goal.Flag.LOOK)); + } + + public boolean canUse() { + return EndSlimeEntity.this.getTarget() == null && (EndSlimeEntity.this.onGround || EndSlimeEntity.this.isInWater() || EndSlimeEntity.this + .isInLava() || EndSlimeEntity.this.hasEffect(MobEffects.LEVITATION)) && EndSlimeEntity.this.getMoveControl() instanceof EndSlimeMoveControl; + } + + public void tick() { + if (--this.timer <= 0) { + this.timer = 40 + EndSlimeEntity.this.getRandom().nextInt(60); + this.targetYaw = (float) EndSlimeEntity.this.getRandom().nextInt(360); + } + + ((EndSlimeMoveControl) EndSlimeEntity.this.getMoveControl()).look(this.targetYaw, false); + } + } + + class FaceTowardTargetGoal extends Goal { + private int ticksLeft; + + public FaceTowardTargetGoal() { + this.setFlags(EnumSet.of(Goal.Flag.LOOK)); + } + + public boolean canUse() { + LivingEntity livingEntity = EndSlimeEntity.this.getTarget(); + if (livingEntity == null) { + return false; + } else if (!livingEntity.isAlive()) { + return false; + } else { + return (!(livingEntity instanceof Player) || !((Player) livingEntity).getAbilities().invulnerable) && EndSlimeEntity.this + .getMoveControl() instanceof EndSlimeMoveControl; + } + } + + public void start() { + this.ticksLeft = 300; + super.start(); + } + + public boolean canContinueToUse() { + LivingEntity livingEntity = EndSlimeEntity.this.getTarget(); + if (livingEntity == null) { + return false; + } else if (!livingEntity.isAlive()) { + return false; + } else if (livingEntity instanceof Player && ((Player) livingEntity).getAbilities().invulnerable) { + return false; + } else { + return --this.ticksLeft > 0; + } + } + + public void tick() { + EndSlimeEntity.this.lookAt(EndSlimeEntity.this.getTarget(), 10.0F, 10.0F); + ((EndSlimeMoveControl) EndSlimeEntity.this.getMoveControl()).look( + EndSlimeEntity.this.getYRot(), + EndSlimeEntity.this.isDealsDamage() + ); + } + } + + class EndSlimeMoveControl extends MoveControl { + private float targetYaw; + private int ticksUntilJump; + private boolean jumpOften; + + public EndSlimeMoveControl(EndSlimeEntity slime) { + super(slime); + this.targetYaw = 180.0F * slime.getYRot() / 3.1415927F; + } + + public void look(float targetYaw, boolean jumpOften) { + this.targetYaw = targetYaw; + this.jumpOften = jumpOften; + } + + public void move(double speed) { + this.speedModifier = speed; + this.operation = MoveControl.Operation.MOVE_TO; + } + + public void tick() { + this.mob.setYRot(this.rotlerp(this.mob.getYRot(), this.targetYaw, 90.0F)); + this.mob.yHeadRot = this.mob.getYRot(); + this.mob.yBodyRot = this.mob.getYRot(); + if (this.operation != MoveControl.Operation.MOVE_TO) { + this.mob.setZza(0.0F); + } else { + this.operation = MoveControl.Operation.WAIT; + if (this.mob.isOnGround()) { + this.mob.setSpeed((float) (this.speedModifier * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED))); + if (this.ticksUntilJump-- <= 0) { + this.ticksUntilJump = EndSlimeEntity.this.getJumpDelay(); + if (this.jumpOften) { + this.ticksUntilJump /= 3; + } + + EndSlimeEntity.this.getJumpControl().jump(); + if (EndSlimeEntity.this.doPlayJumpSound()) { + EndSlimeEntity.this.playSound( + EndSlimeEntity.this.getJumpSound(), + EndSlimeEntity.this.getSoundVolume(), + getJumpSoundPitch() + ); + } + } else { + EndSlimeEntity.this.xxa = 0.0F; + EndSlimeEntity.this.zza = 0.0F; + this.mob.setSpeed(0.0F); + } + } else { + this.mob.setSpeed((float) (this.speedModifier * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED))); + } + + } + } + + private float getJumpSoundPitch() { + float f = EndSlimeEntity.this.isTiny() ? 1.4F : 0.8F; + return ((EndSlimeEntity.this.random.nextFloat() - EndSlimeEntity.this.random.nextFloat()) * 0.2F + 1.0F) * f; + } + } +} diff --git a/src/main/java/org/betterx/betterend/entity/ShadowWalkerEntity.java b/src/main/java/org/betterx/betterend/entity/ShadowWalkerEntity.java new file mode 100644 index 00000000..58e44a71 --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/ShadowWalkerEntity.java @@ -0,0 +1,149 @@ +package org.betterx.betterend.entity; + +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndSounds; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; +import net.minecraft.world.entity.ai.goal.MeleeAttackGoal; +import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal; +import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal; +import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; +import net.minecraft.world.entity.monster.Monster; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; + +public class ShadowWalkerEntity extends Monster { + public ShadowWalkerEntity(EntityType entityType, Level world) { + super(entityType, world); + } + + @Override + protected void registerGoals() { + this.goalSelector.addGoal(2, new AttackGoal(this, 1.0D, false)); + this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0D)); + this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 8.0F)); + this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); + this.targetSelector.addGoal(2, new NearestAttackableTargetGoal(this, Player.class, true)); + } + + public static AttributeSupplier.Builder createMobAttributes() { + return Monster + .createMonsterAttributes() + .add(Attributes.FOLLOW_RANGE, 35.0) + .add(Attributes.MOVEMENT_SPEED, 0.15) + .add(Attributes.ATTACK_DAMAGE, 4.5) + .add(Attributes.ARMOR, 2.0) + .add(Attributes.SPAWN_REINFORCEMENTS_CHANCE); + } + + @Override + public void tick() { + super.tick(); + level.addParticle( + ParticleTypes.ASH, + getX() + random.nextGaussian() * 0.2, + getY() + random.nextGaussian() * 0.5 + 1, + getZ() + random.nextGaussian() * 0.2, + 0, + 0, + 0 + ); + level.addParticle( + ParticleTypes.SMOKE, + getX() + random.nextGaussian() * 0.2, + getY() + random.nextGaussian() * 0.5 + 1, + getZ() + random.nextGaussian() * 0.2, + 0, + 0, + 0 + ); + level.addParticle( + ParticleTypes.ENTITY_EFFECT, + getX() + random.nextGaussian() * 0.2, + getY() + random.nextGaussian() * 0.5 + 1, + getZ() + random.nextGaussian() * 0.2, + 0, + 0, + 0 + ); + } + + @Override + protected SoundEvent getAmbientSound() { + return EndSounds.ENTITY_SHADOW_WALKER; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return EndSounds.ENTITY_SHADOW_WALKER_DAMAGE; + } + + @Override + protected SoundEvent getDeathSound() { + return EndSounds.ENTITY_SHADOW_WALKER_DEATH; + } + + @Override + protected void playStepSound(BlockPos pos, BlockState state) { + } + + @Override + protected float getSoundVolume() { + return MHelper.randRange(0.25F, 0.5F, random); + } + + @Override + public float getVoicePitch() { + return MHelper.randRange(0.75F, 1.25F, random); + } + + @Override + public boolean doHurtTarget(Entity target) { + boolean attack = super.doHurtTarget(target); + if (attack && target instanceof LivingEntity) { + LivingEntity living = (LivingEntity) target; + if (!(living.hasEffect(MobEffects.BLINDNESS))) { + living.addEffect(new MobEffectInstance(MobEffects.BLINDNESS, 60)); + } + } + return attack; + } + + private final class AttackGoal extends MeleeAttackGoal { + private final ShadowWalkerEntity walker; + private int ticks; + + public AttackGoal(ShadowWalkerEntity walker, double speed, boolean pauseWhenMobIdle) { + super(walker, speed, pauseWhenMobIdle); + this.walker = walker; + } + + public void start() { + super.start(); + this.ticks = 0; + } + + public void stop() { + super.stop(); + this.walker.setAggressive(false); + } + + public void tick() { + super.tick(); + ++this.ticks; + this.walker.setAggressive(this.ticks >= 5 && this.getTicksUntilNextAttack() < this.getAttackInterval() / 2); + } + } +} diff --git a/src/main/java/org/betterx/betterend/entity/SilkMothEntity.java b/src/main/java/org/betterx/betterend/entity/SilkMothEntity.java new file mode 100644 index 00000000..6e58e229 --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/SilkMothEntity.java @@ -0,0 +1,325 @@ +package org.betterx.betterend.entity; + +import org.betterx.bclib.entity.DespawnableAnimal; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.EndBlockProperties; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndEntities; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Registry; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.control.FlyingMoveControl; +import net.minecraft.world.entity.ai.control.LookControl; +import net.minecraft.world.entity.ai.goal.BreedGoal; +import net.minecraft.world.entity.ai.goal.FloatGoal; +import net.minecraft.world.entity.ai.goal.FollowParentGoal; +import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation; +import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.entity.ai.util.AirAndWaterRandomPos; +import net.minecraft.world.entity.ai.util.HoverRandomPos; +import net.minecraft.world.entity.animal.FlyingAnimal; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.pathfinder.BlockPathTypes; +import net.minecraft.world.phys.Vec3; + +import java.util.EnumSet; +import org.jetbrains.annotations.Nullable; + +public class SilkMothEntity extends DespawnableAnimal implements FlyingAnimal { + private BlockPos hivePos; + private BlockPos entrance; + private Level hiveWorld; + + public SilkMothEntity(EntityType entityType, Level world) { + super(entityType, world); + this.moveControl = new FlyingMoveControl(this, 20, true); + this.lookControl = new MothLookControl(this); + this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); + this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, -1.0F); + this.xpReward = 1; + } + + public static AttributeSupplier.Builder createMobAttributes() { + return LivingEntity + .createLivingAttributes() + .add(Attributes.MAX_HEALTH, 2.0D) + .add(Attributes.FOLLOW_RANGE, 16.0D) + .add(Attributes.FLYING_SPEED, 0.4D) + .add(Attributes.MOVEMENT_SPEED, 0.1D); + } + + public void setHive(Level world, BlockPos hive) { + this.hivePos = hive; + this.hiveWorld = world; + } + + @Override + public boolean canBeLeashed(Player player) { + return false; + } + + @Override + public void addAdditionalSaveData(CompoundTag tag) { + if (hivePos != null) { + tag.put("HivePos", NbtUtils.writeBlockPos(hivePos)); + tag.putString("HiveWorld", hiveWorld.dimension().location().toString()); + } + } + + @Override + public void readAdditionalSaveData(CompoundTag tag) { + if (tag.contains("HivePos")) { + hivePos = NbtUtils.readBlockPos(tag.getCompound("HivePos")); + ResourceLocation worldID = new ResourceLocation(tag.getString("HiveWorld")); + try { + hiveWorld = level.getServer().getLevel(ResourceKey.create(Registry.DIMENSION_REGISTRY, worldID)); + } catch (Exception e) { + BetterEnd.LOGGER.warning("Silk Moth Hive World {} is missing!", worldID); + hivePos = null; + } + } + } + + @Override + protected void registerGoals() { + this.goalSelector.addGoal(1, new ReturnToHiveGoal()); + this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D)); + this.goalSelector.addGoal(5, new FollowParentGoal(this, 1.25D)); + this.goalSelector.addGoal(8, new WanderAroundGoal()); + this.goalSelector.addGoal(9, new FloatGoal(this)); + } + + @Override + protected PathNavigation createNavigation(Level world) { + FlyingPathNavigation birdNavigation = new FlyingPathNavigation(this, world) { + public boolean isStableDestination(BlockPos pos) { + BlockState state = this.level.getBlockState(pos); + return state.isAir() || !state.getMaterial().blocksMotion(); + } + + public void tick() { + super.tick(); + } + }; + birdNavigation.setCanOpenDoors(false); + birdNavigation.setCanFloat(false); + birdNavigation.setCanPassDoors(true); + return birdNavigation; + } + + @Override + public boolean isPushable() { + return false; + } + + @Override + public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource) { + return false; + } + + @Override + protected Entity.MovementEmission getMovementEmission() { + return Entity.MovementEmission.EVENTS; + } + + @Override + public boolean isFlying() { + return !this.onGround; + } + + @Override + public boolean isNoGravity() { + return true; + } + + @Override + public AgeableMob getBreedOffspring(ServerLevel world, AgeableMob entity) { + return EndEntities.SILK_MOTH.create(world); + } + + @Override + protected void dropFromLootTable(DamageSource source, boolean causedByPlayer) { + int minCount = 0; + int maxCount = 1; + if (causedByPlayer && this.lastHurtByPlayer != null) { + int looting = EnchantmentHelper.getMobLooting(this.lastHurtByPlayer); + minCount += looting; + maxCount += looting; + if (maxCount > 2) { + maxCount = 2; + } + } + int count = minCount < maxCount ? MHelper.randRange(minCount, maxCount, random) : maxCount; + ItemEntity drop = new ItemEntity(level, getX(), getY(), getZ(), new ItemStack(EndItems.SILK_FIBER, count)); + this.level.addFreshEntity(drop); + } + + class MothLookControl extends LookControl { + MothLookControl(Mob entity) { + super(entity); + } + + protected boolean resetXRotOnTick() { + return true; + } + } + + class WanderAroundGoal extends Goal { + WanderAroundGoal() { + this.setFlags(EnumSet.of(Goal.Flag.MOVE)); + } + + @Override + public boolean canUse() { + return SilkMothEntity.this.navigation.isDone() && SilkMothEntity.this.random.nextInt(10) == 0; + } + + @Override + public boolean canContinueToUse() { + return SilkMothEntity.this.navigation.isInProgress(); + } + + @Override + public void start() { + Vec3 vec3d = null; + if (SilkMothEntity.this.hivePos != null && SilkMothEntity.this.hiveWorld == SilkMothEntity.this.level) { + if (SilkMothEntity.this.position() + .distanceToSqr( + SilkMothEntity.this.hivePos.getX(), + SilkMothEntity.this.hivePos.getY(), + SilkMothEntity.this.hivePos.getZ() + ) > 16) { + vec3d = SilkMothEntity.this.position().add(random.nextGaussian() * 2, 0, random.nextGaussian() * 2); + } + } + vec3d = vec3d == null ? this.getRandomLocation() : vec3d; + if (vec3d != null) { + try { + SilkMothEntity.this.navigation.moveTo(SilkMothEntity.this.navigation.createPath( + new BlockPos(vec3d), + 1 + ), 1.0D); + } catch (Exception e) { + } + } + } + + @Nullable + private Vec3 getRandomLocation() { + Vec3 vec3d3 = SilkMothEntity.this.getViewVector(0.0F); + Vec3 vec3d4 = HoverRandomPos.getPos(SilkMothEntity.this, 8, 7, vec3d3.x, vec3d3.z, 1.5707964F, 3, 1); + return vec3d4 != null ? vec3d4 : AirAndWaterRandomPos.getPos( + SilkMothEntity.this, + 8, + 4, + -2, + vec3d3.x, + vec3d3.z, + 1.5707963705062866D + ); + } + } + + class ReturnToHiveGoal extends Goal { + ReturnToHiveGoal() { + this.setFlags(EnumSet.of(Goal.Flag.MOVE)); + } + + @Override + public boolean canUse() { + return SilkMothEntity.this.hivePos != null && + SilkMothEntity.this.hiveWorld == SilkMothEntity.this.level && + SilkMothEntity.this.navigation.isDone() && + SilkMothEntity.this.random.nextInt(8) == 0 && + SilkMothEntity.this.position().distanceToSqr( + SilkMothEntity.this.hivePos.getX(), + SilkMothEntity.this.hivePos.getY(), + SilkMothEntity.this.hivePos.getZ() + ) < 16384; + } + + @Override + public boolean canContinueToUse() { + return SilkMothEntity.this.navigation.isInProgress() && level.getBlockState(entrance) + .isAir() && (level.getBlockState(hivePos) + .is(EndBlocks.SILK_MOTH_NEST) || level + .getBlockState(hivePos) + .is(EndBlocks.SILK_MOTH_HIVE)); + } + + @Override + public void start() { + BlockState state = SilkMothEntity.this.level.getBlockState(SilkMothEntity.this.hivePos); + if (!state.is(EndBlocks.SILK_MOTH_NEST) && !state.is(EndBlocks.SILK_MOTH_HIVE)) { + SilkMothEntity.this.hivePos = null; + return; + } + try { + SilkMothEntity.this.entrance = SilkMothEntity.this.hivePos.relative(state.getValue(BlockStateProperties.HORIZONTAL_FACING)); + SilkMothEntity.this.navigation.moveTo(SilkMothEntity.this.navigation.createPath(entrance, 1), 1.0D); + } catch (Exception e) { + } + } + + @Override + public void tick() { + super.tick(); + if (SilkMothEntity.this.entrance == null) { + return; + } + double dx = Math.abs(SilkMothEntity.this.entrance.getX() - SilkMothEntity.this.getX()); + double dy = Math.abs(SilkMothEntity.this.entrance.getY() - SilkMothEntity.this.getY()); + double dz = Math.abs(SilkMothEntity.this.entrance.getZ() - SilkMothEntity.this.getZ()); + if (dx + dy + dz < 1) { + BlockState state = SilkMothEntity.this.level.getBlockState(hivePos); + if (state.is(EndBlocks.SILK_MOTH_NEST) || state.is(EndBlocks.SILK_MOTH_HIVE)) { + int fullness = state.getValue(EndBlockProperties.FULLNESS); + boolean isHive = state.is(EndBlocks.SILK_MOTH_HIVE); + if (fullness < 3 && (isHive || SilkMothEntity.this.random.nextBoolean())) { + fullness += isHive ? MHelper.randRange(1, 2, random) : 1; + if (fullness > 3) { + fullness = 3; + } + BlocksHelper.setWithUpdate( + SilkMothEntity.this.hiveWorld, + SilkMothEntity.this.hivePos, + state.setValue(EndBlockProperties.FULLNESS, fullness) + ); + } + SilkMothEntity.this.level.playSound( + null, + SilkMothEntity.this.entrance, + SoundEvents.BEEHIVE_ENTER, + SoundSource.BLOCKS, + 1, + 1 + ); + SilkMothEntity.this.discard(); + } else { + SilkMothEntity.this.hivePos = null; + } + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/entity/model/CubozoaEntityModel.java b/src/main/java/org/betterx/betterend/entity/model/CubozoaEntityModel.java new file mode 100644 index 00000000..42fae1f3 --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/model/CubozoaEntityModel.java @@ -0,0 +1,106 @@ +package org.betterx.betterend.entity.model; + +import org.betterx.betterend.entity.CubozoaEntity; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartNames; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.util.Mth; + +public class CubozoaEntityModel extends EntityModel { + private final static int TENTACLE_COUNT = 4; + + private final ModelPart model; + private final ModelPart[] tentacle_center; + private final ModelPart[] tentacle; + private float scaleY; + private float scaleXZ; + + public static LayerDefinition getTexturedModelData() { + MeshDefinition modelData = new MeshDefinition(); + PartDefinition modelPartData = modelData.getRoot(); + + PartDefinition bodyPart = modelPartData.addOrReplaceChild( + PartNames.BODY, + CubeListBuilder.create().texOffs(0, 17).addBox(-2.0F, -12.5F, -2.0F, 4.0F, 4.0F, 4.0F), + PartPose.offset(0.0F, 24.0F, 0.0F) + ); + + bodyPart.addOrReplaceChild( + "main_cube_r1", + CubeListBuilder.create().texOffs(0, 0).addBox(-5.0F, -7.0F, -5.0F, 10.0F, 7.0F, 10.0F), + PartPose.offsetAndRotation(0.0F, -14.0F, 0.0F, 0.0F, 0.0F, -3.1416F) + ); + + for (int i = 1; i <= TENTACLE_COUNT; i++) { + PartDefinition tentaclePart = bodyPart.addOrReplaceChild( + "tentacle_center_" + i, + CubeListBuilder.create(), + PartPose.offsetAndRotation(0.0F, 0.0F, 0.0F, 0.0F, i * 1.5708F, 0.0F) + ); + + tentaclePart.addOrReplaceChild( + "tentacle_" + i, + CubeListBuilder.create().texOffs(16, 17).addBox(-4.0F, 0.0F, 0.0F, 8.0F, 7.0F, 0.0F), + PartPose.offset(0.0F, -7.0F, 4.5F) + ); + } + + return LayerDefinition.create(modelData, 48, 48); + } + + public CubozoaEntityModel(ModelPart modelPart) { + super(RenderType::entityTranslucent); + tentacle = new ModelPart[TENTACLE_COUNT]; + tentacle_center = new ModelPart[TENTACLE_COUNT]; + + model = modelPart.getChild(PartNames.BODY); + for (int i = 1; i <= TENTACLE_COUNT; i++) { + tentacle_center[i - 1] = model.getChild("tentacle_center_" + i); + tentacle[i - 1] = tentacle_center[i - 1].getChild("tentacle_" + i); + } + } + + @Override + public void setupAnim( + CubozoaEntity entity, + float limbAngle, + float limbDistance, + float animationProgress, + float headYaw, + float headPitch + ) { + float sin = Mth.sin(animationProgress * 0.13F); + scaleY = sin * 0.1F + 0.9F; + scaleXZ = Mth.sin(animationProgress * 0.13F + 3.14F) * 0.1F + 0.9F; + + for (int i = 0; i < TENTACLE_COUNT; i++) { + tentacle[i].xRot = sin * 0.15f; + } + } + + @Override + public void renderToBuffer( + PoseStack matrices, + VertexConsumer vertices, + int light, + int overlay, + float red, + float green, + float blue, + float alpha + ) { + matrices.pushPose(); + matrices.scale(scaleXZ, scaleY, scaleXZ); + model.render(matrices, vertices, light, overlay); + matrices.popPose(); + } +} diff --git a/src/main/java/org/betterx/betterend/entity/model/DragonflyEntityModel.java b/src/main/java/org/betterx/betterend/entity/model/DragonflyEntityModel.java new file mode 100644 index 00000000..869bf62d --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/model/DragonflyEntityModel.java @@ -0,0 +1,148 @@ +package org.betterx.betterend.entity.model; + +import org.betterx.betterend.entity.DragonflyEntity; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartNames; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.client.renderer.RenderType; + +public class DragonflyEntityModel extends EntityModel { + private final ModelPart model; + private final ModelPart head; + private final ModelPart tail; + private final ModelPart tail_2; + private final ModelPart wing_1; + private final ModelPart wing_2; + private final ModelPart wing_3; + private final ModelPart wing_4; + private final ModelPart legs_1; + private final ModelPart legs_2; + + public static LayerDefinition getTexturedModelData() { + MeshDefinition modelData = new MeshDefinition(); + PartDefinition modelPartData = modelData.getRoot(); + + PartDefinition bodyPart = modelPartData.addOrReplaceChild( + PartNames.BODY, + CubeListBuilder.create().texOffs(0, 0).addBox(-4.0F, -4.0F, 0.0F, 4.0F, 4.0F, 9.0F), + PartPose.offset(2.0F, 21.5F, -4.0F) + ); + + bodyPart.addOrReplaceChild( + PartNames.HEAD, + CubeListBuilder.create().texOffs(17, 0).addBox(-1.5F, -1.5F, -2.5F, 3.0F, 3.0F, 3.0F), + PartPose.offsetAndRotation(-2.0F, -2.0F, 0.0F, 0.3491F, 0.0F, 0.0F) + ); + + PartDefinition tailPart = bodyPart.addOrReplaceChild( + PartNames.TAIL, + CubeListBuilder.create().texOffs(26, 0).addBox(-1.5F, -1.5F, 0.0F, 3.0F, 3.0F, 7.0F), + PartPose.offset(-2.0F, -2.0F, 9.0F) + ); + + tailPart.addOrReplaceChild( + PartNames.TAIL_FIN, + CubeListBuilder.create().texOffs(36, 0).addBox(-1.0F, -1.0F, 0.0F, 2.0F, 2.0F, 10.0F), + PartPose.offset(0.0F, 0.0F, 7.0F) + ); + + bodyPart.addOrReplaceChild( + PartNames.LEFT_WING, + CubeListBuilder.create().texOffs(0, 13).addBox(-15.0F, 0.0F, -3.0F, 15.0F, 0.0F, 4.0F), + PartPose.offset(-2.0F, -4.0F, 4.0F) + ); + + bodyPart.addOrReplaceChild( + PartNames.RIGHT_WING, + CubeListBuilder.create().mirror().texOffs(0, 13).addBox(0.0F, 0.0F, -3.0F, 15.0F, 0.0F, 4.0F), + PartPose.offset(-2.0F, -4.0F, 4.0F) + ); + + bodyPart.addOrReplaceChild( + PartNames.LEFT_WING_BASE, + CubeListBuilder.create().texOffs(4, 17).addBox(-12.0F, 0.0F, -2.5F, 12.0F, 0.0F, 3.0F), + PartPose.offset(-2.0F, -4.0F, 8.0F) + ); + + bodyPart.addOrReplaceChild( + PartNames.RIGHT_WING_BASE, + CubeListBuilder.create().mirror().texOffs(4, 17).addBox(0.0F, 0.0F, -2.5F, 12.0F, 0.0F, 3.0F), + PartPose.offset(-2.0F, -4.0F, 8.0F) + ); + + bodyPart.addOrReplaceChild( + PartNames.LEFT_LEG, + CubeListBuilder.create().texOffs(50, 1).addBox(0.0F, 0.0F, 0.0F, 0.0F, 3.0F, 6.0F), + PartPose.offsetAndRotation(-1.0F, 0.0F, 1.0F, 0.0F, 0.0F, -0.5236F) + ); + + bodyPart.addOrReplaceChild( + PartNames.RIGHT_LEG, + CubeListBuilder.create().texOffs(50, 1).addBox(0.0F, 0.0F, 0.0F, 0.0F, 3.0F, 6.0F), + PartPose.offsetAndRotation(-3.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.5236F) + ); + + return LayerDefinition.create(modelData, 64, 64); + } + + public DragonflyEntityModel(ModelPart modelPart) { + super(RenderType::entityCutout); + + model = modelPart.getChild(PartNames.BODY); + head = model.getChild(PartNames.HEAD); + tail = model.getChild(PartNames.TAIL); + tail_2 = tail.getChild(PartNames.TAIL_FIN); + wing_1 = model.getChild(PartNames.LEFT_WING); + wing_2 = model.getChild(PartNames.RIGHT_WING); + wing_3 = model.getChild(PartNames.LEFT_WING_BASE); + wing_4 = model.getChild(PartNames.RIGHT_WING_BASE); + legs_1 = model.getChild(PartNames.LEFT_LEG); + legs_2 = model.getChild(PartNames.RIGHT_LEG); + } + + @Override + public void setupAnim( + DragonflyEntity entity, + float limbAngle, + float limbDistance, + float animationProgress, + float headYaw, + float headPitch + ) { + float progress = animationProgress * 2F; + + wing_1.zRot = 0.3491F + (float) Math.sin(progress) * 0.3491F; + wing_2.zRot = -wing_1.zRot; + + wing_3.zRot = 0.3491F + (float) Math.cos(progress) * 0.3491F; + wing_4.zRot = -wing_3.zRot; + + progress = animationProgress * 0.05F; + + head.xRot = 0.3491F + (float) Math.sin(progress * 0.7F) * 0.1F; + tail.xRot = (float) Math.cos(progress) * 0.05F - 0.05F; + tail_2.xRot = -tail.xRot * 1.5F; + } + + @Override + public void renderToBuffer( + PoseStack matrices, + VertexConsumer vertices, + int light, + int overlay, + float red, + float green, + float blue, + float alpha + ) { + model.render(matrices, vertices, light, overlay); + } +} diff --git a/src/main/java/org/betterx/betterend/entity/model/EndFishEntityModel.java b/src/main/java/org/betterx/betterend/entity/model/EndFishEntityModel.java new file mode 100644 index 00000000..b9029277 --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/model/EndFishEntityModel.java @@ -0,0 +1,110 @@ +package org.betterx.betterend.entity.model; + +import org.betterx.betterend.entity.EndFishEntity; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartNames; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.client.renderer.RenderType; + +public class EndFishEntityModel extends EntityModel { + private final ModelPart model; + private final ModelPart fin_top; + private final ModelPart fin_bottom; + private final ModelPart flipper; + private final ModelPart fin_right; + private final ModelPart fin_left; + + public static LayerDefinition getTexturedModelData() { + MeshDefinition modelData = new MeshDefinition(); + PartDefinition modelPartData = modelData.getRoot(); + + PartDefinition bodyPart = modelPartData.addOrReplaceChild( + PartNames.BODY, + CubeListBuilder.create().texOffs(0, 0).addBox(-1.0F, -2.0F, -4.0F, 2.0F, 4.0F, 8.0F), + PartPose.offset(0.0F, 20.0F, 0.0F) + ); + + bodyPart.addOrReplaceChild( + PartNames.TOP_FIN, + CubeListBuilder.create().texOffs(0, 6).addBox(0.0F, -8.0F, 0.0F, 0.0F, 8.0F, 6.0F), + PartPose.offsetAndRotation(0.0F, -2.0F, -4.0F, -0.6981F, 0.0F, 0.0F) + ); + + bodyPart.addOrReplaceChild( + PartNames.BOTTOM_FIN, + CubeListBuilder.create().texOffs(0, 6).addBox(0.0F, 0.0F, 0.0F, 0.0F, 8.0F, 6.0F), + PartPose.offsetAndRotation(0.0F, 2.0F, -4.0F, 0.6981F, 0.0F, 0.0F) + ); + + bodyPart.addOrReplaceChild( + PartNames.TAIL_FIN, + CubeListBuilder.create().texOffs(0, 15).addBox(0.0F, -5.0F, 0.0F, 0.0F, 5.0F, 5.0F), + PartPose.offsetAndRotation(0.0F, 0.0F, 2.0F, -0.7854F, 0.0F, 0.0F) + ); + + bodyPart.addOrReplaceChild( + PartNames.RIGHT_FIN, + CubeListBuilder.create().texOffs(0, 25).addBox(-3.7071F, 0.7071F, -1.5F, 3.0F, 0.0F, 3.0F), + PartPose.offsetAndRotation(-1.0F, 0.0F, -1.0F, 1.5708F, 0.7854F, 0.0F) + ); + + bodyPart.addOrReplaceChild( + PartNames.LEFT_FIN, + CubeListBuilder.create().mirror().texOffs(0, 25).addBox(0.7071F, 0.7071F, -1.5F, 3.0F, 0.0F, 3.0F), + PartPose.offsetAndRotation(-1.0F, 0.0F, -1.0F, 1.5708F, -0.7854F, 0.0F) + ); + + return LayerDefinition.create(modelData, 32, 32); + } + + public EndFishEntityModel(ModelPart modelPart) { + super(RenderType::entityCutout); + + model = modelPart.getChild(PartNames.BODY); + fin_top = model.getChild(PartNames.TOP_FIN); + fin_bottom = model.getChild(PartNames.BOTTOM_FIN); + flipper = model.getChild(PartNames.TAIL_FIN); + fin_right = model.getChild(PartNames.RIGHT_FIN); + fin_left = model.getChild(PartNames.LEFT_FIN); + } + + @Override + public void setupAnim( + EndFishEntity entity, + float limbAngle, + float limbDistance, + float animationProgress, + float headYaw, + float headPitch + ) { + float s1 = (float) Math.sin(animationProgress * 0.1); + float s2 = (float) Math.sin(animationProgress * 0.05); + flipper.yRot = s1 * 0.3F; + fin_top.xRot = s2 * 0.02F - 0.6981F; + fin_bottom.xRot = 0.6981F - s2 * 0.02F; + fin_left.yRot = s1 * 0.3F - 0.7854F; + fin_right.yRot = 0.7854F - s1 * 0.3F; + } + + @Override + public void renderToBuffer( + PoseStack matrices, + VertexConsumer vertices, + int light, + int overlay, + float red, + float green, + float blue, + float alpha + ) { + model.render(matrices, vertices, light, overlay); + } +} diff --git a/src/main/java/org/betterx/betterend/entity/model/EndSlimeEntityModel.java b/src/main/java/org/betterx/betterend/entity/model/EndSlimeEntityModel.java new file mode 100644 index 00000000..3b0745ee --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/model/EndSlimeEntityModel.java @@ -0,0 +1,156 @@ +package org.betterx.betterend.entity.model; + +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.entity.EndSlimeEntity; +import org.betterx.betterend.registry.EndEntitiesRenders; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.ListModel; +import net.minecraft.client.model.geom.EntityModelSet; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartNames; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.client.renderer.RenderType; + +import com.google.common.collect.ImmutableList; + +public class EndSlimeEntityModel extends ListModel { + private final ModelPart innerCube; + private final ModelPart rightEye; + private final ModelPart leftEye; + private final ModelPart mouth; + private final ModelPart flower; + private final ModelPart crop; + + public static LayerDefinition getShellOnlyTexturedModelData() { + return getTexturedModelData(true); + } + + public static LayerDefinition getCompleteTexturedModelData() { + return getTexturedModelData(false); + } + + private static LayerDefinition getTexturedModelData(boolean onlyShell) { + MeshDefinition modelData = new MeshDefinition(); + PartDefinition modelPartData = modelData.getRoot(); + + if (onlyShell) { + modelPartData.addOrReplaceChild( + PartNames.BODY, + CubeListBuilder.create().texOffs(0, 0).addBox(-4.0F, 16.0F, -4.0F, 8.0F, 8.0F, 8.0F), + PartPose.ZERO + ); + } else { + modelPartData.addOrReplaceChild( + PartNames.BODY, + CubeListBuilder.create().texOffs(0, 16).addBox(-3.0F, 17.0F, -3.0F, 6.0F, 6.0F, 6.0F), + PartPose.ZERO + ); + + modelPartData.addOrReplaceChild( + PartNames.RIGHT_EYE, + CubeListBuilder.create().texOffs(32, 0).addBox(-3.25F, 18.0F, -3.5F, 2.0F, 2.0F, 2.0F), + PartPose.ZERO + ); + + modelPartData.addOrReplaceChild( + PartNames.LEFT_EYE, + CubeListBuilder.create().texOffs(32, 4).addBox(1.25F, 18.0F, -3.5F, 2.0F, 2.0F, 2.0F), + PartPose.ZERO + ); + + modelPartData.addOrReplaceChild( + PartNames.MOUTH, + CubeListBuilder.create().texOffs(32, 8).addBox(0.0F, 21.0F, -3.5F, 1.0F, 1.0F, 1.0F), + PartPose.ZERO + ); + + PartDefinition flowerPart = modelPartData.addOrReplaceChild( + "flower", + CubeListBuilder.create(), + PartPose.ZERO + ); + PartDefinition cropPart = modelPartData.addOrReplaceChild("crop", CubeListBuilder.create(), PartPose.ZERO); + + for (int i = 0; i < 6; i++) { + final PartDefinition parent = i < 4 ? flowerPart : cropPart; + final float rot = MHelper.degreesToRadians(i < 4 ? (i * 45F) : ((i - 4) * 90F + 45F)); + + PartDefinition petalRotPart = parent.addOrReplaceChild( + "petalRot_" + i, + CubeListBuilder.create(), + PartPose.offsetAndRotation(0, 0, 0, 0, rot, 0) + ); + + + petalRotPart.addOrReplaceChild( + "petal_" + i, + CubeListBuilder.create().texOffs(40, 0).addBox(0.0F, 0.0F, 0.0F, 8.0F, 8.0F, 0.0F), + PartPose.offset(-4, 8, 0) + ); + } + } + + return LayerDefinition.create(modelData, 64, 32); + } + + public EndSlimeEntityModel(EntityModelSet modelSet, boolean onlyShell) { + super(RenderType::entityCutout); + + ModelPart modelPart = modelSet.bakeLayer(onlyShell + ? EndEntitiesRenders.END_SLIME_SHELL_MODEL + : EndEntitiesRenders.END_SLIME_MODEL); + + innerCube = modelPart.getChild(PartNames.BODY); + if (!onlyShell) { + rightEye = modelPart.getChild(PartNames.RIGHT_EYE); + leftEye = modelPart.getChild(PartNames.LEFT_EYE); + mouth = modelPart.getChild(PartNames.MOUTH); + flower = modelPart.getChild("flower"); + crop = modelPart.getChild("crop"); + } else { + rightEye = null; + leftEye = null; + mouth = null; + flower = null; + crop = null; + } + } + + @Override + public void setupAnim( + T entity, + float limbAngle, + float limbDistance, + float animationProgress, + float headYaw, + float headPitch + ) { + } + + public void renderFlower(PoseStack matrices, VertexConsumer vertices, int light, int overlay) { + flower.render(matrices, vertices, light, overlay); + } + + public void renderCrop(PoseStack matrices, VertexConsumer vertices, int light, int overlay) { + crop.render(matrices, vertices, light, overlay); + } + + private boolean isOnlyShell() { + return rightEye == null; + } + + @Override + public Iterable parts() { + if (isOnlyShell()) { + return ImmutableList.of(this.innerCube); + } else { + return ImmutableList.of(this.innerCube, this.rightEye, this.leftEye, this.mouth); + } + } +} diff --git a/src/main/java/org/betterx/betterend/entity/model/SilkMothEntityModel.java b/src/main/java/org/betterx/betterend/entity/model/SilkMothEntityModel.java new file mode 100644 index 00000000..af94286c --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/model/SilkMothEntityModel.java @@ -0,0 +1,187 @@ +package org.betterx.betterend.entity.model; + +import org.betterx.betterend.entity.SilkMothEntity; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartNames; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.util.Mth; + +public class SilkMothEntityModel extends EntityModel { + private final ModelPart legsL; + private final ModelPart cube_r1; + private final ModelPart cube_r2; + private final ModelPart cube_r3; + private final ModelPart legsR; + private final ModelPart cube_r4; + private final ModelPart cube_r5; + private final ModelPart cube_r6; + private final ModelPart head_pivot; + private final ModelPart tendril_r_r1; + private final ModelPart tendril_r_r2; + private final ModelPart bb_main; + private final ModelPart wingR_r1; + private final ModelPart wingL_r1; + private final ModelPart abdomen_r1; + + public static LayerDefinition getTexturedModelData() { + MeshDefinition modelData = new MeshDefinition(); + PartDefinition modelPartData = modelData.getRoot(); + + PartDefinition legsL = modelPartData.addOrReplaceChild( + PartNames.LEFT_LEG, + CubeListBuilder.create().texOffs(0, 0), + PartPose.offsetAndRotation(1.5f, 19.9f, -0.45f, 0.0f, 0.0f, 0.6981f) + ); + + legsL.addOrReplaceChild( + "cube_r1", + CubeListBuilder.create().texOffs(0, 13).addBox(0.0216f, 0.0f, -0.5976f, 3.0f, 0.0f, 1.0f), + PartPose.offsetAndRotation(0.0f, 0.0f, -1.0f, 0.0f, 0.2182f, 0.3927f) + ); + + legsL.addOrReplaceChild( + "cube_r2", + CubeListBuilder.create().texOffs(0, 15).addBox(0.0f, 0.0f, -0.6f, 3.0f, 0.0f, 1.0f), + PartPose.offsetAndRotation(0.5f, 0.1f, -0.05f, 0.0f, 0.0f, 0.3927f) + ); + + legsL.addOrReplaceChild( + "cube_r3", + CubeListBuilder.create().texOffs(0, 14).addBox(0.0f, 0.0f, -0.5f, 3.0f, 0.0f, 1.0f), + PartPose.offsetAndRotation(0.0f, 0.0f, 0.9f, 0.0f, -0.2182f, 0.3927f) + ); + + PartDefinition legsR = modelPartData.addOrReplaceChild( + PartNames.RIGHT_LEG, + CubeListBuilder.create().texOffs(0, 0), + PartPose.offsetAndRotation(-1.5f, 19.9f, -0.55f, 0.0f, 3.1416f, -0.6545f) + ); + + legsR.addOrReplaceChild( + "cube_r4", + CubeListBuilder.create().texOffs(0, 10).addBox(0.0f, 0.0f, -0.5f, 3.0f, 0.0f, 1.0f), + PartPose.offsetAndRotation(0.0f, 0.0f, -1.0f, 0.0f, 0.2182f, 0.3927f) + ); + + legsR.addOrReplaceChild( + "cube_r5", + CubeListBuilder.create().texOffs(0, 11).addBox(0.0f, 0.0f, -0.4f, 3.0f, 0.0f, 1.0f), + PartPose.offsetAndRotation(0.5f, 0.1f, -0.05f, 0.0f, 0.0f, 0.3927f) + ); + + legsR.addOrReplaceChild( + "cube_r6", + CubeListBuilder.create().texOffs(0, 12).addBox(0.0216f, 0.0f, -0.4024f, 3.0f, 0.0f, 1.0f), + PartPose.offsetAndRotation(0.0f, 0.0f, 0.9f, 0.0f, -0.2182f, 0.3927f) + ); + + PartDefinition head_pivot = modelPartData.addOrReplaceChild( + PartNames.HEAD, + CubeListBuilder.create().texOffs(15, 10).addBox(-1.5f, -1.5f, -2.0f, 3.0f, 3.0f, 3.0f), + PartPose.offset(0.0f, 18.0f, -3.0f) + ); + + head_pivot.addOrReplaceChild( + "tendril_r_r1", + CubeListBuilder.create().mirror().texOffs(23, 0).addBox(-1.5f, -5.0f, 0.0f, 3.0f, 5.0f, 0.0f), + PartPose.offsetAndRotation(1.0f, -1.15f, -1.0f, 0.0f, 0.0f, 0.3927f) + ); + + head_pivot.addOrReplaceChild( + "tendril_r_r2", + CubeListBuilder.create().texOffs(23, 0).addBox(-1.5f, -5.0f, 0.0f, 3.0f, 5.0f, 0.0f), + PartPose.offsetAndRotation(-1.0f, -1.15f, -1.0f, 0.0f, 0.0f, -0.3927f) + ); + + PartDefinition bb_main = modelPartData.addOrReplaceChild( + PartNames.BODY, + CubeListBuilder.create().texOffs(19, 19).addBox(-2.5f, -8.5f, -3.0f, 5.0f, 5.0f, 3.0f), + PartPose.offset(0.0f, 24.0f, 0.0f) + ); + + bb_main.addOrReplaceChild( + PartNames.RIGHT_WING, + CubeListBuilder.create().mirror().texOffs(0, 5).addBox(-7.0f, 0.0f, -3.0f, 9.0f, 0.0f, 5.0f), + PartPose.offsetAndRotation(-1.5f, -6.5f, 0.5f, 0.0f, 0.0f, 0.3927f) + ); + + bb_main.addOrReplaceChild( + PartNames.LEFT_WING, + CubeListBuilder.create().texOffs(0, 5).addBox(-2.0f, 0.0f, -3.0f, 9.0f, 0.0f, 5.0f), + PartPose.offsetAndRotation(1.5f, -6.5f, 0.5f, 0.0f, 0.0f, -0.3927f) + ); + + bb_main.addOrReplaceChild( + "abdomen_r1", + CubeListBuilder.create().texOffs(0, 10).addBox(-3.0f, -4.0f, -1.0f, 4.0f, 4.0f, 7.0f), + PartPose.offsetAndRotation(1.0f, -3.9f, 0.0f, -0.3927f, 0.0f, 0.0f) + ); + + return LayerDefinition.create(modelData, 64, 64); + } + + public SilkMothEntityModel(ModelPart modelPart) { + super(RenderType::entityCutout); + + legsL = modelPart.getChild(PartNames.LEFT_LEG); + cube_r1 = legsL.getChild("cube_r1"); + cube_r2 = legsL.getChild("cube_r2"); + cube_r3 = legsL.getChild("cube_r3"); + legsR = modelPart.getChild(PartNames.RIGHT_LEG); + cube_r4 = legsR.getChild("cube_r4"); + cube_r5 = legsR.getChild("cube_r5"); + cube_r6 = legsR.getChild("cube_r6"); + head_pivot = modelPart.getChild(PartNames.HEAD); + tendril_r_r1 = head_pivot.getChild("tendril_r_r1"); + tendril_r_r2 = head_pivot.getChild("tendril_r_r2"); + bb_main = modelPart.getChild(PartNames.BODY); + wingR_r1 = bb_main.getChild(PartNames.RIGHT_WING); + wingL_r1 = bb_main.getChild(PartNames.LEFT_WING); + abdomen_r1 = bb_main.getChild("abdomen_r1"); + } + + @Override + public void setupAnim( + SilkMothEntity entity, + float limbAngle, + float limbDistance, + float animationProgress, + float headYaw, + float headPitch + ) { + wingR_r1.zRot = Mth.sin(animationProgress * 2F) * 0.4F + 0.3927F; + wingL_r1.zRot = -wingR_r1.zRot; + head_pivot.xRot = Mth.sin(animationProgress * 0.03F) * 0.1F; + tendril_r_r1.zRot = Mth.sin(animationProgress * 0.07F) * 0.2F + 0.3927F; + tendril_r_r2.zRot = -tendril_r_r1.zRot; + abdomen_r1.xRot = Mth.sin(animationProgress * 0.05F) * 0.1F - 0.3927F; + legsR.zRot = Mth.sin(animationProgress * 0.07F) * 0.1F - 0.6545F; + legsL.zRot = -legsR.zRot; + } + + @Override + public void renderToBuffer( + PoseStack matrices, + VertexConsumer vertices, + int light, + int overlay, + float red, + float green, + float blue, + float alpha + ) { + bb_main.render(matrices, vertices, light, overlay); + head_pivot.render(matrices, vertices, light, overlay); + legsL.render(matrices, vertices, light, overlay); + legsR.render(matrices, vertices, light, overlay); + } +} diff --git a/src/main/java/org/betterx/betterend/entity/render/RendererEntityCubozoa.java b/src/main/java/org/betterx/betterend/entity/render/RendererEntityCubozoa.java new file mode 100644 index 00000000..838f4846 --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/render/RendererEntityCubozoa.java @@ -0,0 +1,77 @@ +package org.betterx.betterend.entity.render; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.entity.CubozoaEntity; +import org.betterx.betterend.entity.model.CubozoaEntityModel; +import org.betterx.betterend.registry.EndEntitiesRenders; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.client.renderer.entity.layers.EyesLayer; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; + +public class RendererEntityCubozoa extends MobRenderer { + private static final ResourceLocation[] TEXTURE = new ResourceLocation[2]; + private static final RenderType[] GLOW = new RenderType[2]; + + public RendererEntityCubozoa(EntityRendererProvider.Context ctx) { + super(ctx, new CubozoaEntityModel(ctx.bakeLayer(EndEntitiesRenders.CUBOZOA_MODEL)), 0.5f); + this.addLayer(new EyesLayer(this) { + @Override + public RenderType renderType() { + return GLOW[0]; + } + + @Override + public void render( + PoseStack matrices, + MultiBufferSource vertexConsumers, + int light, + CubozoaEntity entity, + float limbAngle, + float limbDistance, + float tickDelta, + float animationProgress, + float headYaw, + float headPitch + ) { + VertexConsumer vertexConsumer = vertexConsumers.getBuffer(GLOW[entity.getVariant()]); + this.getParentModel() + .renderToBuffer( + matrices, + vertexConsumer, + 15728640, + OverlayTexture.NO_OVERLAY, + 1.0F, + 1.0F, + 1.0F, + 1.0F + ); + } + }); + } + + @Override + protected void scale(CubozoaEntity entity, PoseStack matrixStack, float f) { + float scale = entity.getScale(); + matrixStack.scale(scale, scale, scale); + } + + @Override + public ResourceLocation getTextureLocation(CubozoaEntity entity) { + return TEXTURE[entity.getVariant()]; + } + + static { + TEXTURE[0] = BetterEnd.makeID("textures/entity/cubozoa/cubozoa.png"); + TEXTURE[1] = BetterEnd.makeID("textures/entity/cubozoa/cubozoa_sulphur.png"); + + GLOW[0] = RenderType.eyes(BetterEnd.makeID("textures/entity/cubozoa/cubozoa_glow.png")); + GLOW[1] = RenderType.eyes(BetterEnd.makeID("textures/entity/cubozoa/cubozoa_sulphur_glow.png")); + } +} \ No newline at end of file diff --git a/src/main/java/ru/betterend/entity/render/RendererEntityDragonfly.java b/src/main/java/org/betterx/betterend/entity/render/RendererEntityDragonfly.java similarity index 63% rename from src/main/java/ru/betterend/entity/render/RendererEntityDragonfly.java rename to src/main/java/org/betterx/betterend/entity/render/RendererEntityDragonfly.java index 37e82160..46ebb687 100644 --- a/src/main/java/ru/betterend/entity/render/RendererEntityDragonfly.java +++ b/src/main/java/org/betterx/betterend/entity/render/RendererEntityDragonfly.java @@ -1,30 +1,32 @@ -package ru.betterend.entity.render; - -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.entity.EntityRenderDispatcher; -import net.minecraft.client.renderer.entity.MobRenderer; -import net.minecraft.client.renderer.entity.layers.EyesLayer; -import net.minecraft.resources.ResourceLocation; -import ru.betterend.BetterEnd; -import ru.betterend.entity.DragonflyEntity; -import ru.betterend.entity.model.DragonflyEntityModel; - -public class RendererEntityDragonfly extends MobRenderer { - private static final ResourceLocation TEXTURE = BetterEnd.makeID("textures/entity/dragonfly.png"); - private static final RenderType GLOW = RenderType.eyes(BetterEnd.makeID("textures/entity/dragonfly_glow.png")); - - public RendererEntityDragonfly(EntityRenderDispatcher entityRenderDispatcher) { - super(entityRenderDispatcher, new DragonflyEntityModel(), 0.5f); - this.addLayer(new EyesLayer(this) { - @Override - public RenderType renderType() { - return GLOW; - } - }); - } - - @Override - public ResourceLocation getTextureLocation(DragonflyEntity entity) { - return TEXTURE; - } +package org.betterx.betterend.entity.render; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.entity.DragonflyEntity; +import org.betterx.betterend.entity.model.DragonflyEntityModel; +import org.betterx.betterend.registry.EndEntitiesRenders; + +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.client.renderer.entity.layers.EyesLayer; +import net.minecraft.resources.ResourceLocation; + +public class RendererEntityDragonfly extends MobRenderer { + private static final ResourceLocation TEXTURE = BetterEnd.makeID("textures/entity/dragonfly.png"); + private static final RenderType GLOW = RenderType.eyes(BetterEnd.makeID("textures/entity/dragonfly_glow.png")); + + public RendererEntityDragonfly(EntityRendererProvider.Context ctx) { + super(ctx, new DragonflyEntityModel(ctx.bakeLayer(EndEntitiesRenders.DRAGONFLY_MODEL)), 0.5f); + this.addLayer(new EyesLayer(this) { + @Override + public RenderType renderType() { + return GLOW; + } + }); + } + + @Override + public ResourceLocation getTextureLocation(DragonflyEntity entity) { + return TEXTURE; + } } \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/entity/render/RendererEntityEndFish.java b/src/main/java/org/betterx/betterend/entity/render/RendererEntityEndFish.java new file mode 100644 index 00000000..a57e1f37 --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/render/RendererEntityEndFish.java @@ -0,0 +1,76 @@ +package org.betterx.betterend.entity.render; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.entity.EndFishEntity; +import org.betterx.betterend.entity.model.EndFishEntityModel; +import org.betterx.betterend.registry.EndEntitiesRenders; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.client.renderer.entity.layers.EyesLayer; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; + +public class RendererEntityEndFish extends MobRenderer { + private static final ResourceLocation[] TEXTURE = new ResourceLocation[EndFishEntity.VARIANTS]; + private static final RenderType[] GLOW = new RenderType[EndFishEntity.VARIANTS]; + + public RendererEntityEndFish(EntityRendererProvider.Context ctx) { + super(ctx, new EndFishEntityModel(ctx.bakeLayer(EndEntitiesRenders.END_FISH_MODEL)), 0.5f); + this.addLayer(new EyesLayer(this) { + @Override + public RenderType renderType() { + return GLOW[0]; + } + + @Override + public void render( + PoseStack matrices, + MultiBufferSource vertexConsumers, + int light, + EndFishEntity entity, + float limbAngle, + float limbDistance, + float tickDelta, + float animationProgress, + float headYaw, + float headPitch + ) { + VertexConsumer vertexConsumer = vertexConsumers.getBuffer(GLOW[entity.getVariant()]); + this.getParentModel() + .renderToBuffer( + matrices, + vertexConsumer, + 15728640, + OverlayTexture.NO_OVERLAY, + 1.0F, + 1.0F, + 1.0F, + 1.0F + ); + } + }); + } + + @Override + protected void scale(EndFishEntity entity, PoseStack matrixStack, float f) { + float scale = entity.getScale(); + matrixStack.scale(scale, scale, scale); + } + + @Override + public ResourceLocation getTextureLocation(EndFishEntity entity) { + return TEXTURE[entity.getVariant()]; + } + + static { + for (int i = 0; i < EndFishEntity.VARIANTS; i++) { + TEXTURE[i] = BetterEnd.makeID("textures/entity/end_fish/end_fish_" + i + ".png"); + GLOW[i] = RenderType.eyes(BetterEnd.makeID("textures/entity/end_fish/end_fish_" + i + "_glow.png")); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/entity/render/RendererEntityEndSlime.java b/src/main/java/org/betterx/betterend/entity/render/RendererEntityEndSlime.java new file mode 100644 index 00000000..d2d2db51 --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/render/RendererEntityEndSlime.java @@ -0,0 +1,172 @@ +package org.betterx.betterend.entity.render; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.entity.EndSlimeEntity; +import org.betterx.betterend.entity.model.EndSlimeEntityModel; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.client.renderer.entity.RenderLayerParent; +import net.minecraft.client.renderer.entity.layers.EyesLayer; +import net.minecraft.client.renderer.entity.layers.RenderLayer; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; + +public class RendererEntityEndSlime extends MobRenderer> { + private static final ResourceLocation[] TEXTURE = new ResourceLocation[4]; + private static final RenderType[] GLOW = new RenderType[4]; + + public RendererEntityEndSlime(EntityRendererProvider.Context ctx) { + super(ctx, new EndSlimeEntityModel<>(ctx.getModelSet(), false), 0.25f); + this.addLayer(new OverlayFeatureRenderer(this, ctx)); + this.addLayer(new EyesLayer>(this) { + @Override + public RenderType renderType() { + return GLOW[0]; + } + + @Override + public void render( + PoseStack matrices, + MultiBufferSource vertexConsumers, + int light, + EndSlimeEntity entity, + float limbAngle, + float limbDistance, + float tickDelta, + float animationProgress, + float headYaw, + float headPitch + ) { + VertexConsumer vertexConsumer = vertexConsumers.getBuffer(GLOW[entity.getSlimeType()]); + this.getParentModel() + .renderToBuffer( + matrices, + vertexConsumer, + 15728640, + OverlayTexture.NO_OVERLAY, + 1.0F, + 1.0F, + 1.0F, + 1.0F + ); + if (entity.isLake()) { + this.getParentModel().renderFlower(matrices, vertexConsumer, 15728640, OverlayTexture.NO_OVERLAY); + } + } + }); + } + + @Override + public ResourceLocation getTextureLocation(EndSlimeEntity entity) { + return TEXTURE[entity.getSlimeType()]; + } + + @Override + public void render( + EndSlimeEntity slimeEntity, + float f, + float g, + PoseStack matrixStack, + MultiBufferSource vertexConsumerProvider, + int i + ) { + this.shadowRadius = 0.25F * (float) slimeEntity.getSize(); + super.render(slimeEntity, f, g, matrixStack, vertexConsumerProvider, i); + } + + @Override + protected void scale(EndSlimeEntity slimeEntity, PoseStack matrixStack, float f) { + matrixStack.scale(0.999F, 0.999F, 0.999F); + matrixStack.translate(0.0D, 0.0010000000474974513D, 0.0D); + float h = (float) slimeEntity.getSize(); + float i = Mth.lerp(f, slimeEntity.oSquish, slimeEntity.squish) / (h * 0.5F + 1.0F); + float j = 1.0F / (i + 1.0F); + matrixStack.scale(j * h, 1.0F / j * h, j * h); + } + + private final class OverlayFeatureRenderer extends RenderLayer> { + private final EndSlimeEntityModel modelOrdinal; + private final EndSlimeEntityModel modelLake; + + public OverlayFeatureRenderer( + RenderLayerParent> featureRendererContext, + EntityRendererProvider.Context ctx + ) { + super(featureRendererContext); + modelOrdinal = new EndSlimeEntityModel<>(ctx.getModelSet(), true); + modelLake = new EndSlimeEntityModel<>(ctx.getModelSet(), true); + } + + public void render( + PoseStack matrixStack, + MultiBufferSource vertexConsumerProvider, + int i, + T livingEntity, + float f, + float g, + float h, + float j, + float k, + float l + ) { + if (!livingEntity.isInvisible()) { + if (livingEntity.isLake()) { + VertexConsumer vertexConsumer = vertexConsumerProvider.getBuffer(RenderType.entityCutout(this.getTextureLocation( + livingEntity))); + this.getParentModel() + .renderFlower( + matrixStack, + vertexConsumer, + i, + LivingEntityRenderer.getOverlayCoords(livingEntity, 0.0F) + ); + } else if (livingEntity.isAmber() || livingEntity.isChorus()) { + VertexConsumer vertexConsumer = vertexConsumerProvider.getBuffer(RenderType.entityCutout(this.getTextureLocation( + livingEntity))); + this.getParentModel() + .renderCrop( + matrixStack, + vertexConsumer, + i, + LivingEntityRenderer.getOverlayCoords(livingEntity, 0.0F) + ); + } + + EndSlimeEntityModel model = livingEntity.getSlimeType() == 1 ? modelLake : modelOrdinal; + this.getParentModel().copyPropertiesTo(model); + model.prepareMobModel(livingEntity, f, g, h); + model.setupAnim(livingEntity, f, g, j, k, l); + VertexConsumer vertexConsumer = vertexConsumerProvider.getBuffer(RenderType.entityTranslucent(this.getTextureLocation( + livingEntity))); + model.renderToBuffer( + matrixStack, + vertexConsumer, + i, + LivingEntityRenderer.getOverlayCoords(livingEntity, 0.0F), + 1.0F, + 1.0F, + 1.0F, + 1.0F + ); + } + } + } + + static { + TEXTURE[0] = BetterEnd.makeID("textures/entity/end_slime/end_slime.png"); + TEXTURE[1] = BetterEnd.makeID("textures/entity/end_slime/end_slime_mossy.png"); + TEXTURE[2] = BetterEnd.makeID("textures/entity/end_slime/end_slime_lake.png"); + TEXTURE[3] = BetterEnd.makeID("textures/entity/end_slime/end_slime_amber.png"); + GLOW[0] = RenderType.eyes(BetterEnd.makeID("textures/entity/end_slime/end_slime_glow.png")); + GLOW[1] = GLOW[0]; + GLOW[2] = RenderType.eyes(BetterEnd.makeID("textures/entity/end_slime/end_slime_lake_glow.png")); + GLOW[3] = RenderType.eyes(BetterEnd.makeID("textures/entity/end_slime/end_slime_amber_glow.png")); + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/entity/render/RendererEntityShadowWalker.java b/src/main/java/org/betterx/betterend/entity/render/RendererEntityShadowWalker.java new file mode 100644 index 00000000..1985c2d9 --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/render/RendererEntityShadowWalker.java @@ -0,0 +1,24 @@ +package org.betterx.betterend.entity.render; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.entity.ShadowWalkerEntity; + +import net.minecraft.client.model.PlayerModel; +import net.minecraft.client.model.geom.ModelLayers; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.HumanoidMobRenderer; +import net.minecraft.resources.ResourceLocation; + +public class RendererEntityShadowWalker extends HumanoidMobRenderer> { + private static final ResourceLocation TEXTURE = BetterEnd.makeID("textures/entity/shadow_walker.png"); + + public RendererEntityShadowWalker(EntityRendererProvider.Context ctx) { + super(ctx, new PlayerModel(ctx.bakeLayer(ModelLayers.PLAYER), false), 0.5F); + //super(entityRenderDispatcher, new PlayerModel(0.0F, false), 0.5F); + } + + @Override + public ResourceLocation getTextureLocation(ShadowWalkerEntity zombieEntity) { + return TEXTURE; + } +} diff --git a/src/main/java/org/betterx/betterend/entity/render/SilkMothEntityRenderer.java b/src/main/java/org/betterx/betterend/entity/render/SilkMothEntityRenderer.java new file mode 100644 index 00000000..bbb00f9d --- /dev/null +++ b/src/main/java/org/betterx/betterend/entity/render/SilkMothEntityRenderer.java @@ -0,0 +1,23 @@ +package org.betterx.betterend.entity.render; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.entity.SilkMothEntity; +import org.betterx.betterend.entity.model.SilkMothEntityModel; +import org.betterx.betterend.registry.EndEntitiesRenders; + +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.resources.ResourceLocation; + +public class SilkMothEntityRenderer extends MobRenderer { + private static final ResourceLocation TEXTURE = BetterEnd.makeID("textures/entity/silk_moth.png"); + + public SilkMothEntityRenderer(EntityRendererProvider.Context ctx) { + super(ctx, new SilkMothEntityModel(ctx.bakeLayer(EndEntitiesRenders.SILK_MOTH_MODEL)), 0.5f); + } + + @Override + public ResourceLocation getTextureLocation(SilkMothEntity entity) { + return TEXTURE; + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/events/ItemTooltipCallback.java b/src/main/java/org/betterx/betterend/events/ItemTooltipCallback.java new file mode 100644 index 00000000..ff3ea996 --- /dev/null +++ b/src/main/java/org/betterx/betterend/events/ItemTooltipCallback.java @@ -0,0 +1,36 @@ +package org.betterx.betterend.events; + +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; + +import java.util.List; + +@Environment(EnvType.CLIENT) +public interface ItemTooltipCallback { + /** + * Fired after the game has appended all base tooltip lines to the list. + */ + Event EVENT = EventFactory.createArrayBacked( + ItemTooltipCallback.class, + callbacks -> (player, stack, context, lines) -> { + for (ItemTooltipCallback callback : callbacks) { + callback.getTooltip(player, stack, context, lines); + } + } + ); + + /** + * Called when an item stack's tooltip is rendered. Text added to {@code lines} will be + * rendered with the tooltip. + * + * @param lines the list containing the lines of text displayed on the stack's tooltip + */ + void getTooltip(Player player, ItemStack stack, TooltipFlag context, List lines); +} diff --git a/src/main/java/org/betterx/betterend/events/PlayerAdvancementsCallback.java b/src/main/java/org/betterx/betterend/events/PlayerAdvancementsCallback.java new file mode 100644 index 00000000..6d4bdf8b --- /dev/null +++ b/src/main/java/org/betterx/betterend/events/PlayerAdvancementsCallback.java @@ -0,0 +1,21 @@ +package org.betterx.betterend.events; + +import net.minecraft.advancements.Advancement; +import net.minecraft.server.level.ServerPlayer; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; + +public interface PlayerAdvancementsCallback { + + Event PLAYER_ADVANCEMENT_COMPLETE = EventFactory.createArrayBacked( + PlayerAdvancementsCallback.class, + callbacks -> (player, advancement, criterionName) -> { + for (PlayerAdvancementsCallback event : callbacks) { + event.onAdvancementComplete(player, advancement, criterionName); + } + } + ); + + void onAdvancementComplete(ServerPlayer player, Advancement advancement, String criterionName); +} diff --git a/src/main/java/org/betterx/betterend/integration/EndBiomeIntegration.java b/src/main/java/org/betterx/betterend/integration/EndBiomeIntegration.java new file mode 100644 index 00000000..d57bf4cb --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/EndBiomeIntegration.java @@ -0,0 +1,5 @@ +package org.betterx.betterend.integration; + +public interface EndBiomeIntegration { + void addBiomes(); +} diff --git a/src/main/java/org/betterx/betterend/integration/FlamboyantRefabricatedIntegration.java b/src/main/java/org/betterx/betterend/integration/FlamboyantRefabricatedIntegration.java new file mode 100644 index 00000000..e485663c --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/FlamboyantRefabricatedIntegration.java @@ -0,0 +1,53 @@ +package org.betterx.betterend.integration; + +import org.betterx.bclib.integration.ModIntegration; +import org.betterx.betterend.blocks.HydraluxPetalColoredBlock; +import org.betterx.betterend.complexmaterials.ColoredMaterial; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.ui.ColorUtil; + +import net.minecraft.world.level.ItemLike; + +import com.google.common.collect.Maps; + +import java.awt.*; +import java.util.Map; + +public class FlamboyantRefabricatedIntegration extends ModIntegration { + public FlamboyantRefabricatedIntegration() { + super("flamboyant"); + } + + @Override + public void init() { + Map colors = Maps.newHashMap(); + Map dyes = Maps.newHashMap(); + + addColor("fead1d", "amber", colors, dyes); + addColor("bd9a5f", "beige", colors, dyes); + addColor("edeada", "cream", colors, dyes); + addColor("33430e", "dark_green", colors, dyes); + addColor("639920", "forest_green", colors, dyes); + addColor("f0618c", "hot_pink", colors, dyes); + addColor("491c7b", "indigo", colors, dyes); + addColor("65291b", "maroon", colors, dyes); + addColor("2c3969", "navy", colors, dyes); + addColor("827c17", "olive", colors, dyes); + addColor("7bc618", "pale_green", colors, dyes); + addColor("f4a4bd", "pale_pink", colors, dyes); + addColor("f8d45a", "pale_yellow", colors, dyes); + addColor("6bb1cf", "sky_blue", colors, dyes); + addColor("6e8c9c", "slate_gray", colors, dyes); + addColor("b02454", "violet", colors, dyes); + + new ColoredMaterial(HydraluxPetalColoredBlock::new, EndBlocks.HYDRALUX_PETAL_BLOCK, colors, dyes, true); + } + + private void addColor(String hex, String name, Map colors, Map dyes) { + int color = ColorUtil.color(hex); + colors.put(color, name); + dyes.put(color, getItem(name + "_dye")); + + System.out.println(name + " " + color + " " + new Color(color)); + } +} diff --git a/src/main/java/org/betterx/betterend/integration/Integrations.java b/src/main/java/org/betterx/betterend/integration/Integrations.java new file mode 100644 index 00000000..f576f462 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/Integrations.java @@ -0,0 +1,55 @@ +package org.betterx.betterend.integration; + +import org.betterx.bclib.api.v2.ModIntegrationAPI; +import org.betterx.bclib.integration.ModIntegration; +import org.betterx.bclib.recipes.GridRecipe; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.events.PlayerAdvancementsCallback; +import org.betterx.betterend.integration.byg.BYGIntegration; +import org.betterx.betterend.item.GuideBookItem; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; + +import net.fabricmc.loader.api.FabricLoader; + +public class Integrations { + public static final ModIntegration BYG = ModIntegrationAPI.register(new BYGIntegration()); + public static final ModIntegration NOURISH = ModIntegrationAPI.register(new NourishIntegration()); + public static final ModIntegration FLAMBOYANT_REFABRICATED = ModIntegrationAPI.register(new FlamboyantRefabricatedIntegration()); + + private static boolean hasHydrogen; + + public static void init() { + if (hasGuideBook()) { + GuideBookItem.register(); + + PlayerAdvancementsCallback.PLAYER_ADVANCEMENT_COMPLETE.register((player, advancement, criterionName) -> { + ResourceLocation advId = new ResourceLocation("minecraft:end/enter_end_gateway"); + if (advId.equals(advancement.getId())) { + player.addItem(new ItemStack(GuideBookItem.GUIDE_BOOK)); + } + }); + + GridRecipe.make(BetterEnd.MOD_ID, "guide_book", GuideBookItem.GUIDE_BOOK) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("D", "B", "C") + .addMaterial('D', EndItems.ENDER_DUST) + .addMaterial('B', Items.BOOK) + .addMaterial('C', EndItems.CRYSTAL_SHARDS) + .build(); + } + hasHydrogen = FabricLoader.getInstance().isModLoaded("hydrogen"); + } + + public static boolean hasGuideBook() { + return FabricLoader.getInstance().isModLoaded("patchouli"); + } + + public static boolean hasHydrogen() { + return hasHydrogen; + } +} diff --git a/src/main/java/org/betterx/betterend/integration/NourishIntegration.java b/src/main/java/org/betterx/betterend/integration/NourishIntegration.java new file mode 100644 index 00000000..fc8fd435 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/NourishIntegration.java @@ -0,0 +1,52 @@ +package org.betterx.betterend.integration; + +import org.betterx.bclib.integration.ModIntegration; +import org.betterx.betterend.registry.EndItems; +import org.betterx.worlds.together.tag.v3.TagManager; + +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; + +public class NourishIntegration extends ModIntegration { + public NourishIntegration() { + super("nourish"); + } + + @Override + public void init() { + TagKey fats = getItemTag("fats"); + TagKey fruit = getItemTag("fruit"); + TagKey protein = getItemTag("protein"); + TagKey sweets = getItemTag("sweets"); + + TagManager.ITEMS.add(fats, EndItems.END_FISH_RAW, EndItems.END_FISH_COOKED); + TagManager.ITEMS.add( + fruit, + EndItems.SHADOW_BERRY_RAW, + EndItems.SHADOW_BERRY_COOKED, + EndItems.BLOSSOM_BERRY, + EndItems.SHADOW_BERRY_JELLY, + EndItems.SWEET_BERRY_JELLY, + EndItems.BLOSSOM_BERRY_JELLY, + EndItems.AMBER_ROOT_RAW, + EndItems.CHORUS_MUSHROOM_RAW, + EndItems.CHORUS_MUSHROOM_COOKED, + EndItems.BOLUX_MUSHROOM_COOKED + ); + TagManager.ITEMS.add( + protein, + EndItems.END_FISH_RAW, + EndItems.END_FISH_COOKED, + EndItems.CHORUS_MUSHROOM_COOKED, + EndItems.BOLUX_MUSHROOM_COOKED, + EndItems.CAVE_PUMPKIN_PIE + ); + TagManager.ITEMS.add( + sweets, + EndItems.SHADOW_BERRY_JELLY, + EndItems.SWEET_BERRY_JELLY, + EndItems.BLOSSOM_BERRY_JELLY, + EndItems.CAVE_PUMPKIN_PIE + ); + } +} diff --git a/src/main/java/org/betterx/betterend/integration/byg/BYGBlocks.java b/src/main/java/org/betterx/betterend/integration/byg/BYGBlocks.java new file mode 100644 index 00000000..be446473 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/byg/BYGBlocks.java @@ -0,0 +1,17 @@ +package org.betterx.betterend.integration.byg; + +import org.betterx.bclib.blocks.BaseVineBlock; +import org.betterx.betterend.blocks.basis.EndWallPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.world.level.block.Block; + +public class BYGBlocks { + public static final Block IVIS_MOSS = EndBlocks.registerBlock("ivis_moss", new EndWallPlantBlock()); + public static final Block NIGHTSHADE_MOSS = EndBlocks.registerBlock("nightshade_moss", new EndWallPlantBlock()); + + public static final Block IVIS_VINE = EndBlocks.registerBlock("ivis_vine", new BaseVineBlock()); + + public static void register() { + } +} diff --git a/src/main/java/org/betterx/betterend/integration/byg/BYGIntegration.java b/src/main/java/org/betterx/betterend/integration/byg/BYGIntegration.java new file mode 100644 index 00000000..859da05b --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/byg/BYGIntegration.java @@ -0,0 +1,33 @@ +package org.betterx.betterend.integration.byg; + +import org.betterx.bclib.integration.ModIntegration; +import org.betterx.betterend.integration.EndBiomeIntegration; +import org.betterx.betterend.integration.Integrations; +import org.betterx.betterend.integration.byg.biomes.BYGBiomes; +import org.betterx.betterend.integration.byg.features.BYGFeatures; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; +import org.betterx.worlds.together.tag.v3.TagManager; + +import net.minecraft.world.level.block.Block; + +public class BYGIntegration extends ModIntegration implements EndBiomeIntegration { + public BYGIntegration() { + super("byg"); + } + + @Override + public void init() { + Block block = Integrations.BYG.getBlock("ivis_phylium"); + if (block != null) { + TagManager.BLOCKS.add(block, CommonBlockTags.END_STONES, CommonBlockTags.GEN_END_STONES); + } + BYGBlocks.register(); + BYGFeatures.register(); + BYGBiomes.register(); + } + + @Override + public void addBiomes() { + BYGBiomes.addBiomes(); + } +} diff --git a/src/main/java/org/betterx/betterend/integration/byg/biomes/BYGBiomes.java b/src/main/java/org/betterx/betterend/integration/byg/biomes/BYGBiomes.java new file mode 100644 index 00000000..8c661bdd --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/byg/biomes/BYGBiomes.java @@ -0,0 +1,26 @@ +package org.betterx.betterend.integration.byg.biomes; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.integration.Integrations; +import org.betterx.betterend.registry.EndBiomes; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.world.level.levelgen.SurfaceRules; + +public class BYGBiomes { + public static final SurfaceRules.ConditionSource BYG_WATER_CHECK = SurfaceRules.waterBlockCheck(-1, 0); + // New Biomes + public static final EndBiome OLD_BULBIS_GARDENS = EndBiomes.registerSubBiomeIntegration(new OldBulbisGardens()); + public static final EndBiome NIGHTSHADE_REDWOODS = EndBiomes.registerSubBiomeIntegration(new NightshadeRedwoods()); + //public static final EndBiome ETHERIAL_GROVE = EndBiomes.registerSubBiomeIntegration(new EterialGrove()); + + public static void register() { + BetterEnd.LOGGER.info("Registered " + OLD_BULBIS_GARDENS); + } + + public static void addBiomes() { + EndBiomes.addSubBiomeIntegration(OLD_BULBIS_GARDENS, Integrations.BYG.getID("bulbis_gardens")); + EndBiomes.addSubBiomeIntegration(NIGHTSHADE_REDWOODS, Integrations.BYG.getID("nightshade_forest")); + //EndBiomes.addSubBiomeIntegration(ETHERIAL_GROVE, Integrations.BYG.getID("ethereal_islands")); + } +} diff --git a/src/main/java/org/betterx/betterend/integration/byg/biomes/NightshadeRedwoods.java b/src/main/java/org/betterx/betterend/integration/byg/biomes/NightshadeRedwoods.java new file mode 100644 index 00000000..b645a43d --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/byg/biomes/NightshadeRedwoods.java @@ -0,0 +1,112 @@ +package org.betterx.betterend.integration.byg.biomes; + +import org.betterx.bclib.BCLib; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.SurfaceRuleBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.integration.Integrations; +import org.betterx.betterend.integration.byg.features.BYGFeatures; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.core.Holder; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeSpecialEffects; +import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.GenerationStep.Decoration; +import net.minecraft.world.level.levelgen.SurfaceRules; + +import java.util.List; + +public class NightshadeRedwoods extends EndBiome.Config { + public NightshadeRedwoods() { + super("nightshade_redwoods"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + Holder biome = Integrations.BYG.getBiome("nightshade_forest"); + BiomeSpecialEffects effects = biome.value().getSpecialEffects(); + + builder.fogColor(140, 108, 47) + .fogDensity(1.5F) + .waterAndFogColor(55, 70, 186) + .foliageColor(122, 17, 155) + .particles( + ParticleTypes.REVERSE_PORTAL, + 0.002F + ) + .grassColor(48, 13, 89) + .plantsColor(200, 125, 9) + .feature(EndFeatures.END_LAKE_RARE) + .feature(BYGFeatures.NIGHTSHADE_REDWOOD_TREE) + .feature(BYGFeatures.NIGHTSHADE_MOSS_WOOD) + .feature(BYGFeatures.NIGHTSHADE_MOSS); + + if (BCLib.isClient()) { + SoundEvent loop = effects.getAmbientLoopSoundEvent() + .get(); + SoundEvent music = effects.getBackgroundMusic() + .get() + .getEvent(); + SoundEvent additions = effects.getAmbientAdditionsSettings() + .get() + .getSoundEvent(); + SoundEvent mood = effects.getAmbientMoodSettings() + .get() + .getSoundEvent(); + builder.loop(loop) + .music(music) + .additions(additions) + .mood(mood); + } + biome.value().getGenerationSettings() + .features() + .forEach((list) -> { + list.forEach((feature) -> { + builder.feature(Decoration.VEGETAL_DECORATION, feature); + }); + }); + + for (MobCategory group : MobCategory.values()) { + List list = biome.value() + .getMobSettings() + .getMobs(group) + .unwrap(); + list.forEach((entry) -> { + builder.spawn((EntityType) entry.type, 1, entry.minCount, entry.maxCount); + }); + } + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return Integrations.BYG.getBlock("nightshade_phylium").defaultBlockState(); + } + + @Override + public SurfaceRuleBuilder surface() { + return SurfaceRuleBuilder + .start() + .rule(4, SurfaceRules.sequence(SurfaceRules.ifTrue( + BYGBiomes.BYG_WATER_CHECK, + SurfaceRules.ifTrue( + SurfaceRules.ON_FLOOR, + SurfaceRules.state(getTopMaterial()) + ) + ) + ) + ); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/integration/byg/biomes/OldBulbisGardens.java b/src/main/java/org/betterx/betterend/integration/byg/biomes/OldBulbisGardens.java new file mode 100644 index 00000000..aaa8ae76 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/byg/biomes/OldBulbisGardens.java @@ -0,0 +1,153 @@ +package org.betterx.betterend.integration.byg.biomes; + +import org.betterx.bclib.BCLib; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.SurfaceRuleBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.rules.RoughNoiseCondition; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.integration.Integrations; +import org.betterx.betterend.integration.byg.features.BYGFeatures; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeSpecialEffects; +import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.GenerationStep.Decoration; +import net.minecraft.world.level.levelgen.Noises; +import net.minecraft.world.level.levelgen.SurfaceRules; +import net.minecraft.world.level.levelgen.placement.PlacedFeature; + +import java.util.List; + + +public class OldBulbisGardens extends EndBiome.Config { + public OldBulbisGardens() { + super("old_bulbis_gardens"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + Holder biome = Integrations.BYG.getBiome("bulbis_gardens"); + BiomeSpecialEffects effects = biome.value().getSpecialEffects(); + + builder.fogColor(215, 132, 207) + .fogDensity(1.8F) + .waterAndFogColor(40, 0, 56) + .foliageColor(122, 17, 155) + .particles( + ParticleTypes.REVERSE_PORTAL, + 0.002F + ) + .feature(EndFeatures.END_LAKE_RARE) + .feature(BYGFeatures.OLD_BULBIS_TREE); + + if (BCLib.isClient()) { + SoundEvent loop = effects.getAmbientLoopSoundEvent() + .get(); + SoundEvent music = effects.getBackgroundMusic() + .get() + .getEvent(); + SoundEvent additions = effects.getAmbientAdditionsSettings() + .get() + .getSoundEvent(); + SoundEvent mood = effects.getAmbientMoodSettings() + .get() + .getSoundEvent(); + builder.loop(loop) + .music(music) + .additions(additions) + .mood(mood); + } + + for (MobCategory group : MobCategory.values()) { + List list = biome.value() + .getMobSettings() + .getMobs(group) + .unwrap(); + list.forEach((entry) -> { + builder.spawn((EntityType) entry.type, 1, entry.minCount, entry.maxCount); + }); + } + + List> features = biome.value().getGenerationSettings() + .features(); + HolderSet vegetal = features.get(Decoration.VEGETAL_DECORATION.ordinal()); +// if (vegetal.size() > 2) { +// Supplier getter; + for (var feature : vegetal) { + builder.feature(Decoration.VEGETAL_DECORATION, feature); + } +// // Trees (first two features) +// // I couldn't process them with conditions, so that's why they are hardcoded (paulevs) +// for (int i = 0; i < 2; i++) { +// getter = vegetal.get(i); +// Holder feature = getter.get(); +// ResourceLocation id = BetterEnd.makeID("obg_feature_" + i); +// feature = Registry.register( +// BuiltinRegistries.PLACED_FEATURE, +// id, +// feature +// ); +// builder.feature(Decoration.VEGETAL_DECORATION, feature); +// } +// // Grasses and other features +// for (int i = 2; i < vegetal.size(); i++) { +// getter = vegetal.get(i); +// Holder feature = getter.get(); +// builder.feature(Decoration.VEGETAL_DECORATION, feature); +// } +// } + + builder.feature(EndFeatures.PURPLE_POLYPORE) + .feature(BYGFeatures.IVIS_MOSS_WOOD) + .feature(BYGFeatures.IVIS_MOSS) + .feature(BYGFeatures.IVIS_VINE) + .feature(BYGFeatures.IVIS_SPROUT); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return Integrations.BYG.getBlock("ivis_phylium").defaultBlockState(); + } + + @Override + public BlockState getAltTopMaterial() { + return Integrations.BYG.getBlock("bulbis_phycelium").defaultBlockState(); + } + + @Override + public SurfaceRuleBuilder surface() { + return SurfaceRuleBuilder + .start() + .rule(4, SurfaceRules.sequence(SurfaceRules.ifTrue( + BYGBiomes.BYG_WATER_CHECK, + SurfaceRules.ifTrue( + SurfaceRules.ON_FLOOR, + SurfaceRules.sequence( + SurfaceRules.ifTrue( + new RoughNoiseCondition(Noises.NETHERRACK, 0.19), + SurfaceRules.state(getTopMaterial()) + ), + SurfaceRules.state(getAltTopMaterial()) + ) + ) + ) + ) + ); + } + }; + } + +} diff --git a/src/main/java/org/betterx/betterend/integration/byg/features/BYGFeatures.java b/src/main/java/org/betterx/betterend/integration/byg/features/BYGFeatures.java new file mode 100644 index 00000000..e887a47b --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/byg/features/BYGFeatures.java @@ -0,0 +1,111 @@ +package org.betterx.betterend.integration.byg.features; + +import org.betterx.bclib.api.v3.levelgen.features.BCLFeature; +import org.betterx.bclib.api.v3.levelgen.features.BCLFeatureBuilder; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.integration.Integrations; +import org.betterx.betterend.integration.byg.BYGBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.features.*; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class BYGFeatures { + public static final BCLFeature OLD_BULBIS_TREE = redisterVegetation( + "old_bulbis_tree", + EndFeatures.inlineBuild("old_bulbis_tree_feature", new OldBulbisTreeFeature()), + 1 + ); + public static final BCLFeature IVIS_SPROUT = redisterVegetation( + "ivis_sprout", + EndFeatures.SINGLE_PLANT_FEATURE, + new SinglePlantFeatureConfig(Integrations.BYG.getBlock("ivis_sprout"), 6, 2), + 6 + ); + public static final BCLFeature IVIS_VINE = redisterVegetation( + "ivis_vine", + EndFeatures.VINE_FEATURE, + new VineFeatureConfig(BYGBlocks.IVIS_VINE, 24), + 5 + ); + public static final BCLFeature IVIS_MOSS = redisterVegetation( + "ivis_moss", + EndFeatures.WALL_PLANT_FEATURE, + new WallPlantFeatureConfig(BYGBlocks.IVIS_MOSS, 6), + 1 + ); + public static final BCLFeature IVIS_MOSS_WOOD = redisterVegetation( + "ivis_moss_wood", + EndFeatures.WALL_PLANT_ON_LOG_FEATURE, + new WallPlantFeatureConfig(BYGBlocks.IVIS_MOSS, 6), + 15 + ); + public static final BCLFeature NIGHTSHADE_MOSS = redisterVegetation( + "nightshade_moss", + EndFeatures.WALL_PLANT_FEATURE, + new WallPlantFeatureConfig(BYGBlocks.NIGHTSHADE_MOSS, 5), + 2 + ); + public static final BCLFeature NIGHTSHADE_MOSS_WOOD = redisterVegetation( + "nightshade_moss_wood", + EndFeatures.WALL_PLANT_ON_LOG_FEATURE, + new WallPlantFeatureConfig(BYGBlocks.NIGHTSHADE_MOSS, 5), + 8 + ); + + public static final NightshadeRedwoodTreeFeature NIGHTSHADE_REDWOOD_TREE_FEATURE = + EndFeatures.inlineBuild( + "nightshade_redwood_tree", + new NightshadeRedwoodTreeFeature() + ); + + public static final BCLFeature NIGHTSHADE_REDWOOD_TREE = redisterVegetation( + "nightshade_redwood_tree", + NIGHTSHADE_REDWOOD_TREE_FEATURE, + 1 + ); + public static final BigEtherTreeFeature BIG_ETHER_TREE_FEATURE = + EndFeatures.inlineBuild( + "big_ether_tree", + new BigEtherTreeFeature() + ); + + public static final BCLFeature BIG_ETHER_TREE = redisterVegetation( + "big_ether_tree", + BIG_ETHER_TREE_FEATURE, + 1 + ); + + public static void register() { + } + + private static > BCLFeature redisterVegetation( + String name, + F feature, + int density + ) { + return redisterVegetation(name, feature, NoneFeatureConfiguration.NONE, density); + } + + private static , FC extends FeatureConfiguration> BCLFeature redisterVegetation( + String name, + F feature, + FC config, + int density + ) { + ResourceLocation id = BetterEnd.makeID(name); + return BCLFeatureBuilder + .start(id, feature) + .configuration(config) + .buildAndRegister() + .place() + .countMax(density) + .squarePlacement() + .heightmap() + .onlyInBiome() + .buildAndRegister(); + } +} diff --git a/src/main/java/org/betterx/betterend/integration/byg/features/BigEtherTreeFeature.java b/src/main/java/org/betterx/betterend/integration/byg/features/BigEtherTreeFeature.java new file mode 100644 index 00000000..e39b3e98 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/byg/features/BigEtherTreeFeature.java @@ -0,0 +1,81 @@ +package org.betterx.betterend.integration.byg.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.integration.Integrations; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import com.google.common.base.Function; + +import java.util.List; + +public class BigEtherTreeFeature extends DefaultFeature { + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES)) return false; + + BlockState log = Integrations.BYG.getDefaultState("ether_log"); + BlockState wood = Integrations.BYG.getDefaultState("ether_wood"); + Function splinePlacer = (bpos) -> { + return log; + }; + Function replace = (state) -> { + return state.is(CommonBlockTags.END_STONES) || state.getMaterial() + .equals(Material.PLANT) || state.getMaterial() + .isReplaceable(); + }; + + int height = MHelper.randRange(40, 60, random); + List trunk = SplineHelper.makeSpline(0, 0, 0, 0, height, 0, height / 4); + SplineHelper.offsetParts(trunk, random, 2F, 0, 2F); + SDF sdf = SplineHelper.buildSDF(trunk, 2.3F, 0.8F, splinePlacer); + + int count = height / 15; + for (int i = 1; i < count; i++) { + float splinePos = (float) i / (float) count; + float startAngle = random.nextFloat() * MHelper.PI2; + float length = (1 - splinePos) * height * 0.4F; + int points = (int) (length / 3); + List branch = SplineHelper.makeSpline(0, 0, 0, length, 0, 0, points < 2 ? 2 : points); + SplineHelper.powerOffset(branch, length, 2F); + int rotCount = MHelper.randRange(5, 7, random); + Vector3f start = SplineHelper.getPos(trunk, splinePos * (trunk.size() - 1)); + for (int j = 0; j < rotCount; j++) { + float angle = startAngle + (float) j / rotCount * MHelper.PI2; + List br = SplineHelper.copySpline(branch); + SplineHelper.offsetParts(br, random, 0, 1, 1); + SplineHelper.rotateSpline(br, angle); + + SplineHelper.offset(br, start); + SplineHelper.fillSpline(br, world, wood, pos, replace); + } + } + + sdf.setReplaceFunction((state) -> { + return state.is(CommonBlockTags.END_STONES) || state.getMaterial() + .equals(Material.PLANT) || state.getMaterial() + .isReplaceable(); + }).addPostProcess((info) -> { + if (info.getState().equals(log) && (!info.getStateUp().equals(log) || !info.getStateDown().equals(log))) { + return wood; + } + return info.getState(); + }).fillRecursive(world, pos); + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/integration/byg/features/NightshadeRedwoodTreeFeature.java b/src/main/java/org/betterx/betterend/integration/byg/features/NightshadeRedwoodTreeFeature.java new file mode 100644 index 00000000..1a81537c --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/byg/features/NightshadeRedwoodTreeFeature.java @@ -0,0 +1,201 @@ +package org.betterx.betterend.integration.byg.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.PosInfo; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFFlatWave; +import org.betterx.bclib.sdf.operator.SDFSmoothUnion; +import org.betterx.bclib.sdf.primitive.SDFCappedCone; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.integration.Integrations; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import com.google.common.base.Function; +import com.google.common.collect.Lists; + +import java.util.List; + +public class NightshadeRedwoodTreeFeature extends DefaultFeature { + private static final List BRANCH; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES)) return false; + + BlockState log = Integrations.BYG.getDefaultState("nightshade_log"); + BlockState wood = Integrations.BYG.getDefaultState("nightshade_wood"); + BlockState leaves = Integrations.BYG.getDefaultState("nightshade_leaves"); + BlockState leaves_flower = Integrations.BYG.getDefaultState("flowering_nightshade_leaves"); + + Function splinePlacer = (bpos) -> { + return log; + }; + Function replace = (state) -> { + return state.is(CommonBlockTags.END_STONES) || state.getMaterial() + .equals(Material.PLANT) || state.getMaterial() + .isReplaceable(); + }; + Function post = (info) -> { + if (info.getState().equals(log) && (!info.getStateUp().equals(log) || !info.getStateDown().equals(log))) { + return wood; + } + return info.getState(); + }; + Function ignore = (state) -> { + return state.equals(log) || state.equals(wood); + }; + + int height = MHelper.randRange(40, 60, random); + List trunk = SplineHelper.makeSpline(0, 0, 0, 0, height, 0, height / 4); + SplineHelper.offsetParts(trunk, random, 0.8F, 0, 0.8F); + + if (!SplineHelper.canGenerate(trunk, pos, world, replace)) { + return false; + } + + int count = height >> 2; + float start = trunk.size() / 3F; + float delta = trunk.size() * 0.6F; + float max = height - 7; + float startAngle = random.nextFloat() * MHelper.PI2; + for (int i = 0; i < count; i++) { + float scale = (float) (count - i) / count * 15; + Vector3f offset = SplineHelper.getPos(trunk, (float) i / count * delta + start); + if (offset.y() > max) { + break; + } + List branch = SplineHelper.copySpline(BRANCH); + SplineHelper.rotateSpline(branch, i * 1.3F + startAngle); + SplineHelper.scale(branch, scale); + SplineHelper.offsetParts(branch, random, 0.3F, 0.3F, 0.3F); + SplineHelper.offset(branch, offset); + SplineHelper.fillSpline(branch, world, wood, pos, replace); + } + + SDF sdf = SplineHelper.buildSDF(trunk, 2.3F, 0.8F, splinePlacer); + SDF roots = new SDFSphere().setRadius(2F).setBlock(log); + roots = new SDFFlatWave().setIntensity(2F) + .setRaysCount(MHelper.randRange(5, 7, random)) + .setAngle(random.nextFloat() * MHelper.PI2) + .setSource(roots); + sdf = new SDFSmoothUnion().setRadius(2F).setSourceA(sdf).setSourceB(roots); + sdf.setReplaceFunction(replace).addPostProcess(post).fillRecursive(world, pos); + Vector3f last = SplineHelper.getPos(trunk, trunk.size() - 1.35F); + for (int y = 0; y < 8; y++) { + BlockPos p = pos.offset(last.x() + 0.5, last.y() + y, last.z() + 0.5); + BlocksHelper.setWithoutUpdate(world, p, y == 4 ? wood : log); + } + + for (int y = 0; y < 16; y++) { + BlockPos p = pos.offset(last.x() + 0.5, last.y() + y, last.z() + 0.5); + if (world.isEmptyBlock(p)) { + BlocksHelper.setWithoutUpdate(world, p, leaves); + } + float radius = (1 - y / 16F) * 3F; + int rad = (int) (radius + 1); + radius *= radius; + for (int x = -rad; x <= rad; x++) { + int x2 = x * x; + for (int z = -rad; z <= rad; z++) { + int z2 = z * z; + if (x2 + z2 < radius - random.nextFloat() * rad) { + BlockPos lp = p.offset(x, 0, z); + if (world.isEmptyBlock(lp)) { + BlocksHelper.setWithoutUpdate(world, lp, leaves); + } + } + } + } + } + + MutableBlockPos mut = new MutableBlockPos(); + Function leavesPost1 = (info) -> { + if (info.getState().equals(log) || info.getState().equals(wood)) { + for (int x = -6; x < 7; x++) { + int ax = Math.abs(x); + mut.setX(x + info.getPos().getX()); + for (int z = -6; z < 7; z++) { + int az = Math.abs(z); + mut.setZ(z + info.getPos().getZ()); + for (int y = -6; y < 7; y++) { + int ay = Math.abs(y); + int d = ax + ay + az; + if (d < 7) { + mut.setY(y + info.getPos().getY()); + BlockState state = info.getState(mut); + if (state.getBlock() instanceof LeavesBlock) { + int distance = state.getValue(LeavesBlock.DISTANCE); + if (d < distance) { + info.setState(mut, state.setValue(LeavesBlock.DISTANCE, d)); + } + } + } + } + } + } + } + return info.getState(); + }; + Function leavesPost2 = (info) -> { + if (info.getState().getBlock() instanceof LeavesBlock) { + int distance = info.getState().getValue(LeavesBlock.DISTANCE); + if (distance > MHelper.randRange(2, 4, random)) { + return Blocks.AIR.defaultBlockState(); + } + for (Direction d : BlocksHelper.DIRECTIONS) { + int airCount = 0; + if (info.getState(d).isAir()) { + airCount++; + } + if (airCount > 5) { + return Blocks.AIR.defaultBlockState(); + } + } + if (random.nextInt(8) == 0) { + return leaves_flower.setValue(LeavesBlock.DISTANCE, distance); + } + } + return info.getState(); + }; + + SDF canopy = new SDFCappedCone().setRadius1(12F).setRadius2(1f).setHeight(height * 0.3F).setBlock(leaves); + canopy = new SDFDisplacement().setFunction((vec) -> { + return MHelper.randRange(-3F, 3F, random); + }).setSource(canopy); + canopy.addPostProcess(leavesPost1) + .addPostProcess(leavesPost2) + .fillRecursiveIgnore(world, pos.offset(0, height * 0.75, 0), ignore); + + return true; + } + + static { + BRANCH = Lists.newArrayList( + new Vector3f(0, 0, 0), + new Vector3f(0.25F, 0.1F, 0), + new Vector3f(0.40F, 0.2F, 0), + new Vector3f(0.50F, 0.4F, 0), + new Vector3f(0.55F, 0.6F, 0) + ); + } +} diff --git a/src/main/java/org/betterx/betterend/integration/byg/features/OldBulbisTreeFeature.java b/src/main/java/org/betterx/betterend/integration/byg/features/OldBulbisTreeFeature.java new file mode 100644 index 00000000..c613e7e6 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/byg/features/OldBulbisTreeFeature.java @@ -0,0 +1,219 @@ +package org.betterx.betterend.integration.byg.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFSubtraction; +import org.betterx.bclib.sdf.operator.SDFTranslate; +import org.betterx.bclib.sdf.operator.SDFUnion; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.integration.Integrations; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.phys.AABB; + +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.function.Function; + +public class OldBulbisTreeFeature extends DefaultFeature { + private static final List SPLINE; + private static final List ROOT; + private static final List LEAF; + private static final List SIDE; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES)) return false; + if (!world.getBlockState(pos.below(4)).is(CommonBlockTags.GEN_END_STONES)) return false; + + BlockState stem = Integrations.BYG.getDefaultState("bulbis_stem"); + BlockState wood = Integrations.BYG.getDefaultState("bulbis_wood"); + BlockState cap = Integrations.BYG.getDefaultState(random.nextBoolean() + ? "bulbis_shell" + : "purple_bulbis_shell"); + BlockState glow = Integrations.BYG.getDefaultState("purple_shroomlight"); + + Function replacement = (state) -> { + if (state.equals(stem) || state.equals(wood) || state.is(CommonBlockTags.END_STONES) || state.getMaterial() + .equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + + float size = MHelper.randRange(10, 20, random); + float addSize = MHelper.randRange(1, 1.7F, random); + float addRad = addSize * 0.5F + 0.5F; + int count = (int) (size * 0.15F); + size *= addSize; + float var = MHelper.PI2 / (float) (count * 3); + float start = MHelper.randRange(0, MHelper.PI2, random); + SDF sdf = null; + int x1 = ((pos.getX() >> 4) << 4) - 16; + int z1 = ((pos.getZ() >> 4) << 4) - 16; + AABB limits = new AABB(x1, pos.getY() - 5, z1, x1 + 47, pos.getY() + size * 2, z1 + 47); + for (int i = 0; i < count; i++) { + float angle = (float) i / (float) count * MHelper.PI2 + MHelper.randRange(0, var, random) + start; + List spline = SplineHelper.copySpline(SPLINE); + float sizeXZ = (size + MHelper.randRange(0, size * 0.5F, random)) * 0.7F; + SplineHelper.scale(spline, sizeXZ, sizeXZ * 1.5F + MHelper.randRange(0, size * 0.5F, random), sizeXZ); + SplineHelper.offset(spline, new Vector3f(size * random.nextFloat() * 0.3F, 0, 0)); + SplineHelper.rotateSpline(spline, angle); + SplineHelper.offsetParts(spline, random, 1F, 0, 1F);// 1.3F 0.8F + SDF branch = SplineHelper.buildSDF(spline, 2.3F * addRad, 1.3F * addRad, (bpos) -> { + return stem; + }); + + Vector3f vec = spline.get(spline.size() - 1); + float radius = (size + MHelper.randRange(0, size * 0.5F, random)) * 0.35F; + bigSphere(world, pos.offset(vec.x(), vec.y(), vec.z()), radius, cap, glow, wood, replacement, random); + vec = SplineHelper.getPos(spline, 0.3F); + makeRoots(world, pos.offset(vec.x(), vec.y(), vec.z()), size * 0.4F + 5, random, wood, replacement); + + sdf = (sdf == null) ? branch : new SDFUnion().setSourceA(sdf).setSourceB(branch); + } + + sdf.setReplaceFunction(replacement).addPostProcess((info) -> { + if (info.getState().equals(stem) && (!info.getStateUp().equals(stem) || !info.getStateDown() + .equals(stem))) { + return wood; + } + return info.getState(); + }).fillArea(world, pos, limits); + + return true; + } + + private void bigSphere( + WorldGenLevel world, + BlockPos pos, + float radius, + BlockState cap, + BlockState glow, + BlockState wood, + Function replacement, + RandomSource random + ) { + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + SDF sphere = new SDFSphere().setRadius(radius).setBlock(cap); + + SDF sphereInner = new SDFSphere().setRadius(radius * 0.53F).setBlock(Blocks.AIR); + sphereInner = new SDFDisplacement().setFunction((vec) -> { + return (float) noise.eval(vec.x() * 0.1, vec.y() * 0.1, vec.z() * 0.1); + }).setSource(sphereInner); + + SDF sphereGlow = new SDFSphere().setRadius(radius * 0.6F).setBlock(glow); + sphereGlow = new SDFDisplacement().setFunction((vec) -> { + return (float) noise.eval(vec.x() * 0.1, vec.y() * 0.1, vec.z() * 0.1) * 2F; + }).setSource(sphereGlow); + sphereGlow = new SDFSubtraction().setSourceA(sphereGlow).setSourceB(sphereInner); + + sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sphereGlow); + sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sphereInner); + + float offsetY = radius * 1.7F; + sphere = new SDFUnion().setSourceA(sphere).setSourceB(sphereGlow); + sphere = new SDFTranslate().setTranslate(0, offsetY, 0).setSource(sphere); + + int leafCount = (int) (radius * 0.5F) + 2; + for (int i = 0; i < 4; i++) { + float angle = (float) i / 4 * MHelper.PI2; + List spline = SplineHelper.copySpline(LEAF); + SplineHelper.rotateSpline(spline, angle); + SplineHelper.scale(spline, radius * 1.4F); + SplineHelper.fillSplineForce(spline, world, wood, pos, replacement); + + for (int j = 0; j < leafCount; j++) { + float delta = ((float) j / (float) (leafCount - 1)); + float scale = (float) Math.sin(delta * Math.PI) * 0.8F + 0.2F; + float index = Mth.lerp(delta, 1F, 3.9F); + Vector3f point = SplineHelper.getPos(spline, index); + + List side = SplineHelper.copySpline(SIDE); + SplineHelper.rotateSpline(side, angle); + SplineHelper.scale(side, scale * radius); + BlockPos p = pos.offset(point.x() + 0.5F, point.y() + 0.5F, point.z() + 0.5F); + SplineHelper.fillSplineForce(side, world, wood, p, replacement); + } + } + + sphere.fillArea(world, pos, new AABB(pos.above((int) offsetY)).inflate(radius * 1.3F)); + } + + private void makeRoots( + WorldGenLevel world, + BlockPos pos, + float radius, + RandomSource random, + BlockState wood, + Function replacement + ) { + int count = (int) (radius * 1.5F); + for (int i = 0; i < count; i++) { + float angle = (float) i / (float) count * MHelper.PI2; + float scale = radius * MHelper.randRange(0.85F, 1.15F, random); + + List branch = SplineHelper.copySpline(ROOT); + SplineHelper.rotateSpline(branch, angle); + SplineHelper.scale(branch, scale); + Vector3f last = branch.get(branch.size() - 1); + if (world.getBlockState(pos.offset(last.x(), last.y(), last.z())).is(CommonBlockTags.GEN_END_STONES)) { + SplineHelper.fillSpline(branch, world, wood, pos, replacement); + } + } + } + + static { + SPLINE = Lists.newArrayList( + new Vector3f(0.00F, 0.00F, 0.00F), + new Vector3f(0.10F, 0.35F, 0.00F), + new Vector3f(0.20F, 0.50F, 0.00F), + new Vector3f(0.30F, 0.55F, 0.00F), + new Vector3f(0.42F, 0.70F, 0.00F), + new Vector3f(0.50F, 1.00F, 0.00F) + ); + + ROOT = Lists.newArrayList( + new Vector3f(0F, 1F, 0), + new Vector3f(0.1F, 0.70F, 0), + new Vector3f(0.3F, 0.30F, 0), + new Vector3f(0.7F, 0.05F, 0), + new Vector3f(0.8F, -0.20F, 0) + ); + SplineHelper.offset(ROOT, new Vector3f(0, -0.45F, 0)); + + LEAF = Lists.newArrayList( + new Vector3f(0.00F, 0.0F, 0), + new Vector3f(0.10F, 0.4F, 0), + new Vector3f(0.40F, 0.8F, 0), + new Vector3f(0.75F, 0.9F, 0), + new Vector3f(1.00F, 0.8F, 0) + ); + + SIDE = Lists.newArrayList( + new Vector3f(0, -0.3F, -0.5F), + new Vector3f(0, -0.1F, -0.3F), + new Vector3f(0, 0.0F, 0.0F), + new Vector3f(0, -0.1F, 0.3F), + new Vector3f(0, -0.3F, 0.5F) + ); + } +} diff --git a/src/main/java/org/betterx/betterend/integration/emi/EMIBlastingRecipe.java b/src/main/java/org/betterx/betterend/integration/emi/EMIBlastingRecipe.java new file mode 100644 index 00000000..2924544d --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/emi/EMIBlastingRecipe.java @@ -0,0 +1,40 @@ +package org.betterx.betterend.integration.emi; + +import org.betterx.bclib.integration.emi.EMIAbstractAlloyingRecipe; +import org.betterx.bclib.integration.emi.EMIPlugin; +import org.betterx.betterend.BetterEnd; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.Container; +import net.minecraft.world.item.crafting.BlastingRecipe; +import net.minecraft.world.item.crafting.RecipeManager; +import net.minecraft.world.item.crafting.RecipeType; + +import dev.emi.emi.api.EmiRegistry; + +public class EMIBlastingRecipe extends EMIAbstractAlloyingRecipe { + public EMIBlastingRecipe(BlastingRecipe recipe) { + super(recipe, new ResourceLocation( + "emi", + recipe.getId().getNamespace() + "/" + recipe.getId().getPath() + "/allloying" + ), 1, false); + } + + @Override + protected int getSmeltTime() { + return recipe.getCookingTime(); + } + + @Override + protected float getExperience() { + return recipe.getExperience(); + } + + + static void addAllRecipes(EmiRegistry emiRegistry, RecipeManager manager) { + EMIPlugin.addAllRecipes( + emiRegistry, manager, BetterEnd.LOGGER, + RecipeType.BLASTING, EMIBlastingRecipe::new + ); + } +} diff --git a/src/main/java/org/betterx/betterend/integration/emi/EMIInfusionRecipe.java b/src/main/java/org/betterx/betterend/integration/emi/EMIInfusionRecipe.java new file mode 100644 index 00000000..2f1a4643 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/emi/EMIInfusionRecipe.java @@ -0,0 +1,131 @@ +package org.betterx.betterend.integration.emi; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.recipe.builders.InfusionRecipe; +import org.betterx.ui.ColorUtil; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.FormattedCharSequence; +import net.minecraft.world.item.crafting.RecipeManager; + +import dev.emi.emi.api.EmiRegistry; +import dev.emi.emi.api.recipe.EmiRecipe; +import dev.emi.emi.api.recipe.EmiRecipeCategory; +import dev.emi.emi.api.render.EmiTexture; +import dev.emi.emi.api.stack.EmiIngredient; +import dev.emi.emi.api.stack.EmiStack; +import dev.emi.emi.api.widget.WidgetHolder; + +import java.util.List; +import org.jetbrains.annotations.Nullable; + +public class EMIInfusionRecipe implements EmiRecipe { + public final static EmiTexture BACKGROUND = new EmiTexture( + BetterEnd.makeID("textures/gui/infusion.png"), + 0, 0, + 84, 84, 84, 84, 84, 84 + ); + + public final Component[] ORIENTATIONS = { + Component.translatable("betterend.infusion.north").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.north_east").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.east").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.south_east").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.south").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.south_west").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.west").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.north_west").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + }; + private final ResourceLocation id; + private final List input; + private final List output; + + public EMIInfusionRecipe(InfusionRecipe recipe) { + this.id = recipe.getId(); + this.input = recipe.getIngredients().stream().map(i -> EmiIngredient.of(i)).toList(); + this.output = List.of(EmiStack.of(recipe.getResultItem())); + } + + static void addAllRecipes(EmiRegistry emiRegistry, RecipeManager manager) { + org.betterx.bclib.integration.emi.EMIPlugin.addAllRecipes( + emiRegistry, manager, BetterEnd.LOGGER, + InfusionRecipe.TYPE, EMIInfusionRecipe::new + ); + } + + + @Override + public EmiRecipeCategory getCategory() { + return EMIPlugin.INFUSION_CATEGORY; + } + + @Override + public @Nullable ResourceLocation getId() { + return id; + } + + @Override + public List getInputs() { + return input; + } + + @Override + public List getOutputs() { + return output; + } + + @Override + public int getDisplayWidth() { + return 4 + 10 + 84 + 68; + } + + @Override + public int getDisplayHeight() { + return 4 + 20 + 84; + } + + @Override + public void addWidgets(WidgetHolder widgets) { + final int radius = 36; + final int halfSize = 9; + final int left = 10; + final int top = 17; + + final int cx = left + 84 / 2; + final int cy = top + 84 / 2; + + final int right = left + 84; + final int bottom = top + 84; + widgets.addTexture(BACKGROUND, left, top); + // Add an arrow texture to indicate processing + widgets.addTexture(EmiTexture.EMPTY_ARROW, right + 10, cy - 8); + + // Adds an input slot on the left + widgets.add(new TransparentSlotWidget(input.get(0), cx - halfSize, cy - halfSize)); + + FormattedCharSequence str = FormattedCharSequence.forward("N", Style.EMPTY); + widgets.addText(str, cx - Minecraft.getInstance().font.width(str) / 2, 4, ColorUtil.WHITE, true); + double a = Math.PI; + for (int i = 1; i < input.size(); i++) { + widgets.add(new TransparentSlotWidget( + input.get(i), + cx - halfSize + (int) (Math.sin(a) * radius), + cy - halfSize + (int) (Math.cos(a) * radius) + )).appendTooltip(ORIENTATIONS[i - 1]); + a -= Math.PI / 4; + } + + // Adds an output slot on the right + // Note that output slots need to call `recipeContext` to inform EMI about their recipe context + // This includes being able to resolve recipe trees, favorite stacks with recipe context, and more + widgets.addSlot(output.get(0), right + 40, cy - (halfSize + 4)).output(true).recipeContext(this); + } + + @Override + public boolean supportsRecipeTree() { + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/integration/emi/EMIPlugin.java b/src/main/java/org/betterx/betterend/integration/emi/EMIPlugin.java new file mode 100644 index 00000000..e995ddd6 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/emi/EMIPlugin.java @@ -0,0 +1,40 @@ +package org.betterx.betterend.integration.emi; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.world.item.crafting.RecipeManager; + +import dev.emi.emi.api.EmiRegistry; +import dev.emi.emi.api.recipe.EmiRecipeCategory; +import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; +import dev.emi.emi.api.stack.EmiStack; + +public class EMIPlugin implements dev.emi.emi.api.EmiPlugin { + public static final EmiStack INFUSION_WORKSTATION = EmiStack.of(EndBlocks.INFUSION_PEDESTAL); + public static final EmiStack AZURE_JADESTONE_FURNACE_WORKSTATION = EmiStack.of(EndBlocks.AZURE_JADESTONE.furnace); + public static final EmiStack SANDY_JADESTONE_FURNACE_WORKSTATION = EmiStack.of(EndBlocks.SANDY_JADESTONE.furnace); + public static final EmiStack VIRID_JADESTONE_FURNACE_WORKSTATION = EmiStack.of(EndBlocks.VIRID_JADESTONE.furnace); + + public static final EmiRecipeCategory INFUSION_CATEGORY = new EmiRecipeCategory( + BetterEnd.makeID("infusion"), + INFUSION_WORKSTATION, + org.betterx.bclib.integration.emi.EMIPlugin.getSprite(0, 16) + ); + + @Override + public void register(EmiRegistry emiRegistry) { + final RecipeManager manager = emiRegistry.getRecipeManager(); + emiRegistry.addCategory(INFUSION_CATEGORY); + emiRegistry.addWorkstation(INFUSION_CATEGORY, INFUSION_WORKSTATION); + + EMIInfusionRecipe.addAllRecipes(emiRegistry, manager); + if (org.betterx.bclib.integration.emi.EMIPlugin.END_ALLOYING_CATEGORY != null) { + EMIBlastingRecipe.addAllRecipes(emiRegistry, manager); + } + + emiRegistry.addWorkstation(VanillaEmiRecipeCategories.SMELTING, AZURE_JADESTONE_FURNACE_WORKSTATION); + emiRegistry.addWorkstation(VanillaEmiRecipeCategories.SMELTING, SANDY_JADESTONE_FURNACE_WORKSTATION); + emiRegistry.addWorkstation(VanillaEmiRecipeCategories.SMELTING, VIRID_JADESTONE_FURNACE_WORKSTATION); + } +} diff --git a/src/main/java/org/betterx/betterend/integration/emi/TransparentSlotWidget.java b/src/main/java/org/betterx/betterend/integration/emi/TransparentSlotWidget.java new file mode 100644 index 00000000..1cc65591 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/emi/TransparentSlotWidget.java @@ -0,0 +1,92 @@ +package org.betterx.betterend.integration.emi; + +import org.betterx.ui.layout.components.render.RenderHelper; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.gui.GuiComponent; +import net.minecraft.client.renderer.GameRenderer; + +import dev.emi.emi.EmiClient; +import dev.emi.emi.EmiConfig; +import dev.emi.emi.EmiRenderHelper; +import dev.emi.emi.api.render.EmiRender; +import dev.emi.emi.api.stack.EmiIngredient; +import dev.emi.emi.api.widget.Bounds; +import dev.emi.emi.api.widget.SlotWidget; + +public class TransparentSlotWidget extends SlotWidget { + + public TransparentSlotWidget(EmiIngredient stack, int x, int y) { + super(stack, x, y); + } + + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + Bounds bounds = this.getBounds(); + RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + int width = bounds.width(); + int height = bounds.height(); + if (this.drawBack) { + if (this.textureId != null) { + RenderSystem.setShaderTexture(0, this.textureId); + GuiComponent.blit( + matrices, + bounds.x(), bounds.y(), width, height, + this.u, this.v, width, height, 256, 256 + ); + } else { + renderSlot(matrices); + } + } + + if (this.getRecipe() == null + && EmiClient.availableForCrafting.containsKey(this.getStack()) + && !this.getStack().isEmpty() + && !(Boolean) EmiClient.availableForCrafting.get(this.getStack())) { + GuiComponent.fill( + matrices, + bounds.x(), bounds.y(), + bounds.x() + bounds.width(), bounds.y() + bounds.height(), + 0x44FF0000 + ); + } + + int xOff = (width - 16) / 2; + int yOff = (height - 16) / 2; + this.getStack().render(matrices, bounds.x() + xOff, bounds.y() + yOff, delta); + if (this.catalyst) { + EmiRender.renderCatalystIcon(this.getStack(), matrices, this.x + xOff, this.y + yOff); + } + + if (EmiConfig.showHoverOverlay && bounds.contains(mouseX, mouseY)) { + EmiRenderHelper.drawSlotHightlight( + matrices, + bounds.x() + 1, bounds.y() + 1, + bounds.width() - 2, bounds.height() - 2 + ); + } + + } + + public void renderSlot(PoseStack matrices) { + Bounds bounds = this.getBounds(); + int width = bounds.width(); + int height = bounds.height(); + + GuiComponent.fill(matrices, bounds.x(), bounds.y(), bounds.x() + width, bounds.y() + height, 0xB08b8b8b); + RenderHelper.outline( + matrices, + bounds.x(), + bounds.y(), + bounds.x() + width, + bounds.y() + height, + 0xFA373737, + 0xFAFFFFFF + ); + RenderHelper.vLine(matrices, bounds.x() + width - 1, bounds.y(), bounds.y(), 0xFA8B8B8B); + RenderHelper.hLine(matrices, bounds.x(), bounds.x(), bounds.y() + bounds.height() - 1, 0xFA8B8B8B); + } +} diff --git a/src/main/java/org/betterx/betterend/integration/jei/JEIAlloyingCategory.java b/src/main/java/org/betterx/betterend/integration/jei/JEIAlloyingCategory.java new file mode 100644 index 00000000..649f23e1 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/jei/JEIAlloyingCategory.java @@ -0,0 +1,171 @@ +package org.betterx.betterend.integration.jei; + +import org.betterx.bclib.recipes.AlloyingRecipe; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndBlocks; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import mezz.jei.api.constants.ModIds; +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; +import mezz.jei.api.gui.drawable.IDrawable; +import mezz.jei.api.gui.drawable.IDrawableAnimated; +import mezz.jei.api.gui.drawable.IDrawableStatic; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.helpers.IGuiHelper; +import mezz.jei.api.recipe.IFocusGroup; +import mezz.jei.api.recipe.RecipeIngredientRole; +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.api.recipe.category.IRecipeCategory; + +public class JEIAlloyingCategory implements IRecipeCategory { + public static final RecipeType TYPE = RecipeType.create( + BetterEnd.MOD_ID, + AlloyingRecipe.GROUP, + AlloyingRecipe.class + ); + public static final String TEXTURE_GUI_PATH = "textures/gui/"; + public static final String TEXTURE_GUI_VANILLA = TEXTURE_GUI_PATH + "gui_vanilla.png"; + public static final ResourceLocation RECIPE_GUI_VANILLA = new ResourceLocation(ModIds.JEI_ID, TEXTURE_GUI_VANILLA); + public static final int width = 116; + public static final int height = 54; + + protected final IDrawableStatic staticFlame; + protected final IDrawableStatic addonSlot; + protected final IDrawableAnimated animatedFlame; + + private final IDrawable background; + private final IDrawable icon; + private final Component title; + private final LoadingCache cachedArrows; + + public JEIAlloyingCategory(IGuiHelper guiHelper) { + staticFlame = guiHelper.createDrawable(RECIPE_GUI_VANILLA, 82, 114, 14, 14); + animatedFlame = guiHelper.createAnimatedDrawable(staticFlame, 300, IDrawableAnimated.StartDirection.TOP, true); + background = guiHelper.createDrawable(RECIPE_GUI_VANILLA, 0, 114, 82, 54); + title = Component.translatable(EndBlocks.END_STONE_SMELTER.getDescriptionId()); + icon = guiHelper.createDrawableIngredient(VanillaTypes.ITEM_STACK, new ItemStack(EndBlocks.END_STONE_SMELTER)); + this.cachedArrows = CacheBuilder.newBuilder() + .maximumSize(25) + .build(new CacheLoader<>() { + @Override + public IDrawableAnimated load(Integer cookTime) { + return guiHelper.drawableBuilder( + RECIPE_GUI_VANILLA, + 82, + 128, + 24, + 17 + ) + .buildAnimated( + cookTime, + IDrawableAnimated.StartDirection.LEFT, + false + ); + } + }); + + addonSlot = guiHelper.getSlotDrawable(); + } + + protected IDrawableAnimated getArrow(AlloyingRecipe recipe) { + int cookTime = recipe.getSmeltTime(); + if (cookTime <= 0) { + cookTime = 0; + } + return this.cachedArrows.getUnchecked(cookTime); + } + + @Override + public RecipeType getRecipeType() { + return TYPE; + } + + @Override + public Component getTitle() { + return title; + } + + @Override + public IDrawable getBackground() { + return background; + } + + @Override + public IDrawable getIcon() { + return icon; + } + + @Override + public void setRecipe(IRecipeLayoutBuilder builder, AlloyingRecipe recipe, IFocusGroup focuses) { + builder.addSlot(RecipeIngredientRole.INPUT, 1, 1) + .addIngredients(recipe.getIngredients().get(0)); + + if (recipe.getIngredients().size() > 1) { + builder.addSlot(RecipeIngredientRole.INPUT, 21, 1) + .addIngredients(recipe.getIngredients().get(1)); + } + + builder.addSlot(RecipeIngredientRole.OUTPUT, 61, 19) + .addItemStack(recipe.getResultItem()); + } + + @Override + public boolean isHandled(AlloyingRecipe recipe) { + return !recipe.isSpecial(); + } + + @Override + public void draw( + AlloyingRecipe recipe, + IRecipeSlotsView recipeSlotsView, + PoseStack poseStack, + double mouseX, + double mouseY + ) { + animatedFlame.draw(poseStack, 1, 20); + + if (recipe.getIngredients().size() > 1) { + addonSlot.draw(poseStack, 20, 0); + } + + IDrawableAnimated arrow = getArrow(recipe); + arrow.draw(poseStack, 24, 18); + + drawExperience(recipe, poseStack, 0); + drawCookTime(recipe, poseStack, 45); + + } + + protected void drawExperience(AlloyingRecipe recipe, PoseStack poseStack, int y) { + float experience = recipe.getExperience(); + if (experience > 0) { + Component experienceString = Component.translatable("gui.jei.category.smelting.experience", experience); + Minecraft minecraft = Minecraft.getInstance(); + Font fontRenderer = minecraft.font; + int stringWidth = fontRenderer.width(experienceString); + fontRenderer.draw(poseStack, experienceString, background.getWidth() - stringWidth, y, 0xFF808080); + } + } + + protected void drawCookTime(AlloyingRecipe recipe, PoseStack poseStack, int y) { + int cookTime = recipe.getSmeltTime(); + if (cookTime > 0) { + int cookTimeSeconds = cookTime / 20; + Component timeString = Component.translatable("gui.jei.category.smelting.time.seconds", cookTimeSeconds); + Minecraft minecraft = Minecraft.getInstance(); + net.minecraft.client.gui.Font fontRenderer = minecraft.font; + int stringWidth = fontRenderer.width(timeString); + fontRenderer.draw(poseStack, timeString, background.getWidth() - stringWidth, y, 0xFF808080); + } + } +} diff --git a/src/main/java/org/betterx/betterend/integration/jei/JEIAlloyingFuelCategory.java b/src/main/java/org/betterx/betterend/integration/jei/JEIAlloyingFuelCategory.java new file mode 100644 index 00000000..bd1fc99a --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/jei/JEIAlloyingFuelCategory.java @@ -0,0 +1,183 @@ +package org.betterx.betterend.integration.jei; + +import org.betterx.bclib.recipes.AlloyingRecipe; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.entities.EndStoneSmelterBlockEntity; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.ui.layout.values.Rectangle; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; +import mezz.jei.api.gui.drawable.IDrawable; +import mezz.jei.api.gui.drawable.IDrawableAnimated; +import mezz.jei.api.gui.drawable.IDrawableStatic; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.helpers.IGuiHelper; +import mezz.jei.api.recipe.IFocusGroup; +import mezz.jei.api.recipe.RecipeIngredientRole; +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.api.recipe.category.IRecipeCategory; +import mezz.jei.api.recipe.vanilla.IJeiFuelingRecipe; +import mezz.jei.api.runtime.IIngredientManager; + +import java.text.NumberFormat; +import java.util.Comparator; +import java.util.List; +import org.jetbrains.annotations.Unmodifiable; + + +public class JEIAlloyingFuelCategory implements IRecipeCategory { + public static final RecipeType FUEL_TYPE = RecipeType.create( + BetterEnd.MOD_ID, + AlloyingRecipe.GROUP + "_fuel", + IJeiFuelingRecipe.class + ); + + private final IDrawableStatic background; + private final IDrawable icon; + private final Component localizedName; + private final LoadingCache cachedFlames; + private final Rectangle textArea; + + public static List getFuelRecipes(IIngredientManager ingredientManager) { + return ingredientManager.getAllIngredients(VanillaTypes.ITEM_STACK).stream() + .mapMulti((stack, consumer) -> { + if (EndStoneSmelterBlockEntity.canUseAsFuel(stack)) { + final int time = EndStoneSmelterBlockEntity.getFuelTime(stack); + if (time > 0) { + final List inputs = List.of(stack); + consumer.accept(new IJeiFuelingRecipe() { + @Override + public @Unmodifiable List getInputs() { + return inputs; + } + + @Override + public int getBurnTime() { + return time; + } + }); + } + } + + }) + .sorted(Comparator.comparingInt(IJeiFuelingRecipe::getBurnTime)) + .toList(); + } + + public JEIAlloyingFuelCategory(IGuiHelper guiHelper) { + + // width of the recipe depends on the text, which is different in each language + Minecraft minecraft = Minecraft.getInstance(); + Font fontRenderer = minecraft.font; + Component maxSmeltCountText = createSmeltCountText(10000000 * 200); + int maxStringWidth = fontRenderer.width(maxSmeltCountText.getString()); + int backgroundHeight = 34; + int textPadding = 20; + + background = guiHelper.drawableBuilder(JEIAlloyingCategory.RECIPE_GUI_VANILLA, 0, 134, 18, backgroundHeight) + .addPadding(0, 0, 0, textPadding + maxStringWidth) + .build(); + + textArea = new Rectangle(20, 0, textPadding + maxStringWidth, backgroundHeight); + + icon = guiHelper.createDrawableIngredient( + VanillaTypes.ITEM_STACK, + new ItemStack(EndBlocks.END_STONE_SMELTER) + ); + ; + localizedName = Component.translatable("gui.jei.category.fuel"); + + this.cachedFlames = CacheBuilder.newBuilder() + .maximumSize(25) + .build(new CacheLoader<>() { + @Override + public IDrawableAnimated load(Integer burnTime) { + return guiHelper.drawableBuilder( + JEIAlloyingCategory.RECIPE_GUI_VANILLA, + 82, + 114, + 14, + 14 + ) + .buildAnimated( + burnTime, + IDrawableAnimated.StartDirection.TOP, + true + ); + } + }); + } + + @Override + public IDrawable getBackground() { + return background; + } + + @Override + public RecipeType getRecipeType() { + return FUEL_TYPE; + } + + @Override + public Component getTitle() { + return localizedName; + } + + @Override + public IDrawable getIcon() { + return icon; + } + + @Override + public void setRecipe(IRecipeLayoutBuilder builder, IJeiFuelingRecipe recipe, IFocusGroup focuses) { + builder.addSlot(RecipeIngredientRole.INPUT, 1, 17) + .addItemStacks(recipe.getInputs()); + } + + @Override + public void draw( + IJeiFuelingRecipe recipe, + IRecipeSlotsView recipeSlotsView, + PoseStack poseStack, + double mouseX, + double mouseY + ) { + int burnTime = recipe.getBurnTime(); + IDrawableAnimated flame = cachedFlames.getUnchecked(burnTime); + flame.draw(poseStack, 1, 0); + Minecraft minecraft = Minecraft.getInstance(); + Font font = minecraft.font; + Component smeltCountText = createSmeltCountText(burnTime); + int width = font.width(smeltCountText); + int height = font.lineHeight; + + font.draw( + poseStack, + smeltCountText, + this.textArea.left + (this.textArea.width - width) / 2, + this.textArea.top + (this.textArea.height - height) / 2 + 1, + 0xFF808080 + ); + } + + private static Component createSmeltCountText(int burnTime) { + if (burnTime == 200) { + return Component.translatable("gui.jei.category.fuel.smeltCount.single"); + } else { + NumberFormat numberInstance = NumberFormat.getNumberInstance(); + numberInstance.setMaximumFractionDigits(2); + String smeltCount = numberInstance.format(burnTime / 200f); + return Component.translatable("gui.jei.category.fuel.smeltCount", smeltCount); + } + } +} diff --git a/src/main/java/org/betterx/betterend/integration/jei/JEIPlugin.java b/src/main/java/org/betterx/betterend/integration/jei/JEIPlugin.java new file mode 100644 index 00000000..5d3fa929 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/jei/JEIPlugin.java @@ -0,0 +1,71 @@ +package org.betterx.betterend.integration.jei; + +import org.betterx.bclib.recipes.AlloyingRecipe; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; + +import mezz.jei.api.IModPlugin; +import mezz.jei.api.helpers.IGuiHelper; +import mezz.jei.api.helpers.IJeiHelpers; +import mezz.jei.api.registration.IRecipeCatalystRegistration; +import mezz.jei.api.registration.IRecipeCategoryRegistration; +import mezz.jei.api.registration.IRecipeRegistration; +import mezz.jei.api.registration.IRecipeTransferRegistration; +import mezz.jei.api.runtime.IIngredientManager; + +public class JEIPlugin implements IModPlugin { + public final static ResourceLocation PLUGIN_ID = BetterEnd.makeID("jei_plugin"); + + + @Override + public ResourceLocation getPluginUid() { + return PLUGIN_ID; + } + + @Override + public void registerCategories(IRecipeCategoryRegistration registration) { + IModPlugin.super.registerCategories(registration); + + IJeiHelpers jeiHelpers = registration.getJeiHelpers(); + IGuiHelper guiHelper = jeiHelpers.getGuiHelper(); + + registration.addRecipeCategories(new JEIAlloyingCategory(guiHelper)); + registration.addRecipeCategories(new JEIAlloyingFuelCategory(guiHelper)); + } + + @Override + public void registerRecipes(IRecipeRegistration registration) { + Minecraft minecraft = Minecraft.getInstance(); + ClientLevel world = minecraft.level; + var recipeManager = world.getRecipeManager(); + IIngredientManager ingredientManager = registration.getIngredientManager(); + + IModPlugin.super.registerRecipes(registration); + registration.addRecipes(JEIAlloyingCategory.TYPE, recipeManager.getAllRecipesFor(AlloyingRecipe.TYPE)); + registration.addRecipes( + JEIAlloyingFuelCategory.FUEL_TYPE, + JEIAlloyingFuelCategory.getFuelRecipes(ingredientManager) + ); + } + + @Override + public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) { + IModPlugin.super.registerRecipeCatalysts(registration); + registration.addRecipeCatalyst( + new ItemStack(EndBlocks.END_STONE_SMELTER), + JEIAlloyingCategory.TYPE, + JEIAlloyingFuelCategory.FUEL_TYPE + ); + } + + @Override + public void registerRecipeTransferHandlers(IRecipeTransferRegistration registration) { + IModPlugin.super.registerRecipeTransferHandlers(registration); + + } +} diff --git a/src/main/java/org/betterx/betterend/integration/rei/REIAlloyingCategory.java b/src/main/java/org/betterx/betterend/integration/rei/REIAlloyingCategory.java new file mode 100644 index 00000000..d96b5a37 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/rei/REIAlloyingCategory.java @@ -0,0 +1,88 @@ +package org.betterx.betterend.integration.rei; + + +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.network.chat.Component; + +import com.google.common.collect.Lists; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.gui.widgets.Widgets; +import me.shedaniel.rei.api.client.registry.display.DisplayCategory; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.entry.EntryStack; + +import java.text.DecimalFormat; +import java.util.List; +import org.jetbrains.annotations.NotNull; + +public class REIAlloyingCategory implements DisplayCategory { + private final EntryStack ICON; + + REIAlloyingCategory(EntryStack icon) { + ICON = icon; + } + + @Override + public @NotNull CategoryIdentifier getCategoryIdentifier() { + return REIPlugin.ALLOYING; + } + + @Override + public @NotNull Component getTitle() { + return Component.translatable(EndBlocks.END_STONE_SMELTER.getDescriptionId()); + } + + @Override + public @NotNull EntryStack getIcon() { + return ICON; + } + + @Override + public @NotNull List setupDisplay(REIAlloyingDisplay display, Rectangle bounds) { + Point startPoint = new Point(bounds.getCenterX() - 41, bounds.y + 10); + double smeltTime = display.getSmeltTime(); + DecimalFormat df = new DecimalFormat("###.##"); + List widgets = Lists.newArrayList(); + widgets.add(Widgets.createRecipeBase(bounds)); + widgets.add(Widgets.createResultSlotBackground(new Point(startPoint.x + 61, startPoint.y + 9))); + widgets.add(Widgets.createBurningFire(new Point(startPoint.x - 9, startPoint.y + 20)) + .animationDurationMS(10000)); + widgets.add(Widgets.createLabel( + new Point(bounds.x + bounds.width - 5, bounds.y + 5), + Component.translatable( + "category.rei.cooking.time&xp", + df.format(display.getXp()), + df.format(smeltTime / 20D) + ) + ).noShadow().rightAligned().color(0xFF404040, 0xFFBBBBBB)); + widgets.add(Widgets.createArrow(new Point(startPoint.x + 24, startPoint.y + 8)) + .animationDurationTicks(smeltTime)); + List inputEntries = display.getInputEntries(); + widgets.add(Widgets.createSlot(new Point(startPoint.x - 20, startPoint.y + 1)) + .entries(inputEntries.get(0)) + .markInput()); + if (inputEntries.size() > 1) { + widgets.add(Widgets.createSlot(new Point(startPoint.x + 1, startPoint.y + 1)) + .entries(inputEntries.get(1)) + .markInput()); + } else { + widgets.add(Widgets.createSlot(new Point(startPoint.x + 1, startPoint.y + 1)) + .entries(Lists.newArrayList()) + .markInput()); + } + widgets.add(Widgets.createSlot(new Point(startPoint.x + 61, startPoint.y + 9)) + .entries(display.getOutputEntries().get(0)) + .disableBackground() + .markOutput()); + return widgets; + } + + @Override + public int getDisplayHeight() { + return 49; + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/integration/rei/REIAlloyingDisplay.java b/src/main/java/org/betterx/betterend/integration/rei/REIAlloyingDisplay.java new file mode 100644 index 00000000..b408eaac --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/rei/REIAlloyingDisplay.java @@ -0,0 +1,108 @@ +package org.betterx.betterend.integration.rei; + +import org.betterx.bclib.recipes.AlloyingRecipe; +import org.betterx.betterend.blocks.entities.EndStoneSmelterBlockEntity; + +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.crafting.Recipe; + +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.display.SimpleGridMenuDisplay; +import me.shedaniel.rei.api.common.display.basic.BasicDisplay; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.api.common.util.EntryStacks; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import org.jetbrains.annotations.NotNull; + +public class REIAlloyingDisplay extends BasicDisplay implements SimpleGridMenuDisplay { + + private static final List fuel; + + private final Recipe recipe; + private final float xp; + private final double smeltTime; + + + public REIAlloyingDisplay(AlloyingRecipe recipe) { + this(recipe, recipe.getExperience(), recipe.getSmeltTime()); + } + + protected REIAlloyingDisplay(Recipe recipe, float xp, double smeltTime) { + super( + EntryIngredients.ofIngredients(recipe.getIngredients()), + Collections.singletonList(EntryIngredients.of(recipe.getResultItem())) + ); + this.recipe = recipe; + this.xp = xp; + this.smeltTime = smeltTime; + } + + + public static List getFuel() { + return fuel; + } + + @Override + public @NotNull Optional getDisplayLocation() { + return Optional.ofNullable(recipe).map(Recipe::getId); + } + + @Override + public CategoryIdentifier getCategoryIdentifier() { + return REIPlugin.ALLOYING; + } + + // @Override + // public @NotNull List> getRequiredEntries() { + // return this.input; + // } + + public float getXp() { + return this.xp; + } + + public double getSmeltTime() { + return this.smeltTime; + } + + public Optional> getOptionalRecipe() { + return Optional.ofNullable(recipe); + } + + @Override + public int getWidth() { + return 2; + } + + @Override + public int getHeight() { + return 1; + } + + // @Override + // public List> getOrganisedInputEntries(ContainerInfo containerInfo, AbstractContainerMenu container) { + // return this.input; + // } + + static { + fuel = EndStoneSmelterBlockEntity.availableFuels() + .keySet() + .stream() + .map(Item::getDefaultInstance) + .map(EntryStacks::of) + .map(e -> e.setting( + EntryStack.Settings.TOOLTIP_APPEND_EXTRA, + stack -> Collections.singletonList(Component.translatable( + "category.rei.smelting.fuel").withStyle(ChatFormatting.YELLOW)) + )) + .collect(Collectors.toList()); + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/integration/rei/REIAlloyingFuelCategory.java b/src/main/java/org/betterx/betterend/integration/rei/REIAlloyingFuelCategory.java new file mode 100644 index 00000000..19cacf77 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/rei/REIAlloyingFuelCategory.java @@ -0,0 +1,104 @@ +package org.betterx.betterend.integration.rei; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Items; + +import com.google.common.collect.Lists; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.DisplayRenderer; +import me.shedaniel.rei.api.client.gui.widgets.*; +import me.shedaniel.rei.api.client.registry.display.DisplayCategory; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.EntryStacks; + +import java.text.DecimalFormat; +import java.util.List; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class REIAlloyingFuelCategory implements DisplayCategory { + private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##"); + + @Override + public @NotNull CategoryIdentifier getCategoryIdentifier() { + return REIPlugin.ALLOYING_FUEL; + } + + @Override + public @NotNull Component getTitle() { + return Component.translatable("category.rei.fuel"); + } + + @Override + public int getDisplayHeight() { + return 49; + } + + @Override + public @NotNull EntryStack getIcon() { + return EntryStacks.of(Items.LAVA_BUCKET); + } + + @Override + public List setupDisplay(REIAlloyingFuelDisplay recipeDisplay, Rectangle bounds) { + Point startPoint = new Point(bounds.getCenterX() - 41, bounds.getCenterY() - 17); + String burnTime = DECIMAL_FORMAT.format(recipeDisplay.getFuelTime()); + List widgets = Lists.newArrayList(); + widgets.add(Widgets.createRecipeBase(bounds)); + widgets.add(Widgets.createLabel( + new Point(bounds.x + 26, bounds.getMaxY() - 15), + Component.translatable("category.rei.fuel.time", burnTime) + ).color(0xFF404040, 0xFFBBBBBB).noShadow().leftAligned()); + widgets.add(Widgets.createBurningFire(new Point(bounds.x + 6, startPoint.y + 1)) + .animationDurationTicks(recipeDisplay.getFuelTime())); + widgets.add(Widgets.createSlot(new Point(bounds.x + 6, startPoint.y + 18)) + .entries(recipeDisplay.getInputEntries().get(0)) + .markInput()); + return widgets; + } + + @Override + public DisplayRenderer getDisplayRenderer(REIAlloyingFuelDisplay recipe) { + Slot slot = Widgets.createSlot(new Point(0, 0)) + .entries(recipe.getInputEntries().get(0)) + .disableBackground() + .disableHighlight(); + String burnItems = DECIMAL_FORMAT.format(recipe.getFuelTime() / 200d); + return new DisplayRenderer() { + private final Component text = Component.translatable( + "category.rei.fuel.time_short.items", + burnItems + ); + + @Override + public int getHeight() { + return 22; + } + + @Nullable + @Override + public Tooltip getTooltip(TooltipContext ctx) { + if (slot.containsMouse(ctx.getPoint())) return slot.getCurrentTooltip(ctx); + return null; + } + + @Override + public void render(PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { + slot.setZ(getZ() + 50); + slot.getBounds().setLocation(bounds.x + 4, bounds.y + 2); + slot.render(matrices, mouseX, mouseY, delta); + Minecraft.getInstance().font.drawShadow( + matrices, + text.getVisualOrderText(), + bounds.x + 25, + bounds.y + 8, + -1 + ); + } + }; + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/integration/rei/REIAlloyingFuelDisplay.java b/src/main/java/org/betterx/betterend/integration/rei/REIAlloyingFuelDisplay.java new file mode 100644 index 00000000..02f974d8 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/rei/REIAlloyingFuelDisplay.java @@ -0,0 +1,27 @@ +package org.betterx.betterend.integration.rei; + +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.display.basic.BasicDisplay; +import me.shedaniel.rei.api.common.entry.EntryIngredient; + +import java.util.Collections; +import java.util.List; + +public class REIAlloyingFuelDisplay extends BasicDisplay { + private final int fuelTime; + + public REIAlloyingFuelDisplay(List fuel, int fuelTime) { + super(fuel, Collections.emptyList()); + this.fuelTime = fuelTime; + } + + @Override + public CategoryIdentifier getCategoryIdentifier() { + return REIPlugin.ALLOYING_FUEL; + } + + public int getFuelTime() { + return fuelTime; + } + +} diff --git a/src/main/java/org/betterx/betterend/integration/rei/REIAnvilCategory.java b/src/main/java/org/betterx/betterend/integration/rei/REIAnvilCategory.java new file mode 100644 index 00000000..80fbfaf5 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/rei/REIAnvilCategory.java @@ -0,0 +1,91 @@ +package org.betterx.betterend.integration.rei; + +import org.betterx.betterend.blocks.basis.EndAnvilBlock; + +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; + +import com.google.common.collect.Lists; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.gui.widgets.Widgets; +import me.shedaniel.rei.api.client.registry.display.DisplayCategory; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.entry.EntryStack; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import org.jetbrains.annotations.NotNull; + +public class REIAnvilCategory implements DisplayCategory { + private final EntryStack[] ANVILS; + + REIAnvilCategory(EntryStack[] anvils) { + ANVILS = anvils; + } + + @Override + public CategoryIdentifier getCategoryIdentifier() { + return REIPlugin.SMITHING; + } + + @Override + public @NotNull Component getTitle() { + return Component.translatable(Blocks.ANVIL.getDescriptionId()); + } + + @Override + public @NotNull EntryStack getIcon() { + return ANVILS[0]; + } + + + @Override + public @NotNull List setupDisplay(REIAnvilDisplay display, Rectangle bounds) { + Point startPoint = new Point(bounds.getCenterX() - 41, bounds.y + 10); + List widgets = Lists.newArrayList(); + widgets.add(Widgets.createRecipeBase(bounds)); + int x = startPoint.x + 10; + int y = startPoint.y; + widgets.add(Widgets.createResultSlotBackground(new Point(x + 61, y + 5))); + List inputEntries = display.getInputEntries(); + EntryIngredient materials = inputEntries.get(1); + int anvilLevel = display.getAnvilLevel(); + List> anvils = Arrays.stream(ANVILS).filter(anvil -> { + Object value = anvil.getValue(); + if (value instanceof ItemStack) { + value = ((ItemStack) value).getItem(); + } + Block block = ((BlockItem) value).getBlock(); + if (block instanceof EndAnvilBlock) { + return ((EndAnvilBlock) block).getCraftingLevel() >= anvilLevel; + } + return anvilLevel == 1; + }).collect(Collectors.toList()); + widgets.add(Widgets.createArrow(new Point(x + 24, y + 4))); + widgets.add(Widgets.createLabel( + new Point(bounds.x + bounds.width - 7, bounds.y + bounds.height - 15), + Component.translatable("category.rei.damage.amount&dmg", display.getDamage()) + ).noShadow().rightAligned().color(0xFF404040, 0xFFBBBBBB)); + widgets.add(Widgets.createSlot(new Point(x - 20, y + 4)).entries(materials).markInput()); + widgets.add(Widgets.createSlot(new Point(x + 1, y + 4)).entries(inputEntries.get(0)).markInput()); + widgets.add(Widgets.createSlot(new Point(x + 61, y + 5)) + .entries(display.getOutputEntries().get(0)) + .disableBackground() + .markOutput()); + widgets.add(Widgets.createSlot(new Point(x - 9, y + 25)).entries(anvils)); + + return widgets; + } + + @Override + public int getDisplayHeight() { + return 60; + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/integration/rei/REIAnvilDisplay.java b/src/main/java/org/betterx/betterend/integration/rei/REIAnvilDisplay.java new file mode 100644 index 00000000..4f8cd6fe --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/rei/REIAnvilDisplay.java @@ -0,0 +1,64 @@ +package org.betterx.betterend.integration.rei; + +import org.betterx.bclib.recipes.AnvilRecipe; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Recipe; + +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.display.SimpleGridMenuDisplay; +import me.shedaniel.rei.api.common.display.basic.BasicDisplay; +import me.shedaniel.rei.api.common.util.EntryIngredients; + +import java.util.Collections; +import java.util.Optional; +import org.jetbrains.annotations.NotNull; + +public class REIAnvilDisplay extends BasicDisplay implements SimpleGridMenuDisplay { + + private final AnvilRecipe recipe; + + public REIAnvilDisplay(AnvilRecipe recipe) { + super( + EntryIngredients.ofIngredients(recipe.getIngredients()), + Collections.singletonList(EntryIngredients.of(recipe.getResultItem())) + ); + this.recipe = recipe; + + inputs.get(1).forEach(entryStack -> { + if (entryStack.getValue() instanceof ItemStack itemStack) { + itemStack.setCount(recipe.getInputCount()); + } + }); + } + + public int getDamage() { + return recipe.getDamage(); + } + + public int getAnvilLevel() { + return recipe.getAnvilLevel(); + } + + @Override + public @NotNull Optional getDisplayLocation() { + return Optional.ofNullable(recipe).map(Recipe::getId); + } + + @Override + public CategoryIdentifier getCategoryIdentifier() { + return REIPlugin.SMITHING; + } + + @Override + public int getWidth() { + return 2; + } + + @Override + public int getHeight() { + return 1; + } +} + diff --git a/src/main/java/org/betterx/betterend/integration/rei/REIBlastingDisplay.java b/src/main/java/org/betterx/betterend/integration/rei/REIBlastingDisplay.java new file mode 100644 index 00000000..2d752276 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/rei/REIBlastingDisplay.java @@ -0,0 +1,9 @@ +package org.betterx.betterend.integration.rei; + +import net.minecraft.world.item.crafting.BlastingRecipe; + +public class REIBlastingDisplay extends REIAlloyingDisplay { + public REIBlastingDisplay(BlastingRecipe recipe) { + super(recipe, recipe.getExperience(), recipe.getCookingTime()); + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/integration/rei/REIInfusionCategory.java b/src/main/java/org/betterx/betterend/integration/rei/REIInfusionCategory.java new file mode 100644 index 00000000..8b49ed6b --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/rei/REIInfusionCategory.java @@ -0,0 +1,112 @@ +package org.betterx.betterend.integration.rei; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; + +import com.google.common.collect.Lists; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.gui.widgets.Widgets; +import me.shedaniel.rei.api.client.registry.display.DisplayCategory; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.entry.EntryStack; + +import java.util.ArrayList; +import java.util.List; +import org.jetbrains.annotations.NotNull; + +public class REIInfusionCategory implements DisplayCategory { + + private final static ResourceLocation BACKGROUND = BetterEnd.makeID("textures/gui/rei_infusion.png"); + private final EntryStack ICON; + + REIInfusionCategory(EntryStack icon) { + ICON = icon; + } + + @Override + public @NotNull CategoryIdentifier getCategoryIdentifier() { + return REIPlugin.INFUSION; + } + + @Override + public @NotNull Component getTitle() { + return Component.translatable(EndBlocks.INFUSION_PEDESTAL.getDescriptionId()); + } + + @Override + public @NotNull EntryStack getIcon() { + return ICON; + } + + @Override + public @NotNull List setupDisplay(REIInfusionDisplay display, Rectangle bounds) { + Point centerPoint = new Point(bounds.getCenterX() - 34, bounds.getCenterY() - 2); + List widgets = Lists.newArrayList(); + widgets.add(Widgets.createRecipeBase(bounds)); + List inputEntries = display.getInputEntries(); + List outputEntries = display.getOutputEntries(); + if (inputEntries.size() < 9) { + List newList = new ArrayList(9); + newList.addAll(inputEntries); + for (int i = inputEntries.size(); i < 9; i++) { + newList.add(EntryIngredient.empty()); + } + inputEntries = newList; + } + widgets.add(Widgets.createTexturedWidget(BACKGROUND, bounds.x, bounds.y, 0, 0, 150, 104, 150, 104)); + widgets.add(Widgets.createSlot(centerPoint).entries(inputEntries.get(0)).disableBackground().markInput()); + widgets.add(Widgets.createSlot(new Point(centerPoint.x, centerPoint.y - 28)) + .entries(inputEntries.get(1)) + .disableBackground() + .markInput()); + widgets.add(Widgets.createSlot(new Point(centerPoint.x + 28, centerPoint.y)) + .entries(inputEntries.get(3)) + .disableBackground() + .markInput()); + widgets.add(Widgets.createSlot(new Point(centerPoint.x, centerPoint.y + 28)) + .entries(inputEntries.get(5)) + .disableBackground() + .markInput()); + widgets.add(Widgets.createSlot(new Point(centerPoint.x - 28, centerPoint.y)) + .entries(inputEntries.get(7)) + .disableBackground() + .markInput()); + widgets.add(Widgets.createSlot(new Point(centerPoint.x + 24, centerPoint.y - 24)) + .entries(inputEntries.get(2)) + .disableBackground() + .markInput()); + widgets.add(Widgets.createSlot(new Point(centerPoint.x + 24, centerPoint.y + 24)) + .entries(inputEntries.get(4)) + .disableBackground() + .markInput()); + widgets.add(Widgets.createSlot(new Point(centerPoint.x - 24, centerPoint.y + 24)) + .entries(inputEntries.get(6)) + .disableBackground() + .markInput()); + widgets.add(Widgets.createSlot(new Point(centerPoint.x - 24, centerPoint.y - 24)) + .entries(inputEntries.get(8)) + .disableBackground() + .markInput()); + widgets.add(Widgets.createSlot(new Point(centerPoint.x + 80, centerPoint.y)) + .entries(outputEntries.get(0)) + .disableBackground() + .markOutput()); + widgets.add(Widgets.createLabel( + new Point(bounds.getMaxX() - 5, bounds.y + 6), + Component.translatable("category.rei.infusion.time&val", display.getInfusionTime()) + ).noShadow().rightAligned().color(0xFF404040, 0xFFBBBBBB)); + return widgets; + } + + @Override + public int getDisplayHeight() { + return 104; + } +} + diff --git a/src/main/java/org/betterx/betterend/integration/rei/REIInfusionDisplay.java b/src/main/java/org/betterx/betterend/integration/rei/REIInfusionDisplay.java new file mode 100644 index 00000000..645a84a1 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/rei/REIInfusionDisplay.java @@ -0,0 +1,64 @@ +package org.betterx.betterend.integration.rei; + +import org.betterx.betterend.recipe.builders.InfusionRecipe; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.crafting.Recipe; + +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.display.SimpleGridMenuDisplay; +import me.shedaniel.rei.api.common.display.basic.BasicDisplay; +import me.shedaniel.rei.api.common.util.EntryIngredients; + +import java.util.Collections; +import java.util.Optional; +import org.jetbrains.annotations.NotNull; + +public class REIInfusionDisplay extends BasicDisplay implements SimpleGridMenuDisplay { + + private final InfusionRecipe recipe; + private final int time; + + public REIInfusionDisplay(InfusionRecipe recipe) { + super( + EntryIngredients.ofIngredients(recipe.getIngredients()), + Collections.singletonList(EntryIngredients.of(recipe.getResultItem())) + ); + this.recipe = recipe; + this.time = recipe.getInfusionTime(); + } + + public int getInfusionTime() { + return this.time; + } + + @Override + public @NotNull Optional getDisplayLocation() { + return Optional.ofNullable(recipe).map(Recipe::getId); + } + + @Override + public CategoryIdentifier getCategoryIdentifier() { + return REIPlugin.INFUSION; + } + + // @Override + // public @NotNull List> getRequiredEntries() { + // return this.input; + // } + + @Override + public int getWidth() { + return 0; + } + + @Override + public int getHeight() { + return 0; + } + + // @Override + // public List> getOrganisedInputEntries(ContainerInfo containerInfo, AbstractContainerMenu container) { + // return this.input; + //} +} diff --git a/src/main/java/org/betterx/betterend/integration/rei/REIPlugin.java b/src/main/java/org/betterx/betterend/integration/rei/REIPlugin.java new file mode 100644 index 00000000..3b87f9fd --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/rei/REIPlugin.java @@ -0,0 +1,106 @@ +package org.betterx.betterend.integration.rei; + +import org.betterx.bclib.blocks.BaseFurnaceBlock; +import org.betterx.bclib.recipes.AlloyingRecipe; +import org.betterx.bclib.recipes.AnvilRecipe; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.basis.EndAnvilBlock; +import org.betterx.betterend.recipe.builders.InfusionRecipe; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.BlastingRecipe; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.block.Blocks; + +import net.fabricmc.fabric.api.registry.FuelRegistry; +import net.fabricmc.fabric.impl.content.registry.FuelRegistryImpl; + +import com.google.common.collect.Lists; +import me.shedaniel.rei.api.client.plugins.REIClientPlugin; +import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; +import me.shedaniel.rei.api.client.registry.display.DisplayRegistry; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.api.common.util.EntryStacks; +import me.shedaniel.rei.plugin.common.BuiltinPlugin; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + + +//https://github.com/shedaniel/RoughlyEnoughItems/blob/6.x-1.17/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java +public class REIPlugin implements REIClientPlugin { + public final static ResourceLocation PLUGIN_ID = BetterEnd.makeID("rei_plugin"); + public final static CategoryIdentifier ALLOYING_FUEL = CategoryIdentifier.of( + BetterEnd.MOD_ID, + "alloying_fuel" + ); + public final static CategoryIdentifier ALLOYING = CategoryIdentifier.of( + BetterEnd.MOD_ID, + AlloyingRecipe.GROUP + ); + public final static CategoryIdentifier SMITHING = CategoryIdentifier.of( + BetterEnd.MOD_ID, + AnvilRecipe.ID.getPath() + ); + public final static CategoryIdentifier INFUSION = CategoryIdentifier.of( + BetterEnd.MOD_ID, + InfusionRecipe.GROUP + ); + + @Override + public void registerDisplays(DisplayRegistry registry) { + registry.registerRecipeFiller(AlloyingRecipe.class, AlloyingRecipe.TYPE, REIAlloyingDisplay::new); + registry.registerRecipeFiller(BlastingRecipe.class, RecipeType.BLASTING, REIBlastingDisplay::new); + registry.registerRecipeFiller(AnvilRecipe.class, AnvilRecipe.TYPE, REIAnvilDisplay::new); + registry.registerRecipeFiller(InfusionRecipe.class, InfusionRecipe.TYPE, REIInfusionDisplay::new); + + if (FuelRegistry.INSTANCE instanceof FuelRegistryImpl fabricImpl) { + fabricImpl.getFuelTimes().forEach((item, time) -> { + if (time >= 2000) { + final List list = Collections.singletonList(EntryIngredients.of(item)); + registry.add(new REIAlloyingFuelDisplay(list, time)); + } + }); + } + } + + @Override + public void registerCategories(CategoryRegistry registry) { + EntryStack endStoneSmelter = EntryStacks.of(EndBlocks.END_STONE_SMELTER); + EntryStack infusionRitual = EntryStacks.of(EndBlocks.INFUSION_PEDESTAL); + List> anvils = Lists.newArrayList(EntryIngredients.ofItems(EndBlocks.getModBlocks() + .stream() + .filter(EndAnvilBlock.class::isInstance) + .collect(Collectors.toList()))); + anvils.add(0, EntryStacks.of(Blocks.ANVIL)); + List> ITEM_FURNACES = Lists.newArrayList(EntryIngredients.ofItems(EndBlocks.getModBlocks() + .stream() + .filter(BaseFurnaceBlock.class::isInstance) + .collect(Collectors.toList()))); + EntryStack[] anvilsArray = anvils.toArray(new EntryStack[0]); + EntryStack[] ITEM_FURNACESArray = ITEM_FURNACES.toArray(new EntryStack[0]); + + registry.add( + new REIAlloyingFuelCategory(), + new REIAlloyingCategory(endStoneSmelter), + new REIInfusionCategory(infusionRitual), + new REIAnvilCategory(anvilsArray) + ); + + registry.addWorkstations(ALLOYING_FUEL, endStoneSmelter); + registry.addWorkstations(ALLOYING, endStoneSmelter); + registry.addWorkstations(INFUSION, infusionRitual); + registry.addWorkstations(SMITHING, anvilsArray); + registry.removePlusButton(ALLOYING_FUEL); + registry.removePlusButton(SMITHING); + + registry.addWorkstations(BuiltinPlugin.SMELTING, ITEM_FURNACESArray); + registry.addWorkstations(BuiltinPlugin.FUEL, ITEM_FURNACESArray); + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/integration/trinkets/Elytra.java b/src/main/java/org/betterx/betterend/integration/trinkets/Elytra.java new file mode 100644 index 00000000..fb1597d4 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/trinkets/Elytra.java @@ -0,0 +1,88 @@ +package org.betterx.betterend.integration.trinkets; + +import org.betterx.bclib.items.elytra.BCLElytraItem; +import org.betterx.bclib.items.elytra.BCLElytraUtils; + +import net.minecraft.util.Tuple; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ElytraItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +import net.fabricmc.fabric.api.entity.event.v1.EntityElytraEvents; +import net.fabricmc.fabric.api.entity.event.v1.FabricElytraItem; + +import dev.emi.trinkets.api.SlotReference; +import dev.emi.trinkets.api.TrinketComponent; +import dev.emi.trinkets.api.TrinketsApi; + +import java.util.List; +import java.util.Optional; + +public class Elytra { + private static boolean isElytra(ItemStack stack) { + return stack.getItem() instanceof ElytraItem + || stack.getItem() instanceof FabricElytraItem; + } + + public static void register() { + BCLElytraUtils.slotProvider = (entity, slotGetter) -> { + ItemStack itemStack = slotGetter.apply(EquipmentSlot.CHEST); + if (isElytra(itemStack)) return itemStack; + + Optional oTrinketComponent = TrinketsApi.getTrinketComponent(entity); + if (oTrinketComponent.isPresent()) { + List> equipped = + oTrinketComponent.get().getEquipped(Elytra::isElytra); + + if (!equipped.isEmpty()) return equipped.get(0).getB(); + } + return null; + }; + + BCLElytraUtils.onBreak = (entity, chestStack) -> { + Optional oTrinketComponent = TrinketsApi.getTrinketComponent(entity); + if (oTrinketComponent.isPresent()) { + List> equipped = + oTrinketComponent.get().getEquipped(Elytra::isElytra); + + for (Tuple slot : equipped) { + ItemStack slotStack = slot.getB(); + if (slotStack == chestStack) { + TrinketsApi.onTrinketBroken(slotStack, slot.getA(), entity); + } + } + } + }; + + EntityElytraEvents.CUSTOM.register(Elytra::useElytraTrinket); + } + + private static boolean useElytraTrinket(LivingEntity entity, boolean tickElytra) { + Optional oTrinketComponent = TrinketsApi.getTrinketComponent(entity); + if (oTrinketComponent.isPresent()) { + List> equipped = + oTrinketComponent.get().getEquipped(Elytra::isElytra); + + for (Tuple slot : equipped) { + ItemStack stack = slot.getB(); + Item item = stack.getItem(); + + if (item instanceof ElytraItem) { + if (ElytraItem.isFlyEnabled(stack)) { + BCLElytraItem.vanillaElytraTick(entity, stack); + return true; + } + } else if (item instanceof FabricElytraItem fabricElytraItem) { + if (fabricElytraItem.useCustomElytra(entity, stack, tickElytra)) { + return true; + } + } + } + } + return false; + } +} + + diff --git a/src/main/java/org/betterx/betterend/integration/trinkets/ElytraClient.java b/src/main/java/org/betterx/betterend/integration/trinkets/ElytraClient.java new file mode 100644 index 00000000..2cacb7d8 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/trinkets/ElytraClient.java @@ -0,0 +1,22 @@ +package org.betterx.betterend.integration.trinkets; + +import net.minecraft.world.item.ElytraItem; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.rendering.v1.LivingEntityFeatureRenderEvents; +import net.fabricmc.fabric.api.entity.event.v1.FabricElytraItem; + +import dev.emi.trinkets.api.TrinketsApi; + +@Environment(EnvType.CLIENT) +public class ElytraClient { + public static void register() { + LivingEntityFeatureRenderEvents.ALLOW_CAPE_RENDER.register((player) -> TrinketsApi + .getTrinketComponent(player) + .map(trinketComponent -> trinketComponent.getEquipped( + stack -> stack.getItem() instanceof ElytraItem || + stack.getItem() instanceof FabricElytraItem + ).size() == 0).orElse(true)); + } +} diff --git a/src/main/java/org/betterx/betterend/interfaces/BETargetChecker.java b/src/main/java/org/betterx/betterend/interfaces/BETargetChecker.java new file mode 100644 index 00000000..8735ca5a --- /dev/null +++ b/src/main/java/org/betterx/betterend/interfaces/BETargetChecker.java @@ -0,0 +1,6 @@ +package org.betterx.betterend.interfaces; + +public interface BETargetChecker { + boolean be_isTarget(); + void be_setTarget(boolean target); +} diff --git a/src/main/java/org/betterx/betterend/interfaces/BetterEndElytra.java b/src/main/java/org/betterx/betterend/interfaces/BetterEndElytra.java new file mode 100644 index 00000000..c7d818b5 --- /dev/null +++ b/src/main/java/org/betterx/betterend/interfaces/BetterEndElytra.java @@ -0,0 +1,9 @@ +package org.betterx.betterend.interfaces; + +import org.betterx.bclib.items.elytra.BCLElytraItem; + +import net.minecraft.resources.ResourceLocation; + +public interface BetterEndElytra extends BCLElytraItem { + ResourceLocation getModelTexture(); +} diff --git a/src/main/java/org/betterx/betterend/interfaces/ISlime.java b/src/main/java/org/betterx/betterend/interfaces/ISlime.java new file mode 100644 index 00000000..23834d2f --- /dev/null +++ b/src/main/java/org/betterx/betterend/interfaces/ISlime.java @@ -0,0 +1,9 @@ +package org.betterx.betterend.interfaces; + +import net.minecraft.world.entity.Entity; + +public interface ISlime { + void be_setSlimeSize(int size, boolean heal); + + void entityRemove(Entity.RemovalReason removalReason); +} diff --git a/src/main/java/ru/betterend/interfaces/MobEffectApplier.java b/src/main/java/org/betterx/betterend/interfaces/MobEffectApplier.java similarity index 51% rename from src/main/java/ru/betterend/interfaces/MobEffectApplier.java rename to src/main/java/org/betterx/betterend/interfaces/MobEffectApplier.java index 7aee65f6..41b90dce 100644 --- a/src/main/java/ru/betterend/interfaces/MobEffectApplier.java +++ b/src/main/java/org/betterx/betterend/interfaces/MobEffectApplier.java @@ -1,7 +1,7 @@ -package ru.betterend.interfaces; +package org.betterx.betterend.interfaces; import net.minecraft.world.entity.LivingEntity; public interface MobEffectApplier { - void applyEffect(LivingEntity owner); + void applyEffect(LivingEntity owner); } diff --git a/src/main/java/org/betterx/betterend/interfaces/MultiModelItem.java b/src/main/java/org/betterx/betterend/interfaces/MultiModelItem.java new file mode 100644 index 00000000..360deb1f --- /dev/null +++ b/src/main/java/org/betterx/betterend/interfaces/MultiModelItem.java @@ -0,0 +1,19 @@ +package org.betterx.betterend.interfaces; + +import org.betterx.betterend.registry.EndItems; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public interface MultiModelItem { + @Environment(EnvType.CLIENT) + void registerModelPredicate(); + + static void register() { + EndItems.getModItems().forEach(item -> { + if (item instanceof MultiModelItem) { + ((MultiModelItem) item).registerModelPredicate(); + } + }); + } +} diff --git a/src/main/java/org/betterx/betterend/interfaces/PottablePlant.java b/src/main/java/org/betterx/betterend/interfaces/PottablePlant.java new file mode 100644 index 00000000..3756138d --- /dev/null +++ b/src/main/java/org/betterx/betterend/interfaces/PottablePlant.java @@ -0,0 +1,19 @@ +package org.betterx.betterend.interfaces; + +import net.minecraft.world.level.block.Block; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public interface PottablePlant { + boolean canPlantOn(Block block); + + default boolean canBePotted() { + return true; + } + + @Environment(EnvType.CLIENT) + default String getPottedState() { + return ""; + } +} diff --git a/src/main/java/org/betterx/betterend/interfaces/PottableTerrain.java b/src/main/java/org/betterx/betterend/interfaces/PottableTerrain.java new file mode 100644 index 00000000..e4bafe97 --- /dev/null +++ b/src/main/java/org/betterx/betterend/interfaces/PottableTerrain.java @@ -0,0 +1,7 @@ +package org.betterx.betterend.interfaces; + +public interface PottableTerrain { + default boolean canBePotted() { + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/interfaces/TeleportingEntity.java b/src/main/java/org/betterx/betterend/interfaces/TeleportingEntity.java new file mode 100644 index 00000000..d5c38f97 --- /dev/null +++ b/src/main/java/org/betterx/betterend/interfaces/TeleportingEntity.java @@ -0,0 +1,11 @@ +package org.betterx.betterend.interfaces; + +import net.minecraft.core.BlockPos; + +public interface TeleportingEntity { + void be_setExitPos(BlockPos pos); + + void be_resetExitPos(); + + boolean be_canTeleport(); +} diff --git a/src/main/java/org/betterx/betterend/item/ArmoredElytra.java b/src/main/java/org/betterx/betterend/item/ArmoredElytra.java new file mode 100644 index 00000000..ca942491 --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/ArmoredElytra.java @@ -0,0 +1,103 @@ +package org.betterx.betterend.item; + +import org.betterx.bclib.items.BaseArmorItem; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.interfaces.BetterEndElytra; +import org.betterx.betterend.interfaces.MultiModelItem; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.item.*; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.client.model.FabricModelPredicateProviderRegistry; + +public class ArmoredElytra extends BaseArmorItem implements MultiModelItem, BetterEndElytra { + private final ResourceLocation wingTexture; + private final Item repairItem; + private final double movementFactor; + private final float toughness; + private final int defense; + + public ArmoredElytra( + String name, + ArmorMaterial material, + Item repairItem, + int durability, + double movementFactor, + boolean fireproof + ) { + super( + material, + EquipmentSlot.CHEST, + fireproof ? EndItems + .makeEndItemSettings() + .durability(durability) + .rarity(Rarity.EPIC) + .fireResistant() : EndItems.makeEndItemSettings().durability(durability).rarity(Rarity.EPIC) + ); + this.wingTexture = BetterEnd.makeID("textures/entity/" + name + ".png"); + this.repairItem = repairItem; + this.movementFactor = movementFactor; + this.defense = (int) ((double) material.getDefenseForSlot(EquipmentSlot.CHEST) / 1.15); + this.toughness = material.getToughness() / 1.15F; + addAttributeModifier( + Attributes.ARMOR, + new AttributeModifier( + ARMOR_MODIFIER_UUID_PER_SLOT[2], + "Armor modifier", + defense, + AttributeModifier.Operation.ADDITION + ) + ); + addAttributeModifier( + Attributes.ARMOR_TOUGHNESS, + new AttributeModifier( + ARMOR_MODIFIER_UUID_PER_SLOT[2], + "Armor toughness", + toughness, + AttributeModifier.Operation.ADDITION + ) + ); + } + + @Override + public double getMovementFactor() { + return movementFactor; + } + + @Override + @Environment(EnvType.CLIENT) + public ResourceLocation getModelTexture() { + return wingTexture; + } + + @Override + public boolean isValidRepairItem(ItemStack itemStack, ItemStack itemStack2) { + return super.isValidRepairItem(itemStack, itemStack2) || itemStack2.getItem() == repairItem; + } + + @Override + public int getDefense() { + return defense; + } + + @Override + public float getToughness() { + return toughness; + } + + @Override + @Environment(EnvType.CLIENT) + public void registerModelPredicate() { + FabricModelPredicateProviderRegistry.register( + this, + new ResourceLocation("broken"), + (itemStack, clientLevel, livingEntity, id) -> ElytraItem.isFlyEnabled(itemStack) ? 0.0F : 1.0F + ); + } +} diff --git a/src/main/java/org/betterx/betterend/item/CrystaliteArmor.java b/src/main/java/org/betterx/betterend/item/CrystaliteArmor.java new file mode 100644 index 00000000..8e1df1ea --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/CrystaliteArmor.java @@ -0,0 +1,47 @@ +package org.betterx.betterend.item; + +import org.betterx.bclib.items.BaseArmorItem; +import org.betterx.betterend.effects.EndStatusEffects; +import org.betterx.betterend.item.material.EndArmorMaterial; + +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.Style; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; + +public class CrystaliteArmor extends BaseArmorItem { + + public final static MutableComponent CHEST_DESC; + public final static MutableComponent BOOTS_DESC; + + public CrystaliteArmor(EquipmentSlot equipmentSlot, Properties settings) { + super(EndArmorMaterial.CRYSTALITE, equipmentSlot, settings); + } + + public static boolean hasFullSet(LivingEntity owner) { + for (ItemStack armorStack : owner.getArmorSlots()) { + if (!(armorStack.getItem() instanceof CrystaliteArmor)) { + return false; + } + } + return true; + } + + public static void applySetEffect(LivingEntity owner) { + if ((owner.tickCount & 63) == 0) { + owner.addEffect(new MobEffectInstance(EndStatusEffects.CRYSTALITE_HEALTH_REGEN)); + } + } + + static { + Style descStyle = Style.EMPTY.applyFormats(ChatFormatting.DARK_AQUA, ChatFormatting.ITALIC); + CHEST_DESC = Component.translatable("tooltip.armor.crystalite_chest"); + CHEST_DESC.setStyle(descStyle); + BOOTS_DESC = Component.translatable("tooltip.armor.crystalite_boots"); + BOOTS_DESC.setStyle(descStyle); + } +} diff --git a/src/main/java/org/betterx/betterend/item/CrystaliteBoots.java b/src/main/java/org/betterx/betterend/item/CrystaliteBoots.java new file mode 100644 index 00000000..0b889317 --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/CrystaliteBoots.java @@ -0,0 +1,42 @@ +package org.betterx.betterend.item; + +import org.betterx.betterend.effects.EndStatusEffects; +import org.betterx.betterend.interfaces.MobEffectApplier; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.network.chat.Component; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Rarity; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import java.util.List; +import org.jetbrains.annotations.Nullable; + +public class CrystaliteBoots extends CrystaliteArmor implements MobEffectApplier { + + public CrystaliteBoots() { + super(EquipmentSlot.FEET, EndItems.makeEndItemSettings().rarity(Rarity.RARE)); + } + + @Override + public void applyEffect(LivingEntity owner) { + if ((owner.tickCount & 63) == 0) { + owner.addEffect(new MobEffectInstance(EndStatusEffects.CRYSTALITE_MOVE_SPEED)); + } + } + + @Override + @Environment(EnvType.CLIENT) + public void appendHoverText(ItemStack stack, @Nullable Level level, List lines, TooltipFlag tooltip) { + super.appendHoverText(stack, level, lines, tooltip); + lines.add(1, Component.empty()); + lines.add(2, BOOTS_DESC); + } +} diff --git a/src/main/java/org/betterx/betterend/item/CrystaliteChestplate.java b/src/main/java/org/betterx/betterend/item/CrystaliteChestplate.java new file mode 100644 index 00000000..ee8042af --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/CrystaliteChestplate.java @@ -0,0 +1,40 @@ +package org.betterx.betterend.item; + +import org.betterx.betterend.effects.EndStatusEffects; +import org.betterx.betterend.interfaces.MobEffectApplier; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.network.chat.Component; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Rarity; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import java.util.List; +import org.jetbrains.annotations.Nullable; + +public class CrystaliteChestplate extends CrystaliteArmor implements MobEffectApplier { + + public CrystaliteChestplate() { + super(EquipmentSlot.CHEST, EndItems.makeEndItemSettings().rarity(Rarity.RARE)); + } + + @Override + public void applyEffect(LivingEntity owner) { + owner.addEffect(new MobEffectInstance(EndStatusEffects.CRYSTALITE_DIG_SPEED)); + } + + @Override + @Environment(EnvType.CLIENT) + public void appendHoverText(ItemStack stack, @Nullable Level level, List lines, TooltipFlag tooltip) { + super.appendHoverText(stack, level, lines, tooltip); + lines.add(1, Component.empty()); + lines.add(2, CHEST_DESC); + } +} diff --git a/src/main/java/org/betterx/betterend/item/CrystaliteElytra.java b/src/main/java/org/betterx/betterend/item/CrystaliteElytra.java new file mode 100644 index 00000000..f16063bf --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/CrystaliteElytra.java @@ -0,0 +1,87 @@ +package org.betterx.betterend.item; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.interfaces.BetterEndElytra; +import org.betterx.betterend.interfaces.MultiModelItem; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.item.ElytraItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Rarity; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.client.model.FabricModelPredicateProviderRegistry; + +public class CrystaliteElytra extends CrystaliteArmor implements MultiModelItem, BetterEndElytra { + + private final ResourceLocation wingTexture; + private final double movementFactor; + private final int defense; + private final float toughness; + + public CrystaliteElytra(int durability, double movementFactor) { + super(EquipmentSlot.CHEST, EndItems.makeEndItemSettings().durability(durability).rarity(Rarity.EPIC)); + this.wingTexture = BetterEnd.makeID("textures/entity/elytra_crystalite.png"); + this.movementFactor = movementFactor; + this.defense = (int) ((double) material.getDefenseForSlot(EquipmentSlot.CHEST) / 1.25); + this.toughness = material.getToughness() / 1.25F; + addAttributeModifier( + Attributes.ARMOR, + new AttributeModifier( + ARMOR_MODIFIER_UUID_PER_SLOT[2], + "Armor modifier", + defense, + AttributeModifier.Operation.ADDITION + ) + ); + addAttributeModifier( + Attributes.ARMOR_TOUGHNESS, + new AttributeModifier( + ARMOR_MODIFIER_UUID_PER_SLOT[2], + "Armor toughness", + toughness, + AttributeModifier.Operation.ADDITION + ) + ); + } + + @Override + public boolean isValidRepairItem(ItemStack itemStack, ItemStack itemStack2) { + return super.isValidRepairItem(itemStack, itemStack2) || itemStack2.getItem() == EndItems.ENCHANTED_MEMBRANE; + } + + @Override + public double getMovementFactor() { + return movementFactor; + } + + @Override + @Environment(EnvType.CLIENT) + public ResourceLocation getModelTexture() { + return wingTexture; + } + + @Override + public int getDefense() { + return defense; + } + + @Override + public float getToughness() { + return toughness; + } + + @Override + public void registerModelPredicate() { + FabricModelPredicateProviderRegistry.register( + this, + new ResourceLocation("broken"), + (itemStack, clientLevel, livingEntity, i) -> ElytraItem.isFlyEnabled(itemStack) ? 0.0F : 1.0F + ); + } +} diff --git a/src/main/java/org/betterx/betterend/item/CrystaliteHelmet.java b/src/main/java/org/betterx/betterend/item/CrystaliteHelmet.java new file mode 100644 index 00000000..c7e28778 --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/CrystaliteHelmet.java @@ -0,0 +1,22 @@ +package org.betterx.betterend.item; + +import org.betterx.betterend.registry.EndAttributes; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.item.Rarity; + +import java.util.UUID; + +public class CrystaliteHelmet extends CrystaliteArmor { + + public CrystaliteHelmet() { + super(EquipmentSlot.HEAD, EndItems.makeEndItemSettings().rarity(Rarity.RARE)); + UUID uuid = ARMOR_MODIFIER_UUID_PER_SLOT[EquipmentSlot.HEAD.getIndex()]; + addAttributeModifier( + EndAttributes.BLINDNESS_RESISTANCE, + new AttributeModifier(uuid, "Helmet blindness resistance", 1.0, AttributeModifier.Operation.ADDITION) + ); + } +} diff --git a/src/main/java/org/betterx/betterend/item/CrystaliteLeggings.java b/src/main/java/org/betterx/betterend/item/CrystaliteLeggings.java new file mode 100644 index 00000000..005ab32b --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/CrystaliteLeggings.java @@ -0,0 +1,22 @@ +package org.betterx.betterend.item; + +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.item.Rarity; + +import java.util.UUID; + +public class CrystaliteLeggings extends CrystaliteArmor { + + public CrystaliteLeggings() { + super(EquipmentSlot.LEGS, EndItems.makeEndItemSettings().rarity(Rarity.RARE)); + UUID uuid = ARMOR_MODIFIER_UUID_PER_SLOT[EquipmentSlot.LEGS.getIndex()]; + addAttributeModifier( + Attributes.MAX_HEALTH, + new AttributeModifier(uuid, "Armor health boost", 4.0, AttributeModifier.Operation.ADDITION) + ); + } +} diff --git a/src/main/java/org/betterx/betterend/item/EnchantedItem.java b/src/main/java/org/betterx/betterend/item/EnchantedItem.java new file mode 100644 index 00000000..33ec8191 --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/EnchantedItem.java @@ -0,0 +1,37 @@ +package org.betterx.betterend.item; + +import org.betterx.bclib.client.models.ModelsHelper; +import org.betterx.bclib.items.ModelProviderItem; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Rarity; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class EnchantedItem extends ModelProviderItem { + + private final Item source; + + public EnchantedItem(Item source) { + super(EndItems.makeEndItemSettings().rarity(Rarity.RARE).stacksTo(16)); + this.source = source; + } + + @Override + public boolean isFoil(ItemStack stack) { + return true; + } + + @Override + @Environment(EnvType.CLIENT) + public BlockModel getItemModel(ResourceLocation resourceLocation) { + ResourceLocation sourceId = Registry.ITEM.getKey(source); + return ModelsHelper.createItemModel(sourceId); + } +} diff --git a/src/main/java/org/betterx/betterend/item/EndArmorItem.java b/src/main/java/org/betterx/betterend/item/EndArmorItem.java new file mode 100644 index 00000000..1147de7b --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/EndArmorItem.java @@ -0,0 +1,64 @@ +package org.betterx.betterend.item; + +import org.betterx.bclib.interfaces.ItemModelProvider; + +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.item.ArmorItem; +import net.minecraft.world.item.ArmorMaterial; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; + +import java.util.UUID; + +public class EndArmorItem extends ArmorItem implements ItemModelProvider { + + protected static final UUID[] ARMOR_MODIFIER_UUID_PER_SLOT = new UUID[]{ + UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"), + UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D"), + UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E"), + UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150") + }; + + protected final Multimap defaultModifiers; + + public EndArmorItem(ArmorMaterial material, EquipmentSlot equipmentSlot, Properties settings) { + super(material, equipmentSlot, settings); + this.defaultModifiers = HashMultimap.create(); + UUID uuid = ARMOR_MODIFIER_UUID_PER_SLOT[equipmentSlot.getIndex()]; + addAttributeModifier( + Attributes.ARMOR, + new AttributeModifier(uuid, "Armor modifier", getDefense(), AttributeModifier.Operation.ADDITION) + ); + addAttributeModifier( + Attributes.ARMOR_TOUGHNESS, + new AttributeModifier(uuid, "Armor toughness", getToughness(), AttributeModifier.Operation.ADDITION) + ); + if (knockbackResistance > 0.0F) { + addAttributeModifier( + Attributes.KNOCKBACK_RESISTANCE, + new AttributeModifier( + uuid, + "Armor knockback resistance", + knockbackResistance, + AttributeModifier.Operation.ADDITION + ) + ); + } + } + + @Override + public Multimap getDefaultAttributeModifiers(EquipmentSlot equipmentSlot) { + return equipmentSlot == slot ? defaultModifiers : super.getDefaultAttributeModifiers(equipmentSlot); + } + + protected void addAttributeModifier(Attribute attribute, AttributeModifier modifier) { + if (defaultModifiers.containsKey(attribute)) { + defaultModifiers.removeAll(attribute); + } + defaultModifiers.put(attribute, modifier); + } +} diff --git a/src/main/java/org/betterx/betterend/item/EndAttribute.java b/src/main/java/org/betterx/betterend/item/EndAttribute.java new file mode 100644 index 00000000..ff084d7c --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/EndAttribute.java @@ -0,0 +1,10 @@ +package org.betterx.betterend.item; + +import net.minecraft.world.entity.ai.attributes.Attribute; + +public class EndAttribute extends Attribute { + + public EndAttribute(String description, double value) { + super(description, value); + } +} diff --git a/src/main/java/org/betterx/betterend/item/EndBucketItem.java b/src/main/java/org/betterx/betterend/item/EndBucketItem.java new file mode 100644 index 00000000..ca873727 --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/EndBucketItem.java @@ -0,0 +1,15 @@ +package org.betterx.betterend.item; + +import org.betterx.bclib.interfaces.ItemModelProvider; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.MobBucketItem; +import net.minecraft.world.level.material.Fluids; + +public class EndBucketItem extends MobBucketItem implements ItemModelProvider { + public EndBucketItem(EntityType type) { + super(type, Fluids.WATER, SoundEvents.BUCKET_EMPTY, EndItems.makeEndItemSettings().stacksTo(1)); + } +} diff --git a/src/main/java/org/betterx/betterend/item/EternalCrystalItem.java b/src/main/java/org/betterx/betterend/item/EternalCrystalItem.java new file mode 100644 index 00000000..2385a398 --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/EternalCrystalItem.java @@ -0,0 +1,12 @@ +package org.betterx.betterend.item; + +import org.betterx.bclib.items.ModelProviderItem; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.world.item.Rarity; + +public class EternalCrystalItem extends ModelProviderItem { + public EternalCrystalItem() { + super(EndItems.makeEndItemSettings().stacksTo(16).rarity(Rarity.EPIC)); + } +} \ No newline at end of file diff --git a/src/main/java/ru/betterend/item/GuideBookItem.java b/src/main/java/org/betterx/betterend/item/GuideBookItem.java similarity index 62% rename from src/main/java/ru/betterend/item/GuideBookItem.java rename to src/main/java/org/betterx/betterend/item/GuideBookItem.java index 3e7348c4..6fe5b6f9 100644 --- a/src/main/java/ru/betterend/item/GuideBookItem.java +++ b/src/main/java/org/betterx/betterend/item/GuideBookItem.java @@ -1,45 +1,49 @@ -package ru.betterend.item; - -import java.util.List; - -import net.minecraft.ChatFormatting; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResultHolder; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.level.Level; -import ru.bclib.items.ModelProviderItem; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndItems; -import ru.betterend.util.LangUtil; -import vazkii.patchouli.api.PatchouliAPI; - -public class GuideBookItem extends ModelProviderItem { - public final static ResourceLocation BOOK_ID = BetterEnd.makeID("guidebook"); - public static final Item GUIDE_BOOK = EndItems.registerEndItem(BOOK_ID, new GuideBookItem()); - - public static void register() {} - - public GuideBookItem() { - super(EndItems.makeEndItemSettings().stacksTo(1)); - } - - @Override - public InteractionResultHolder use(Level world, Player user, InteractionHand hand) { - if (!world.isClientSide && user instanceof ServerPlayer) { - PatchouliAPI.get().openBookGUI((ServerPlayer) user, BOOK_ID); - return InteractionResultHolder.success(user.getItemInHand(hand)); - } - return InteractionResultHolder.consume(user.getItemInHand(hand)); - } - - @Override - public void appendHoverText(ItemStack stack, Level world, List tooltip, TooltipFlag context) { - tooltip.add(LangUtil.getText("book.betterend", "subtitle").withStyle(ChatFormatting.DARK_PURPLE, ChatFormatting.ITALIC)); - } -} +package org.betterx.betterend.item; + +import org.betterx.bclib.items.ModelProviderItem; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndItems; +import org.betterx.betterend.util.LangUtil; + +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; + +import vazkii.patchouli.api.PatchouliAPI; + +import java.util.List; + +public class GuideBookItem extends ModelProviderItem { + public final static ResourceLocation BOOK_ID = BetterEnd.makeID("guidebook"); + public static final Item GUIDE_BOOK = EndItems.getItemRegistry().register(BOOK_ID, new GuideBookItem()); + + public static void register() { + } + + public GuideBookItem() { + super(EndItems.makeEndItemSettings().stacksTo(1)); + } + + @Override + public InteractionResultHolder use(Level world, Player user, InteractionHand hand) { + if (!world.isClientSide && user instanceof ServerPlayer) { + PatchouliAPI.get().openBookGUI((ServerPlayer) user, BOOK_ID); + return InteractionResultHolder.success(user.getItemInHand(hand)); + } + return InteractionResultHolder.consume(user.getItemInHand(hand)); + } + + @Override + public void appendHoverText(ItemStack stack, Level world, List tooltip, TooltipFlag context) { + tooltip.add(LangUtil.getText("book.betterend", "subtitle") + .withStyle(ChatFormatting.DARK_PURPLE, ChatFormatting.ITALIC)); + } +} diff --git a/src/main/java/org/betterx/betterend/item/material/EndArmorMaterial.java b/src/main/java/org/betterx/betterend/item/material/EndArmorMaterial.java new file mode 100644 index 00000000..e5a0206f --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/material/EndArmorMaterial.java @@ -0,0 +1,98 @@ +package org.betterx.betterend.item.material; + +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.LazyLoadedValue; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ArmorMaterial; +import net.minecraft.world.item.crafting.Ingredient; + +import java.util.function.Supplier; + +public enum EndArmorMaterial implements ArmorMaterial { + THALLASIUM("thallasium", 17, new int[]{1, 4, 5, 2}, 12, SoundEvents.ARMOR_EQUIP_IRON, 0.0F, 0.0F, () -> { + return Ingredient.of(EndBlocks.THALLASIUM.ingot); + }), TERMINITE("terminite", 26, new int[]{3, 6, 7, 3}, 14, SoundEvents.ARMOR_EQUIP_IRON, 1.0F, 0.05F, () -> { + return Ingredient.of(EndBlocks.TERMINITE.ingot); + }), AETERNIUM("aeternium", 40, new int[]{4, 7, 9, 4}, 18, SoundEvents.ARMOR_EQUIP_NETHERITE, 3.5F, 0.2F, () -> { + return Ingredient.of(EndItems.AETERNIUM_INGOT); + }), CRYSTALITE("crystalite", 30, new int[]{3, 6, 8, 3}, 24, SoundEvents.ARMOR_EQUIP_DIAMOND, 1.2F, 0.1F, () -> { + return Ingredient.of(EndBlocks.TERMINITE.ingot); + }); + + private static final int[] BASE_DURABILITY = new int[]{13, 15, 16, 11}; + private final String name; + private final int durabilityMultiplier; + private final int[] protectionAmounts; + private final int enchantability; + private final SoundEvent equipSound; + private final float toughness; + private final float knockbackResistance; + @SuppressWarnings("deprecation") + private final LazyLoadedValue repairIngredient; + + @SuppressWarnings("deprecation") + EndArmorMaterial( + String name, + int durabilityMultiplier, + int[] protectionAmounts, + int enchantability, + SoundEvent equipSound, + float toughness, + float knockbackResistance, + Supplier repairIngredient + ) { + this.name = name; + this.durabilityMultiplier = durabilityMultiplier; + this.protectionAmounts = protectionAmounts; + this.enchantability = enchantability; + this.equipSound = equipSound; + this.toughness = toughness; + this.knockbackResistance = knockbackResistance; + this.repairIngredient = new LazyLoadedValue<>(repairIngredient); + } + + @Override + public int getDurabilityForSlot(EquipmentSlot slot) { + return BASE_DURABILITY[slot.getIndex()] * this.durabilityMultiplier; + } + + @Override + public int getDefenseForSlot(EquipmentSlot slot) { + return this.protectionAmounts[slot.getIndex()]; + } + + @Override + public int getEnchantmentValue() { + return this.enchantability; + } + + @Override + public SoundEvent getEquipSound() { + return this.equipSound; + } + + @Override + public Ingredient getRepairIngredient() { + return this.repairIngredient.get(); + } + + @Override + public String getName() { + return this.name; + } + + @Override + public float getToughness() { + return this.toughness; + } + + @Override + public float getKnockbackResistance() { + return this.knockbackResistance; + } + +} diff --git a/src/main/java/org/betterx/betterend/item/material/EndToolMaterial.java b/src/main/java/org/betterx/betterend/item/material/EndToolMaterial.java new file mode 100644 index 00000000..0e8dcd15 --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/material/EndToolMaterial.java @@ -0,0 +1,77 @@ +package org.betterx.betterend.item.material; + +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.util.LazyLoadedValue; +import net.minecraft.world.item.Tier; +import net.minecraft.world.item.Tiers; +import net.minecraft.world.item.crafting.Ingredient; + +import java.util.function.Supplier; + +public enum EndToolMaterial implements Tier { + THALLASIUM(Tiers.IRON.getLevel(), 320, 7.0F, 1.5F, 12, () -> { + return Ingredient.of(EndBlocks.THALLASIUM.ingot); + }), TERMINITE(Tiers.DIAMOND.getLevel(), 1230, 8.5F, 3.0F, 14, () -> { + return Ingredient.of(EndBlocks.TERMINITE.ingot); + }), AETERNIUM(5, 2196, 10.0F, 4.5F, 18, () -> { + return Ingredient.of(EndItems.AETERNIUM_INGOT); + }); + + private final int durability; + private final float miningSpeed; + private final float attackDamage; + private final int miningLevel; + private final int enchantability; + @SuppressWarnings("deprecation") + private final LazyLoadedValue repairIngredient; + + @SuppressWarnings("deprecation") + EndToolMaterial( + int miningLevel, + int durability, + float miningSpeed, + float attackDamage, + int enchantability, + Supplier repairIngredient + ) { + this.durability = durability; + this.miningSpeed = miningSpeed; + this.attackDamage = attackDamage; + this.miningLevel = miningLevel; + this.enchantability = enchantability; + this.repairIngredient = new LazyLoadedValue<>(repairIngredient); + } + + @Override + public int getUses() { + return this.durability; + } + + @Override + public float getSpeed() { + return this.miningSpeed; + } + + @Override + public float getAttackDamageBonus() { + return this.attackDamage; + } + + @Override + public int getLevel() { + return this.miningLevel; + } + + @Override + public int getEnchantmentValue() { + return this.enchantability; + } + + @Override + public Ingredient getRepairIngredient() { + return this.repairIngredient.get(); + } + +} diff --git a/src/main/java/org/betterx/betterend/item/model/ArmoredElytraModel.java b/src/main/java/org/betterx/betterend/item/model/ArmoredElytraModel.java new file mode 100644 index 00000000..f287d145 --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/model/ArmoredElytraModel.java @@ -0,0 +1,95 @@ +package org.betterx.betterend.item.model; + +import net.minecraft.client.model.AgeableListModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartNames; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.client.player.AbstractClientPlayer; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.phys.Vec3; + +import com.google.common.collect.ImmutableList; + +public class ArmoredElytraModel extends AgeableListModel { + private final ModelPart rightWing; + private final ModelPart leftWing; + + public static LayerDefinition getTexturedModelData() { + MeshDefinition modelData = new MeshDefinition(); + PartDefinition modelPartData = modelData.getRoot(); + modelPartData.addOrReplaceChild( + PartNames.LEFT_WING, + CubeListBuilder.create().texOffs(22, 0).addBox(-10.0f, 0.0f, 0.0f, 10.0f, 20.0f, 2.0f), + PartPose.ZERO + ); + + modelPartData.addOrReplaceChild( + PartNames.RIGHT_WING, + CubeListBuilder.create().mirror().texOffs(22, 0).addBox(0.0f, 0.0f, 0.0f, 10.0f, 20.0f, 2.0f), + PartPose.ZERO + ); + + return LayerDefinition.create(modelData, 64, 32); + } + + public ArmoredElytraModel(ModelPart modelPart) { + leftWing = modelPart.getChild(PartNames.LEFT_WING); + rightWing = modelPart.getChild(PartNames.RIGHT_WING); + } + + protected Iterable headParts() { + return ImmutableList.of(); + } + + protected Iterable bodyParts() { + return ImmutableList.of(leftWing, rightWing); + } + + public void setupAnim(T livingEntity, float f, float g, float h, float i, float j) { + float rotX = 0.2617994F; + float rotZ = -0.2617994F; + float rotY = 0.0F; + float wingY = 0.0F; + if (livingEntity.isFallFlying()) { + float coef = 1.0F; + Vec3 vec3 = livingEntity.getDeltaMovement(); + if (vec3.y < 0.0D) { + Vec3 normalized = vec3.normalize(); + coef = 1.0F - (float) Math.pow(-normalized.y, 2.5D); + } + rotX = coef * 0.34906584F + (1.0F - coef) * rotX; + rotZ = coef * -1.5707964F + (1.0F - coef) * rotZ; + } else if (livingEntity.isCrouching()) { + rotX = 0.6981317F; + rotZ = -0.7853982F; + rotY = 0.08726646F; + wingY = 3.0F; + } + + leftWing.x = 5.0F; + leftWing.y = wingY; + if (livingEntity instanceof AbstractClientPlayer) { + AbstractClientPlayer abstractClientPlayer = (AbstractClientPlayer) livingEntity; + abstractClientPlayer.elytraRotX = (float) ((double) abstractClientPlayer.elytraRotX + (double) (rotX - abstractClientPlayer.elytraRotX) * 0.1D); + abstractClientPlayer.elytraRotY = (float) ((double) abstractClientPlayer.elytraRotY + (double) (rotY - abstractClientPlayer.elytraRotY) * 0.1D); + abstractClientPlayer.elytraRotZ = (float) ((double) abstractClientPlayer.elytraRotZ + (double) (rotZ - abstractClientPlayer.elytraRotZ) * 0.1D); + leftWing.xRot = abstractClientPlayer.elytraRotX; + leftWing.yRot = abstractClientPlayer.elytraRotY; + leftWing.zRot = abstractClientPlayer.elytraRotZ; + } else { + leftWing.xRot = rotX; + leftWing.zRot = rotZ; + leftWing.yRot = rotY; + } + + rightWing.x = -leftWing.x; + rightWing.yRot = -leftWing.yRot; + rightWing.y = leftWing.y; + rightWing.xRot = leftWing.xRot; + rightWing.zRot = -leftWing.zRot; + } +} diff --git a/src/main/java/org/betterx/betterend/item/model/CrystaliteArmorProvider.java b/src/main/java/org/betterx/betterend/item/model/CrystaliteArmorProvider.java new file mode 100644 index 00000000..dc24ec7a --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/model/CrystaliteArmorProvider.java @@ -0,0 +1,97 @@ +package org.betterx.betterend.item.model; + +import org.betterx.betterend.item.CrystaliteArmor; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.player.AbstractClientPlayer; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import com.google.common.collect.Lists; +import shadow.fabric.api.client.rendering.v1.ArmorRenderingRegistry; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Environment(EnvType.CLIENT) +public class CrystaliteArmorProvider implements ArmorRenderingRegistry.ModelProvider, ArmorRenderingRegistry.TextureProvider { + //TODO: find new registry + private final static ResourceLocation FIRST_LAYER = new ResourceLocation( + "textures/models/armor/crystalite_layer_1.png"); + private final static ResourceLocation SECOND_LAYER = new ResourceLocation( + "textures/models/armor/crystalite_layer_2.png"); + private final static CrystaliteHelmetModel HELMET_MODEL = CrystaliteHelmetModel.createModel(null); + private final static CrystaliteChestplateModel CHEST_MODEL = CrystaliteChestplateModel.createRegularModel(null); + private final static CrystaliteChestplateModel CHEST_MODEL_SLIM = CrystaliteChestplateModel.createThinModel(null); + private final static CrystaliteLeggingsModel LEGGINGS_MODEL = CrystaliteLeggingsModel.createModel(null); + private final static CrystaliteBootsModel BOOTS_MODEL = CrystaliteBootsModel.createModel(null); + + //@Override + public @NotNull ResourceLocation getArmorTexture( + LivingEntity entity, + ItemStack stack, + EquipmentSlot slot, + boolean secondLayer, + @Nullable String suffix, + ResourceLocation defaultTexture + ) { + if (!isStackValid(stack)) return defaultTexture; + if (secondLayer) return SECOND_LAYER; + return FIRST_LAYER; + } + + //@Override + public @NotNull HumanoidModel getArmorModel( + LivingEntity entity, + ItemStack stack, + EquipmentSlot slot, + HumanoidModel defaultModel + ) { + if (!isStackValid(stack)) return defaultModel; + switch (slot) { + case HEAD: { + return HELMET_MODEL; + } + case CHEST: { + if (entity instanceof AbstractClientPlayer && ((AbstractClientPlayer) entity).getModelName() + .equals("slim")) { + CHEST_MODEL_SLIM.copyPropertiesTo(defaultModel); + return CHEST_MODEL_SLIM; + } + CHEST_MODEL.copyPropertiesTo(defaultModel); + return CHEST_MODEL; + } + case LEGS: { + return LEGGINGS_MODEL; + } + case FEET: { + BOOTS_MODEL.copyPropertiesTo(defaultModel); + return BOOTS_MODEL; + } + default: { + return defaultModel; + } + } + } + + public Iterable getRenderedItems() { + return Lists.newArrayList( + EndItems.CRYSTALITE_HELMET, + EndItems.CRYSTALITE_CHESTPLATE, + EndItems.CRYSTALITE_ELYTRA, + EndItems.CRYSTALITE_LEGGINGS, + EndItems.CRYSTALITE_BOOTS + ); + } + + private boolean isStackValid(ItemStack stack) { + return stack.getItem() instanceof CrystaliteArmor; + } +} diff --git a/src/main/java/org/betterx/betterend/item/model/CrystaliteBootsModel.java b/src/main/java/org/betterx/betterend/item/model/CrystaliteBootsModel.java new file mode 100644 index 00000000..3b95678f --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/model/CrystaliteBootsModel.java @@ -0,0 +1,84 @@ +package org.betterx.betterend.item.model; + +import org.betterx.betterend.registry.EndEntitiesRenders; + +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.model.geom.EntityModelSet; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.*; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.world.entity.LivingEntity; + +import com.google.common.collect.Lists; + +import java.util.Collections; + +public class CrystaliteBootsModel extends HumanoidModel { + + public ModelPart leftBoot; + public ModelPart rightBoot; + + public static LayerDefinition getTexturedModelData() { + final float scale = 1.0f; + MeshDefinition modelData = new MeshDefinition(); + PartDefinition modelPartData = modelData.getRoot(); + + // TODO: see if we need to subclass HumanoidModel + // Humanoid model tries to retrieve all parts in it's constructor, + // so we need to add empty Nodes + modelPartData.addOrReplaceChild("head", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("hat", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("body", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("right_arm", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("left_arm", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("right_leg", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("left_leg", CubeListBuilder.create(), PartPose.ZERO); + + CubeDeformation deformation = new CubeDeformation(scale + 0.25f); + modelPartData.addOrReplaceChild( + "leftBoot", + CubeListBuilder.create().texOffs(0, 32).addBox(-2.0f, 0.0f, -2.0f, 4.0f, 12.0f, 4.0f, deformation), + PartPose.offset(1.9f, 12.0f, 0.0f) + ); + + modelPartData.addOrReplaceChild( + "rightBoot", + CubeListBuilder.create().texOffs(0, 16).addBox(-2.0f, 0.0f, -2.0f, 4.0f, 12.0f, 4.0f, deformation), + PartPose.offset(-1.9f, 12.0f, 0.0f) + ); + + return LayerDefinition.create(modelData, 64, 48); + } + + public static CrystaliteBootsModel createModel(EntityModelSet entityModelSet) { + return new CrystaliteBootsModel(entityModelSet == null + ? getTexturedModelData().bakeRoot() + : entityModelSet.bakeLayer( + EndEntitiesRenders.CRYSTALITE_BOOTS)); + } + + public CrystaliteBootsModel(ModelPart modelPart) { + super(modelPart, RenderType::entityTranslucent); + + leftBoot = modelPart.getChild("leftBoot"); + rightBoot = modelPart.getChild("rightBoot"); + } + + @Override + public void copyPropertiesTo(HumanoidModel bipedEntityModel) { + super.copyPropertiesTo(bipedEntityModel); + this.leftBoot.copyFrom(leftLeg); + this.rightBoot.copyFrom(rightLeg); + } + + @Override + protected Iterable headParts() { + return Collections::emptyIterator; + } + + @Override + protected Iterable bodyParts() { + return Lists.newArrayList(leftBoot, rightBoot); + } +} diff --git a/src/main/java/org/betterx/betterend/item/model/CrystaliteChestplateModel.java b/src/main/java/org/betterx/betterend/item/model/CrystaliteChestplateModel.java new file mode 100644 index 00000000..a32f2dcf --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/model/CrystaliteChestplateModel.java @@ -0,0 +1,155 @@ +package org.betterx.betterend.item.model; + +import org.betterx.betterend.registry.EndEntitiesRenders; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.model.geom.EntityModelSet; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartNames; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.*; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.world.entity.HumanoidArm; +import net.minecraft.world.entity.LivingEntity; + +import com.google.common.collect.Lists; + +import java.util.Collections; + +public class CrystaliteChestplateModel extends HumanoidModel { + + public ModelPart leftShoulder; + public ModelPart rightShoulder; + private final boolean thinArms; + + public static LayerDefinition getRegularTexturedModelData() { + return getTexturedModelData(1.0f, false); + } + + public static LayerDefinition getThinTexturedModelData() { + return getTexturedModelData(1.0f, true); + } + + private static LayerDefinition getTexturedModelData(float scale, boolean thinArms) { + MeshDefinition modelData = new MeshDefinition(); + PartDefinition modelPartData = modelData.getRoot(); + + // TODO: see if we need to subclass HumanoidModel + // Humanoid model tries to retrieve all parts in it's constructor, + // so we need to add empty Nodes + modelPartData.addOrReplaceChild("head", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("hat", CubeListBuilder.create(), PartPose.ZERO); + // modelPartData.addOrReplaceChild("body", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("right_arm", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("left_arm", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("right_leg", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("left_leg", CubeListBuilder.create(), PartPose.ZERO); + + CubeDeformation deformation = new CubeDeformation(scale + 0.25F); + PartDefinition body = modelPartData.addOrReplaceChild( + PartNames.BODY, + CubeListBuilder.create().texOffs(16, 16).addBox(-4.0f, 0.0f, -2.0f, 8.0f, 12.0f, 4.0f, deformation), + PartPose.ZERO + ); + + if (thinArms) { + deformation = new CubeDeformation(scale + 0.45F); + PartDefinition leftShoulder = modelPartData.addOrReplaceChild( + "leftShoulder", + CubeListBuilder.create() + .mirror() + .texOffs(40, 32) + .addBox(-1.0f, -2.5f, -2.0f, 4.0f, 12.0f, 4.0f, deformation), + PartPose.offset(5.0f, 2.0f, 0.0f) + ); + + PartDefinition rightShoulder = modelPartData.addOrReplaceChild( + "rightShoulder", + CubeListBuilder.create() + .texOffs(40, 16) + .addBox(-3.0f, -2.5f, -2.0f, 4.0f, 12.0f, 4.0f, deformation), + PartPose.offset(-5.0f, 2.0f, 10.0f) + ); + } else { + deformation = new CubeDeformation(scale + 0.45F); + PartDefinition leftShoulder = modelPartData.addOrReplaceChild( + "leftShoulder", + CubeListBuilder.create() + .mirror() + .texOffs(40, 32) + .addBox(-1.0f, -2.5f, -2.0f, 4.0f, 12.0f, 4.0f, deformation), + PartPose.offset(5.0f, 2.0f, 0.0f) + ); + + PartDefinition rightShoulder = modelPartData.addOrReplaceChild( + "rightShoulder", + CubeListBuilder.create() + .texOffs(40, 16) + .addBox(-3.0f, -2.5f, -2.0f, 4.0f, 12.0f, 4.0f, deformation), + PartPose.offset(-5.0f, 2.0f, 10.0f) + ); + } + return LayerDefinition.create(modelData, 64, 48); + } + + final ModelPart localBody; + + public static CrystaliteChestplateModel createRegularModel(EntityModelSet entityModelSet) { + return new CrystaliteChestplateModel( + entityModelSet == null + ? getRegularTexturedModelData().bakeRoot() + : entityModelSet + .bakeLayer(EndEntitiesRenders.CRYSTALITE_CHESTPLATE), + false + ); + } + + public static CrystaliteChestplateModel createThinModel(EntityModelSet entityModelSet) { + return new CrystaliteChestplateModel( + entityModelSet == null + ? getThinTexturedModelData().bakeRoot() + : entityModelSet + .bakeLayer(EndEntitiesRenders.CRYSTALITE_CHESTPLATE_THIN), + true + ); + } + + protected CrystaliteChestplateModel(ModelPart modelPart, boolean thinArms) { + super(modelPart, RenderType::entityTranslucent); + this.thinArms = thinArms; + localBody = modelPart.getChild(PartNames.BODY); + leftShoulder = modelPart.getChild("leftShoulder"); + rightShoulder = modelPart.getChild("rightShoulder"); + } + + @Override + public void copyPropertiesTo(HumanoidModel bipedEntityModel) { + super.copyPropertiesTo(bipedEntityModel); + this.leftShoulder.copyFrom(leftArm); + this.rightShoulder.copyFrom(rightArm); + } + + @Override + protected Iterable headParts() { + return Collections::emptyIterator; + } + + @Override + protected Iterable bodyParts() { + return Lists.newArrayList(localBody, leftShoulder, rightShoulder); + } + + @Override + public void translateToHand(HumanoidArm arm, PoseStack matrices) { + ModelPart modelPart = this.getArm(arm); + if (this.thinArms) { + float f = 0.5F * (float) (arm == HumanoidArm.RIGHT ? 1 : -1); + modelPart.x += f; + modelPart.translateAndRotate(matrices); + modelPart.x -= f; + } else { + modelPart.translateAndRotate(matrices); + } + } +} diff --git a/src/main/java/org/betterx/betterend/item/model/CrystaliteHelmetModel.java b/src/main/java/org/betterx/betterend/item/model/CrystaliteHelmetModel.java new file mode 100644 index 00000000..5001d78a --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/model/CrystaliteHelmetModel.java @@ -0,0 +1,74 @@ +package org.betterx.betterend.item.model; + +import org.betterx.betterend.registry.EndEntitiesRenders; + +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.model.geom.EntityModelSet; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartNames; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.*; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.world.entity.LivingEntity; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import com.google.common.collect.Lists; + +import java.util.Collections; + +@Environment(EnvType.CLIENT) +public class CrystaliteHelmetModel extends HumanoidModel { + final ModelPart myHat; + + public static LayerDefinition getTexturedModelData() { + final float scale = 1.0f; + MeshDefinition modelData = new MeshDefinition(); + PartDefinition modelPartData = modelData.getRoot(); + + // TODO: see if we need to subclass HumanoidModel + // Humanoid model tries to retrieve all parts in it's constructor, + // so we need to add empty Nodes + modelPartData.addOrReplaceChild("head", CubeListBuilder.create(), PartPose.ZERO); + //modelPartData.addOrReplaceChild("hat", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("body", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("right_arm", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("left_arm", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("right_leg", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("left_leg", CubeListBuilder.create(), PartPose.ZERO); + + CubeDeformation deformation_hat = new CubeDeformation(scale + 0.5f); + PartDefinition hat = modelPartData.addOrReplaceChild( + PartNames.HAT, + CubeListBuilder.create().texOffs(0, 0).addBox(-4.0f, -8.0f, -4.0f, 8.0f, 8.0f, 8.0f, deformation_hat), + PartPose.ZERO + ); + + return LayerDefinition.create(modelData, 64, 48); + } + + public static CrystaliteHelmetModel createModel(EntityModelSet entityModelSet) { + return new CrystaliteHelmetModel(entityModelSet == null + ? getTexturedModelData().bakeRoot() + : entityModelSet.bakeLayer( + EndEntitiesRenders.CRYSTALITE_HELMET)); + } + + + public CrystaliteHelmetModel(ModelPart modelPart) { + super(modelPart, RenderType::entityTranslucent); + + myHat = modelPart.getChild(PartNames.HAT); + } + + @Override + protected Iterable headParts() { + return Collections::emptyIterator; + } + + @Override + protected Iterable bodyParts() { + return Lists.newArrayList(myHat); + } +} diff --git a/src/main/java/org/betterx/betterend/item/model/CrystaliteLeggingsModel.java b/src/main/java/org/betterx/betterend/item/model/CrystaliteLeggingsModel.java new file mode 100644 index 00000000..6c2e2e2c --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/model/CrystaliteLeggingsModel.java @@ -0,0 +1,85 @@ +package org.betterx.betterend.item.model; + +import org.betterx.betterend.registry.EndEntitiesRenders; + +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.model.geom.EntityModelSet; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartNames; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.*; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.world.entity.LivingEntity; + +import com.google.common.collect.Lists; + +import java.util.Collections; + +public class CrystaliteLeggingsModel extends HumanoidModel { + public static LayerDefinition getTexturedModelData() { + float scale = 1.0f; + MeshDefinition modelData = new MeshDefinition(); + PartDefinition modelPartData = modelData.getRoot(); + + // TODO: see if we need to subclass HumanoidModel + // Humanoid model tries to retrieve all parts in it's constructor, + // so we need to add empty Nodes + modelPartData.addOrReplaceChild("head", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("hat", CubeListBuilder.create(), PartPose.ZERO); + // modelPartData.addOrReplaceChild("body", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("right_arm", CubeListBuilder.create(), PartPose.ZERO); + modelPartData.addOrReplaceChild("left_arm", CubeListBuilder.create(), PartPose.ZERO); + // modelPartData.addOrReplaceChild("right_leg", CubeListBuilder.create(), PartPose.ZERO); + // modelPartData.addOrReplaceChild("left_leg", CubeListBuilder.create(), PartPose.ZERO); + + CubeDeformation deformation = new CubeDeformation(scale); + modelPartData.addOrReplaceChild( + PartNames.BODY, + CubeListBuilder.create().texOffs(16, 16).addBox(-4.0f, 0.0f, -2.0f, 8.0f, 12.0f, 4.0f, deformation), + PartPose.ZERO + ); + + modelPartData.addOrReplaceChild( + PartNames.LEFT_LEG, + CubeListBuilder.create().texOffs(0, 32).addBox(-2.0f, 0.0f, -2.0f, 4.0f, 12.0f, 4.0f, deformation), + PartPose.offset(1.9f, 12.0f, 0.0f) + ); + + modelPartData.addOrReplaceChild( + PartNames.RIGHT_LEG, + CubeListBuilder.create().texOffs(0, 16).addBox(-2.0f, 0.0f, -2.0f, 4.0f, 12.0f, 4.0f, deformation), + PartPose.offset(-1.9f, 12.0f, 0.0f) + ); + + return LayerDefinition.create(modelData, 64, 48); + } + + final ModelPart myBody; + final ModelPart myLeftLeg; + final ModelPart myRightLeg; + + public static CrystaliteLeggingsModel createModel(EntityModelSet entityModelSet) { + return new CrystaliteLeggingsModel(entityModelSet == null + ? getTexturedModelData().bakeRoot() + : entityModelSet.bakeLayer( + EndEntitiesRenders.CRYSTALITE_LEGGINGS)); + } + + public CrystaliteLeggingsModel(ModelPart modelPart) { + super(modelPart, RenderType::entityTranslucent); + + myBody = modelPart.getChild(PartNames.BODY); + myLeftLeg = modelPart.getChild(PartNames.LEFT_LEG); + myRightLeg = modelPart.getChild(PartNames.RIGHT_LEG); + } + + @Override + protected Iterable headParts() { + return Collections::emptyIterator; + } + + @Override + protected Iterable bodyParts() { + return Lists.newArrayList(myBody, myRightLeg, myLeftLeg); + } +} diff --git a/src/main/java/org/betterx/betterend/item/tool/EndHammerItem.java b/src/main/java/org/betterx/betterend/item/tool/EndHammerItem.java new file mode 100644 index 00000000..7168a6e0 --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/tool/EndHammerItem.java @@ -0,0 +1,160 @@ +package org.betterx.betterend.item.tool; + +import org.betterx.bclib.client.models.ModelsHelper; +import org.betterx.bclib.interfaces.ItemModelProvider; +import org.betterx.bclib.interfaces.TagProvider; +import org.betterx.bclib.util.MHelper; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; +import org.betterx.worlds.together.tag.v3.CommonItemTags; + +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.DiggerItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Tier; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Material; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableMultimap.Builder; +import com.google.common.collect.Multimap; + +import java.util.List; +import java.util.UUID; + +public class EndHammerItem extends DiggerItem implements ItemModelProvider, TagProvider { + public final static UUID ATTACK_KNOCKBACK_MODIFIER_ID = Mth.createInsecureUUID(MHelper.RANDOM_SOURCE); + + private final Multimap attributeModifiers; + + public EndHammerItem(Tier material, float attackDamage, float attackSpeed, double knockback, Properties settings) { + super(attackDamage, attackSpeed, material, CommonBlockTags.MINABLE_WITH_HAMMER, settings); + + Builder builder = ImmutableMultimap.builder(); + builder.put( + Attributes.ATTACK_DAMAGE, + new AttributeModifier( + BASE_ATTACK_DAMAGE_UUID, + "Weapon modifier", + attackDamage + material.getAttackDamageBonus(), + AttributeModifier.Operation.ADDITION + ) + ); + builder.put( + Attributes.ATTACK_SPEED, + new AttributeModifier( + BASE_ATTACK_SPEED_UUID, + "Weapon modifier", + attackSpeed, + AttributeModifier.Operation.ADDITION + ) + ); + builder.put( + Attributes.ATTACK_KNOCKBACK, + new AttributeModifier( + ATTACK_KNOCKBACK_MODIFIER_ID, + "Weapon modifier", + knockback, + AttributeModifier.Operation.ADDITION + ) + ); + this.attributeModifiers = builder.build(); + } + + @Override + public boolean canAttackBlock(BlockState state, Level world, BlockPos pos, Player miner) { + return state.getMaterial().equals(Material.STONE) || state.getMaterial().equals(Material.GLASS) || state.is( + Blocks.DIAMOND_BLOCK) || state.is(Blocks.EMERALD_BLOCK) || state.is(Blocks.LAPIS_BLOCK) || state.is( + Blocks.REDSTONE_BLOCK); + } + + @Override + public boolean hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) { + stack.hurtAndBreak(1, attacker, ((entity) -> entity.broadcastBreakEvent(EquipmentSlot.MAINHAND))); + + return true; + } + + @Override + public boolean mineBlock(ItemStack stack, Level world, BlockState state, BlockPos pos, LivingEntity miner) { + if (state.getDestroySpeed(world, pos) != 0.0F) { + stack.hurtAndBreak(1, miner, ((entity) -> entity.broadcastBreakEvent(EquipmentSlot.MAINHAND))); + } + + return true; + } + + @Override + public float getDestroySpeed(ItemStack stack, BlockState state) { + if (state.getMaterial().equals(Material.GLASS)) { + return this.getTier().getSpeed() * 2.0F; + } + if (isCorrectToolForDrops(state)) { + float mult; + if (state.is(Blocks.DIAMOND_BLOCK) || state.is(Blocks.EMERALD_BLOCK) || state.is(Blocks.LAPIS_BLOCK) || state + .is(Blocks.REDSTONE_BLOCK)) { + mult = this.getTier().getSpeed(); + } else { + mult = this.getTier().getSpeed() / 2.0F; + } + return Math.max(mult, 1.0F); + } + return 1.0F; + } + + @Override + public boolean isCorrectToolForDrops(BlockState state) { + if (state.getMaterial().equals(Material.GLASS)) { + return true; + } + if (!state.is(Blocks.REDSTONE_BLOCK) && !state.is(Blocks.DIAMOND_BLOCK) && !state.is(Blocks.EMERALD_BLOCK) && !state + .is(Blocks.LAPIS_BLOCK) && !state.getMaterial().equals(Material.STONE)) { + return false; + } + int level = this.getTier().getLevel(); + if (state.is(Blocks.IRON_ORE) || state.is(Blocks.LAPIS_BLOCK) || state.is(Blocks.LAPIS_ORE)) { + return level >= 1; + } + if (state.is(Blocks.DIAMOND_BLOCK) && !state.is(Blocks.DIAMOND_ORE) || state.is(Blocks.EMERALD_ORE) || state.is( + Blocks.EMERALD_BLOCK) || state.is(Blocks.GOLD_ORE) || state.is(Blocks.REDSTONE_ORE)) { + return level >= 2; + } + if (state.is(Blocks.OBSIDIAN) || state.is(Blocks.CRYING_OBSIDIAN) || state.is(Blocks.RESPAWN_ANCHOR) || state.is( + Blocks.ANCIENT_DEBRIS)) { + return level >= 3; + } + return true; + } + + @Override + public Multimap getDefaultAttributeModifiers(EquipmentSlot slot) { + return slot == EquipmentSlot.MAINHAND ? this.attributeModifiers : super.getDefaultAttributeModifiers(slot); + } + + @Override + @Environment(EnvType.CLIENT) + public BlockModel getItemModel(ResourceLocation resourceLocation) { + return ModelsHelper.createHandheldItem(resourceLocation); + } + + @Override + public void addTags(List> blockTags, List> itemTags) { + itemTags.add(CommonItemTags.HAMMERS); + } +} diff --git a/src/main/java/org/betterx/betterend/item/tool/EndPickaxe.java b/src/main/java/org/betterx/betterend/item/tool/EndPickaxe.java new file mode 100644 index 00000000..7ff99127 --- /dev/null +++ b/src/main/java/org/betterx/betterend/item/tool/EndPickaxe.java @@ -0,0 +1,22 @@ +package org.betterx.betterend.item.tool; + +import org.betterx.bclib.items.tool.BasePickaxeItem; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Tier; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +public class EndPickaxe extends BasePickaxeItem { + public EndPickaxe(Tier material, int attackDamage, float attackSpeed, Properties settings) { + super(material, attackDamage, attackSpeed, settings); + } + + @Override + public float getDestroySpeed(ItemStack stack, BlockState state) { + if (state.is(Blocks.END_STONE) && this.getTier().getLevel() > 2) { + return this.speed * 3; + } + return super.getDestroySpeed(stack, state); + } +} diff --git a/src/main/java/ru/betterend/mixin/client/AbstractSoundInstanceAccessor.java b/src/main/java/org/betterx/betterend/mixin/client/AbstractSoundInstanceAccessor.java similarity index 70% rename from src/main/java/ru/betterend/mixin/client/AbstractSoundInstanceAccessor.java rename to src/main/java/org/betterx/betterend/mixin/client/AbstractSoundInstanceAccessor.java index 296a013e..81476c74 100644 --- a/src/main/java/ru/betterend/mixin/client/AbstractSoundInstanceAccessor.java +++ b/src/main/java/org/betterx/betterend/mixin/client/AbstractSoundInstanceAccessor.java @@ -1,12 +1,12 @@ -package ru.betterend.mixin.client; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import net.minecraft.client.resources.sounds.AbstractSoundInstance; - -@Mixin(AbstractSoundInstance.class) -public interface AbstractSoundInstanceAccessor { - @Accessor("volume") - void setVolume(float volume); -} +package org.betterx.betterend.mixin.client; + +import net.minecraft.client.resources.sounds.AbstractSoundInstance; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(AbstractSoundInstance.class) +public interface AbstractSoundInstanceAccessor { + @Accessor("volume") + void setVolume(float volume); +} diff --git a/src/main/java/org/betterx/betterend/mixin/client/ArmorStandRendererMixin.java b/src/main/java/org/betterx/betterend/mixin/client/ArmorStandRendererMixin.java new file mode 100644 index 00000000..67e267e4 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/client/ArmorStandRendererMixin.java @@ -0,0 +1,27 @@ +package org.betterx.betterend.mixin.client; + +import org.betterx.betterend.client.render.ArmoredElytraLayer; + +import net.minecraft.client.model.ArmorStandArmorModel; +import net.minecraft.client.renderer.entity.ArmorStandRenderer; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.world.entity.decoration.ArmorStand; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ArmorStandRenderer.class) +public abstract class ArmorStandRendererMixin extends LivingEntityRenderer { + + public ArmorStandRendererMixin(EntityRendererProvider.Context context, ArmorStandArmorModel entityModel, float f) { + super(context, entityModel, f); + } + + @Inject(method = "*", at = @At("TAIL")) + public void be_addCustomLayer(EntityRendererProvider.Context context, CallbackInfo ci) { + addLayer(new ArmoredElytraLayer<>(this, context.getModelSet())); + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/client/BiomeColorsMixin.java b/src/main/java/org/betterx/betterend/mixin/client/BiomeColorsMixin.java new file mode 100644 index 00000000..68b454b8 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/client/BiomeColorsMixin.java @@ -0,0 +1,63 @@ +package org.betterx.betterend.mixin.client; + +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.client.ClientOptions; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.ui.ColorUtil; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BiomeColors; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.world.level.BlockAndTintGetter; + +import net.fabricmc.loader.api.FabricLoader; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.awt.*; +import java.util.Arrays; +import java.util.Comparator; + +@Mixin(BiomeColors.class) +public class BiomeColorsMixin { + private static final int POISON_COLOR = ColorUtil.color(92, 160, 78); + private static final int STREAM_COLOR = ColorUtil.color(105, 213, 244); + private static final Point[] OFFSETS; + private static final boolean HAS_SODIUM; + + @Inject(method = "getAverageWaterColor", at = @At("RETURN"), cancellable = true) + private static void be_getWaterColor(BlockAndTintGetter world, BlockPos pos, CallbackInfoReturnable info) { + if (ClientOptions.useSulfurWaterColor()) { + BlockAndTintGetter view = HAS_SODIUM ? Minecraft.getInstance().level : world; + MutableBlockPos mut = new MutableBlockPos(); + mut.setY(pos.getY()); + for (int i = 0; i < OFFSETS.length; i++) { + mut.setX(pos.getX() + OFFSETS[i].x); + mut.setZ(pos.getZ() + OFFSETS[i].y); + if ((view.getBlockState(mut).is(EndBlocks.BRIMSTONE))) { + info.setReturnValue(i < 4 ? POISON_COLOR : STREAM_COLOR); + return; + } + } + } + } + + static { + HAS_SODIUM = FabricLoader.getInstance().isModLoaded("sodium"); + + int index = 0; + OFFSETS = new Point[20]; + for (int x = -2; x < 3; x++) { + for (int z = -2; z < 3; z++) { + if ((x != 0 || z != 0) && (Math.abs(x) != 2 || Math.abs(z) != 2)) { + OFFSETS[index++] = new Point(x, z); + } + } + } + Arrays.sort(OFFSETS, Comparator.comparingInt(pos -> MHelper.sqr(pos.x) + MHelper.sqr(pos.y))); + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/client/CapeLayerMixin.java b/src/main/java/org/betterx/betterend/mixin/client/CapeLayerMixin.java new file mode 100644 index 00000000..08a09fb7 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/client/CapeLayerMixin.java @@ -0,0 +1,39 @@ +package org.betterx.betterend.mixin.client; + +import org.betterx.betterend.item.ArmoredElytra; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.player.AbstractClientPlayer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.layers.CapeLayer; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(CapeLayer.class) +public class CapeLayerMixin { + + @Inject(method = "render", at = @At("HEAD"), cancellable = true) + public void be_checkCustomElytra( + PoseStack poseStack, + MultiBufferSource multiBufferSource, + int i, + AbstractClientPlayer abstractClientPlayer, + float f, + float g, + float h, + float j, + float k, + float l, + CallbackInfo info + ) { + ItemStack itemStack = abstractClientPlayer.getItemBySlot(EquipmentSlot.CHEST); + if (itemStack.getItem() instanceof ArmoredElytra) { + info.cancel(); + } + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/client/HumanoidMobRendererMixin.java b/src/main/java/org/betterx/betterend/mixin/client/HumanoidMobRendererMixin.java new file mode 100644 index 00000000..c509585b --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/client/HumanoidMobRendererMixin.java @@ -0,0 +1,35 @@ +package org.betterx.betterend.mixin.client; + +import org.betterx.betterend.client.render.ArmoredElytraLayer; + +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.HumanoidMobRenderer; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.world.entity.Mob; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(HumanoidMobRenderer.class) +public abstract class HumanoidMobRendererMixin> extends MobRenderer { + + public HumanoidMobRendererMixin(EntityRendererProvider.Context context, M entityModel, float f) { + super(context, entityModel, f); + } + + @Inject(method = "(Lnet/minecraft/client/renderer/entity/EntityRendererProvider$Context;Lnet/minecraft/client/model/HumanoidModel;FFFF)V", at = @At("TAIL")) + public void be_addCustomLayer( + EntityRendererProvider.Context context, + M humanoidModel, + float f, + float g, + float h, + float i, + CallbackInfo ci + ) { + addLayer(new ArmoredElytraLayer<>(this, context.getModelSet())); + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/client/ItemStackMixin.java b/src/main/java/org/betterx/betterend/mixin/client/ItemStackMixin.java new file mode 100644 index 00000000..f43b7fc8 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/client/ItemStackMixin.java @@ -0,0 +1,28 @@ +package org.betterx.betterend.mixin.client; + +import org.betterx.betterend.events.ItemTooltipCallback; + +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.List; + +@Mixin(ItemStack.class) +public class ItemStackMixin { + @Inject(method = "getTooltipLines", at = @At("RETURN")) + private void be_getTooltip( + Player entity, + TooltipFlag tooltipContext, + CallbackInfoReturnable> info + ) { + ItemTooltipCallback.EVENT.invoker() + .getTooltip(entity, ItemStack.class.cast(this), tooltipContext, info.getReturnValue()); + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/client/MinecraftClientMixin.java b/src/main/java/org/betterx/betterend/mixin/client/MinecraftClientMixin.java new file mode 100644 index 00000000..62cb5fe5 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/client/MinecraftClientMixin.java @@ -0,0 +1,58 @@ +package org.betterx.betterend.mixin.client; + +import org.betterx.bclib.util.MHelper; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.WinScreen; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.sounds.Music; +import net.minecraft.sounds.Musics; +import net.minecraft.world.level.Level; + +import org.spongepowered.asm.mixin.Final; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Minecraft.class) +public class MinecraftClientMixin { + @Shadow + public LocalPlayer player; + + @Shadow + public Screen screen; + + @Final + @Shadow + public Gui gui; + + @Shadow + public ClientLevel level; + + @Inject(method = "getSituationalMusic", at = @At("HEAD"), cancellable = true) + private void be_getEndMusic(CallbackInfoReturnable info) { + if (!(this.screen instanceof WinScreen) && this.player != null) { + if (this.player.level.dimension() == Level.END) { + if (this.gui.getBossOverlay().shouldPlayMusic() && MHelper.lengthSqr( + this.player.getX(), + this.player.getZ() + ) < 250000) { + info.setReturnValue(Musics.END_BOSS); + } else { + Music sound = this.level.getBiomeManager() + .getNoiseBiomeAtPosition(this.player.blockPosition()) + .value() + .getBackgroundMusic() + .orElse(Musics.END); + info.setReturnValue(sound); + } + info.cancel(); + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/client/ModelLoaderMixin.java b/src/main/java/org/betterx/betterend/mixin/client/ModelLoaderMixin.java new file mode 100644 index 00000000..29a8bcf6 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/client/ModelLoaderMixin.java @@ -0,0 +1,39 @@ +package org.betterx.betterend.mixin.client; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.world.generator.GeneratorOptions; + +import net.minecraft.client.resources.model.ModelBakery; +import net.minecraft.resources.ResourceLocation; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +@Mixin(ModelBakery.class) +public abstract class ModelLoaderMixin { + @ModifyArg(method = "loadModel", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/packs/resources/ResourceManager;getResourceStack(Lnet/minecraft/resources/ResourceLocation;)Ljava/util/List;")) + public ResourceLocation be_switchModelOnLoad(ResourceLocation loc) { + if (GeneratorOptions.changeChorusPlant() && be_changeModel(loc)) { + String path = loc.getPath().replace("chorus", "custom_chorus"); + return BetterEnd.makeID(path); + } + return loc; + } + +// @ModifyVariable(method = "loadModel", ordinal = 2, at = @At(value = "INVOKE")) +// public ResourceLocation be_switchModel(ResourceLocation id) { +// if (GeneratorOptions.changeChorusPlant() && be_changeModel(id)) { +// String path = id.getPath().replace("chorus", "custom_chorus"); +// id = BetterEnd.makeID(path); +// } +// return id; +// } + + private boolean be_changeModel(ResourceLocation id) { + return id.getNamespace().equals("minecraft") + && id.getPath().startsWith("blockstates/") + && id.getPath().contains("chorus") + && !id.getPath().contains("custom_"); + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/client/MusicTrackerMixin.java b/src/main/java/org/betterx/betterend/mixin/client/MusicTrackerMixin.java new file mode 100644 index 00000000..e2f5820b --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/client/MusicTrackerMixin.java @@ -0,0 +1,106 @@ +package org.betterx.betterend.mixin.client; + +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.betterend.client.ClientOptions; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.sounds.AbstractSoundInstance; +import net.minecraft.client.resources.sounds.SoundInstance; +import net.minecraft.client.sounds.MusicManager; +import net.minecraft.sounds.Music; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; + +import org.spongepowered.asm.mixin.Final; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(MusicManager.class) +public abstract class MusicTrackerMixin { + @Final + @Shadow + private Minecraft minecraft; + + @Final + @Shadow + private RandomSource random; + + @Shadow + private SoundInstance currentMusic; + + @Shadow + private int nextSongDelay; + + private static float volume = 1; + private static float srcVolume = 0; + private static long time; + + @Inject(method = "tick", at = @At("HEAD"), cancellable = true) + public void be_onTick(CallbackInfo info) { + if (ClientOptions.blendBiomeMusic()) { + Music musicSound = minecraft.getSituationalMusic(); + if (be_checkNullSound(musicSound) && volume > 0 && be_shouldChangeSound(musicSound) && be_isCorrectBiome()) { + if (volume > 0) { + if (srcVolume < 0) { + srcVolume = currentMusic.getVolume(); + } + if (currentMusic instanceof AbstractSoundInstance) { + ((AbstractSoundInstanceAccessor) currentMusic).setVolume(volume); + } + minecraft.getSoundManager() + .updateSourceVolume(currentMusic.getSource(), currentMusic.getVolume() * volume); + long t = System.currentTimeMillis(); + if (volume == 1 && time == 0) { + time = t; + } + float delta = (t - time) * 0.0005F; + time = t; + volume -= delta; + if (volume < 0) { + volume = 0; + } + } + if (volume == 0) { + volume = 1; + time = 0; + srcVolume = -1; + this.minecraft.getSoundManager().stop(this.currentMusic); + this.nextSongDelay = Mth.nextInt(this.random, 0, musicSound.getMinDelay() / 2); + this.currentMusic = null; + } + if (this.currentMusic == null && this.nextSongDelay-- <= 0) { + this.startPlaying(musicSound); + } + info.cancel(); + } else { + volume = 1; + } + } + } + + private boolean be_isCorrectBiome() { + if (minecraft.level == null) { + return false; + } + return BiomeAPI.getRenderBiome(minecraft.level.getBiome(minecraft.player.blockPosition()) + .value()) instanceof EndBiome; + } + + private boolean be_shouldChangeSound(Music musicSound) { + return currentMusic != null && !musicSound + .getEvent() + .getLocation() + .equals(this.currentMusic.getLocation()) && musicSound.replaceCurrentMusic(); + } + + private boolean be_checkNullSound(Music musicSound) { + return musicSound != null && musicSound.getEvent() != null; + } + + @Shadow + public abstract void startPlaying(Music type); +} diff --git a/src/main/java/org/betterx/betterend/mixin/client/PlayerRendererMixin.java b/src/main/java/org/betterx/betterend/mixin/client/PlayerRendererMixin.java new file mode 100644 index 00000000..ebbefc5f --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/client/PlayerRendererMixin.java @@ -0,0 +1,31 @@ +package org.betterx.betterend.mixin.client; + +import org.betterx.betterend.client.render.ArmoredElytraLayer; + +import net.minecraft.client.model.PlayerModel; +import net.minecraft.client.player.AbstractClientPlayer; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.client.renderer.entity.player.PlayerRenderer; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(PlayerRenderer.class) +public abstract class PlayerRendererMixin extends LivingEntityRenderer> { + + public PlayerRendererMixin( + EntityRendererProvider.Context context, + PlayerModel entityModel, + float f + ) { + super(context, entityModel, f); + } + + @Inject(method = "*", at = @At("TAIL")) + public void be_addCustomLayer(EntityRendererProvider.Context context, boolean bl, CallbackInfo ci) { + addLayer(new ArmoredElytraLayer<>(this, context.getModelSet())); + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/BlockBehaviourMixin.java b/src/main/java/org/betterx/betterend/mixin/common/BlockBehaviourMixin.java new file mode 100644 index 00000000..30df056f --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/BlockBehaviourMixin.java @@ -0,0 +1,52 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.item.tool.EndHammerItem; + +import net.minecraft.util.Mth; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; + +import com.google.common.collect.Lists; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.List; + +@Mixin(BlockBehaviour.class) +public abstract class BlockBehaviourMixin { + @Inject(method = "getDrops", at = @At("HEAD"), cancellable = true) + public void be_getDroppedStacks( + BlockState state, + LootContext.Builder builder, + CallbackInfoReturnable> info + ) { + if (state.is(Blocks.GLOWSTONE)) { + ItemStack tool = builder.getParameter(LootContextParams.TOOL); + if (tool != null && tool.getItem() instanceof EndHammerItem) { + int min = 3; + int max = 4; + int count = 0; + int fortune = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, tool); + if (fortune > 0) { + fortune /= Enchantments.BLOCK_FORTUNE.getMaxLevel(); + min = Mth.clamp(min + fortune, min, max); + if (min == max) { + info.setReturnValue(Lists.newArrayList(new ItemStack(Items.GLOWSTONE_DUST, max))); + } + } + count = MHelper.randRange(min, max, MHelper.RANDOM_SOURCE); + info.setReturnValue(Lists.newArrayList(new ItemStack(Items.GLOWSTONE_DUST, count))); + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/ChorusFlowerBlockMixin.java b/src/main/java/org/betterx/betterend/mixin/common/ChorusFlowerBlockMixin.java new file mode 100644 index 00000000..6a83bd02 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/ChorusFlowerBlockMixin.java @@ -0,0 +1,107 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.world.generator.GeneratorOptions; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.ChorusFlowerBlock; +import net.minecraft.world.level.block.ChorusPlantBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +import org.spongepowered.asm.mixin.Final; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(value = ChorusFlowerBlock.class, priority = 100) +public abstract class ChorusFlowerBlockMixin extends Block { + private static final VoxelShape SHAPE_FULL = Block.box(0, 0, 0, 16, 16, 16); + private static final VoxelShape SHAPE_HALF = Block.box(0, 0, 0, 16, 4, 16); + + public ChorusFlowerBlockMixin(Properties settings) { + super(settings); + } + + @Final + @Shadow + private ChorusPlantBlock plant; + + @Inject(method = "canSurvive", at = @At("HEAD"), cancellable = true) + private void be_canSurvive( + BlockState state, + LevelReader world, + BlockPos pos, + CallbackInfoReturnable info + ) { + if (world.getBlockState(pos.below()).is(EndBlocks.CHORUS_NYLIUM)) { + info.setReturnValue(true); + info.cancel(); + } + } + + @Inject(method = "randomTick", at = @At("HEAD"), cancellable = true) + private void be_randomTick( + BlockState state, + ServerLevel world, + BlockPos pos, + RandomSource random, + CallbackInfo info + ) { + if (world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES)) { + BlockPos up = pos.above(); + if (world.isEmptyBlock(up) && up.getY() < 256) { + int i = state.getValue(ChorusFlowerBlock.AGE); + if (i < 5) { + this.placeGrownFlower(world, up, i + 1); + BlocksHelper.setWithoutUpdate( + world, + pos, + plant.defaultBlockState() + .setValue(ChorusPlantBlock.UP, true) + .setValue(ChorusPlantBlock.DOWN, true) + ); + info.cancel(); + } + } + } + } + + @Shadow + private void placeGrownFlower(Level world, BlockPos pos, int age) { + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + if (GeneratorOptions.changeChorusPlant()) { + return state.getValue(ChorusFlowerBlock.AGE) == 5 ? SHAPE_HALF : SHAPE_FULL; + } else { + return super.getShape(state, world, pos, context); + } + } + + @Inject(method = "placeDeadFlower", at = @At("HEAD"), cancellable = true) + private void be_placeDeadFlower(Level world, BlockPos pos, CallbackInfo info) { + BlockState down = world.getBlockState(pos.below()); + if (down.is(Blocks.CHORUS_PLANT) || down.is(CommonBlockTags.GEN_END_STONES)) { + world.setBlock(pos, this.defaultBlockState().setValue(BlockStateProperties.AGE_5, 5), 2); + world.levelEvent(1034, pos, 0); + } + info.cancel(); + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/ChorusPlantBlockMixin.java b/src/main/java/org/betterx/betterend/mixin/common/ChorusPlantBlockMixin.java new file mode 100644 index 00000000..2e47bc30 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/ChorusPlantBlockMixin.java @@ -0,0 +1,83 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.ChorusPlantBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(value = ChorusPlantBlock.class, priority = 100) +public abstract class ChorusPlantBlockMixin extends Block { + public ChorusPlantBlockMixin(Properties settings) { + super(settings); + } + + @Inject(method = "getStateForPlacement(Lnet/minecraft/world/item/context/BlockPlaceContext;)Lnet/minecraft/world/level/block/state/BlockState;", at = @At("RETURN"), cancellable = true) + private void be_getStateForPlacement(BlockPlaceContext ctx, CallbackInfoReturnable info) { + BlockPos pos = ctx.getClickedPos(); + Level world = ctx.getLevel(); + BlockState plant = info.getReturnValue(); + if (ctx.canPlace() && plant.is(Blocks.CHORUS_PLANT) && world.getBlockState(pos.below()) + .is(CommonBlockTags.END_STONES)) { + info.setReturnValue(plant.setValue(BlockStateProperties.DOWN, true)); + } + } + + @Inject(method = "Lnet/minecraft/world/level/block/ChorusPlantBlock;getStateForPlacement" + "(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)" + "Lnet/minecraft/world/level/block/state/BlockState;", at = @At("RETURN"), cancellable = true) + private void be_getStateForPlacement( + BlockGetter blockGetter, + BlockPos blockPos, + CallbackInfoReturnable info + ) { + BlockState plant = info.getReturnValue(); + if (plant.is(Blocks.CHORUS_PLANT) && blockGetter.getBlockState(blockPos.below()) + .is(CommonBlockTags.END_STONES)) { + info.setReturnValue(plant.setValue(BlockStateProperties.DOWN, true)); + } + } + + @Inject(method = "canSurvive", at = @At("HEAD"), cancellable = true) + private void be_canSurvive( + BlockState state, + LevelReader world, + BlockPos pos, + CallbackInfoReturnable info + ) { + BlockState down = world.getBlockState(pos.below()); + if (down.is(EndBlocks.CHORUS_NYLIUM) || down.is(Blocks.END_STONE)) { + info.setReturnValue(true); + } + } + + @Inject(method = "updateShape", at = @At("RETURN"), cancellable = true) + private void be_updateShape( + BlockState state, + Direction direction, + BlockState newState, + LevelAccessor world, + BlockPos pos, + BlockPos posFrom, + CallbackInfoReturnable info + ) { + BlockState plant = info.getReturnValue(); + if (plant.is(Blocks.CHORUS_PLANT) && world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES)) { + plant = plant.setValue(BlockStateProperties.DOWN, true); + info.setReturnValue(plant); + } + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/ChorusPlantFeatureMixin.java b/src/main/java/org/betterx/betterend/mixin/common/ChorusPlantFeatureMixin.java new file mode 100644 index 00000000..99506fb2 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/ChorusPlantFeatureMixin.java @@ -0,0 +1,47 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.ChorusFlowerBlock; +import net.minecraft.world.level.block.PipeBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.ChorusPlantFeature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ChorusPlantFeature.class) +public class ChorusPlantFeatureMixin { + @Inject(method = "place", at = @At("HEAD"), cancellable = true) + private void be_place( + FeaturePlaceContext featureConfig, + CallbackInfoReturnable info + ) { + final RandomSource random = featureConfig.random(); + final BlockPos blockPos = featureConfig.origin(); + final WorldGenLevel structureWorldAccess = featureConfig.level(); + if (structureWorldAccess.isEmptyBlock(blockPos) && structureWorldAccess.getBlockState(blockPos.below()) + .is(EndBlocks.CHORUS_NYLIUM)) { + ChorusFlowerBlock.generatePlant(structureWorldAccess, blockPos, random, MHelper.randRange(8, 16, random)); + BlockState bottom = structureWorldAccess.getBlockState(blockPos); + if (bottom.is(Blocks.CHORUS_PLANT)) { + BlocksHelper.setWithoutUpdate( + structureWorldAccess, + blockPos, + bottom.setValue(PipeBlock.DOWN, true) + ); + } + info.setReturnValue(true); + } + } +} diff --git a/src/main/java/ru/betterend/mixin/common/CraftingMenuMixin.java b/src/main/java/org/betterx/betterend/mixin/common/CraftingMenuMixin.java similarity index 55% rename from src/main/java/ru/betterend/mixin/common/CraftingMenuMixin.java rename to src/main/java/org/betterx/betterend/mixin/common/CraftingMenuMixin.java index 11c7f94e..ee74d62b 100644 --- a/src/main/java/ru/betterend/mixin/common/CraftingMenuMixin.java +++ b/src/main/java/org/betterx/betterend/mixin/common/CraftingMenuMixin.java @@ -1,29 +1,29 @@ -package ru.betterend.mixin.common; - -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.ContainerLevelAccess; -import net.minecraft.world.inventory.CraftingMenu; -import net.minecraft.world.level.block.CraftingTableBlock; - -@Mixin(CraftingMenu.class) -public abstract class CraftingMenuMixin { - @Final - @Shadow - private ContainerLevelAccess access; - - @Inject(method = "stillValid", at = @At("HEAD"), cancellable = true) - private void be_stillValid(Player player, CallbackInfoReturnable info) { - if (access.evaluate((world, pos) -> { - return world.getBlockState(pos).getBlock() instanceof CraftingTableBlock; - }, true)) { - info.setReturnValue(true); - } - } -} +package org.betterx.betterend.mixin.common; + +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.inventory.CraftingMenu; +import net.minecraft.world.level.block.CraftingTableBlock; + +import org.spongepowered.asm.mixin.Final; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(CraftingMenu.class) +public abstract class CraftingMenuMixin { + @Final + @Shadow + private ContainerLevelAccess access; + + @Inject(method = "stillValid", at = @At("HEAD"), cancellable = true) + private void be_stillValid(Player player, CallbackInfoReturnable info) { + if (access.evaluate((world, pos) -> { + return world.getBlockState(pos).getBlock() instanceof CraftingTableBlock; + }, true)) { + info.setReturnValue(true); + } + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/EnchantmentMenuMixin.java b/src/main/java/org/betterx/betterend/mixin/common/EnchantmentMenuMixin.java new file mode 100644 index 00000000..910caa91 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/EnchantmentMenuMixin.java @@ -0,0 +1,148 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.Registry; +import net.minecraft.util.RandomSource; +import net.minecraft.world.Container; +import net.minecraft.world.inventory.*; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.EnchantmentInstance; + +import org.spongepowered.asm.mixin.Final; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; + +@Mixin(EnchantmentMenu.class) +public abstract class EnchantmentMenuMixin extends AbstractContainerMenu { + @Final + @Shadow + private Container enchantSlots; + + @Final + @Shadow + private ContainerLevelAccess access; + + @Final + @Shadow + private RandomSource random; + + @Final + @Shadow + private DataSlot enchantmentSeed; + + @Shadow + @Final + public int[] costs; + + @Shadow + @Final + public int[] enchantClue; + + @Shadow + @Final + public int[] levelClue; + + protected EnchantmentMenuMixin(MenuType type, int syncId) { + super(type, syncId); + } + + @Inject(method = "slotsChanged", at = @At("HEAD"), cancellable = true) + private void be_slotsChanged(Container inventory, CallbackInfo info) { + if (inventory == this.enchantSlots) { + ItemStack itemStack = inventory.getItem(0); + if (!itemStack.isEmpty() && itemStack.isEnchantable()) { + this.access.execute((world, blockPos) -> { + int i = 0; + + int j; + for (j = -1; j <= 1; ++j) { + for (int k = -1; k <= 1; ++k) { + if ((j != 0 || k != 0) && world.isEmptyBlock(blockPos.offset( + k, + 0, + j + )) && world.isEmptyBlock( + blockPos.offset(k, 1, j))) { + if (world.getBlockState(blockPos.offset(k * 2, 0, j * 2)) + .is(CommonBlockTags.BOOKSHELVES)) { + ++i; + } + + if (world.getBlockState(blockPos.offset(k * 2, 1, j * 2)) + .is(CommonBlockTags.BOOKSHELVES)) { + ++i; + } + + if (k != 0 && j != 0) { + if (world.getBlockState(blockPos.offset(k * 2, 0, j)) + .is(CommonBlockTags.BOOKSHELVES)) { + ++i; + } + + if (world.getBlockState(blockPos.offset(k * 2, 1, j)) + .is(CommonBlockTags.BOOKSHELVES)) { + ++i; + } + + if (world.getBlockState(blockPos.offset(k, 0, j * 2)) + .is(CommonBlockTags.BOOKSHELVES)) { + ++i; + } + + if (world.getBlockState(blockPos.offset(k, 1, j * 2)) + .is(CommonBlockTags.BOOKSHELVES)) { + ++i; + } + } + } + } + } + + random.setSeed(enchantmentSeed.get()); + + for (j = 0; j < 3; ++j) { + costs[j] = EnchantmentHelper.getEnchantmentCost(this.random, j, i, itemStack); + enchantClue[j] = -1; + levelClue[j] = -1; + if (costs[j] < j + 1) { + costs[j] = 0; + } + } + + for (j = 0; j < 3; ++j) { + if (this.costs[j] > 0) { + List list = this.getEnchantmentList(itemStack, j, this.costs[j]); + if (list != null && !list.isEmpty()) { + EnchantmentInstance enchantmentLevelEntry = list.get(this.random.nextInt( + list.size())); + enchantClue[j] = Registry.ENCHANTMENT.getId(enchantmentLevelEntry.enchantment); + levelClue[j] = enchantmentLevelEntry.level; + } + } + } + + broadcastChanges(); + }); + } else { + for (int i = 0; i < 3; ++i) { + costs[i] = 0; + enchantClue[i] = -1; + levelClue[i] = -1; + } + } + info.cancel(); + } + } + + @Shadow + private List getEnchantmentList(ItemStack stack, int slot, int level) { + return null; + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/EndCityFeatureMixin.java b/src/main/java/org/betterx/betterend/mixin/common/EndCityFeatureMixin.java new file mode 100644 index 00000000..81cb4f2e --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/EndCityFeatureMixin.java @@ -0,0 +1,36 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.betterend.world.generator.GeneratorOptions; + +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.levelgen.WorldgenRandom; +import net.minecraft.world.level.levelgen.XoroshiroRandomSource; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.structures.EndCityStructure; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; + +@Mixin(EndCityStructure.class) +public class EndCityFeatureMixin { + @Inject(method = "findGenerationPoint", at = @At("HEAD"), cancellable = true) + private void be_findGenerationPoint( + Structure.GenerationContext context, + CallbackInfoReturnable> info + ) { + final ChunkPos pos = context.chunkPos(); + WorldgenRandom chunkRandom = new WorldgenRandom(new XoroshiroRandomSource(pos.x, pos.z)); + + if (GeneratorOptions.useNewGenerator()) { + int chance = GeneratorOptions.getEndCityFailChance(); + if (chance > 0 && chunkRandom.nextInt(chance) != 0) { + info.setReturnValue(Optional.empty()); + info.cancel(); + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/EndDragonFightMixin.java b/src/main/java/org/betterx/betterend/mixin/common/EndDragonFightMixin.java new file mode 100644 index 00000000..9bd632d3 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/EndDragonFightMixin.java @@ -0,0 +1,101 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.world.generator.GeneratorOptions; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.boss.enderdragon.EndCrystal; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.pattern.BlockPattern; +import net.minecraft.world.level.dimension.end.DragonRespawnAnimation; +import net.minecraft.world.level.dimension.end.EndDragonFight; +import net.minecraft.world.phys.AABB; + +import com.google.common.collect.Lists; +import org.slf4j.Logger; +import org.spongepowered.asm.mixin.Final; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; + +@Mixin(EndDragonFight.class) +public class EndDragonFightMixin { + @Shadow + private DragonRespawnAnimation respawnStage; + @Shadow + private boolean dragonKilled; + @Shadow + private BlockPos portalLocation; + @Shadow + @Final + private static Logger LOGGER; + @Final + @Shadow + private ServerLevel level; + + @Shadow + private BlockPattern.BlockPatternMatch findExitPortal() { + return null; + } + + @Shadow + private void spawnExitPortal(boolean bl) { + } + + @Shadow + private void respawnDragon(List list) { + } + + @Inject(method = "tryRespawn", at = @At("HEAD"), cancellable = true) + private void be_tryRespawnDragon(CallbackInfo info) { + if (GeneratorOptions.replacePortal() && GeneratorOptions.hasDragonFights() && this.dragonKilled && this.respawnStage == null) { + BlockPos blockPos = portalLocation; + if (blockPos == null) { + LOGGER.debug("Tried to respawn, but need to find the portal first."); + BlockPattern.BlockPatternMatch blockPatternMatch = this.findExitPortal(); + if (blockPatternMatch == null) { + LOGGER.debug("Couldn't find a portal, so we made one."); + spawnExitPortal(true); + } else { + LOGGER.debug("Found the exit portal & temporarily using it."); + } + } + + List crystals = Lists.newArrayList(); + for (Direction dir : BlocksHelper.HORIZONTAL) { + BlockPos central = BlockPos.ZERO.relative(dir, 4); + List crystalList = level.getEntitiesOfClass( + EndCrystal.class, + new AABB(central.below(255).south().west(), central.above(255).north().east()) + ); + + int count = crystalList.size(); + for (int n = 0; n < count; n++) { + EndCrystal crystal = crystalList.get(n); + if (!level.getBlockState(crystal.blockPosition().below()).is(Blocks.BEDROCK)) { + crystalList.remove(n); + count--; + n--; + } + } + + if (crystalList.isEmpty()) { + info.cancel(); + return; + } + + crystals.addAll(crystalList); + } + + LOGGER.debug("Found all crystals, respawning dragon."); + respawnDragon(crystals); + info.cancel(); + } + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/EndPodiumFeatureMixin.java b/src/main/java/org/betterx/betterend/mixin/common/EndPodiumFeatureMixin.java new file mode 100644 index 00000000..8f112eab --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/EndPodiumFeatureMixin.java @@ -0,0 +1,96 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.bclib.util.StructureHelper; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.world.generator.GeneratorOptions; +import org.betterx.worlds.together.world.WorldConfig; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.level.levelgen.feature.EndPodiumFeature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; + +import org.spongepowered.asm.mixin.Final; +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.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; + +@Mixin(EndPodiumFeature.class) +public class EndPodiumFeatureMixin { + private static BlockPos be_portalPosition; + + @Final + @Shadow + private boolean active; + + @Inject(method = "place", at = @At("HEAD"), cancellable = true) + private void be_place( + FeaturePlaceContext featurePlaceContext, + CallbackInfoReturnable info + ) { + if (!GeneratorOptions.hasPortal()) { + info.setReturnValue(false); + info.cancel(); + } else if (GeneratorOptions.replacePortal()) { + RandomSource random = featurePlaceContext.random(); + WorldGenLevel world = featurePlaceContext.level(); + BlockPos blockPos = be_updatePortalPos(world); + StructureTemplate structure = StructureHelper.readStructure(BetterEnd.makeID(active + ? "portal/end_portal_active" + : "portal/end_portal_inactive")); + Vec3i size = structure.getSize(); + blockPos = blockPos.offset(-(size.getX() >> 1), -3, -(size.getZ() >> 1)); + structure.placeInWorld(world, blockPos, blockPos, new StructurePlaceSettings(), random, 2); + info.setReturnValue(true); + info.cancel(); + } + } + + @ModifyVariable(method = "place", ordinal = 0, at = @At("HEAD")) + private FeaturePlaceContext be_setPosOnGround(FeaturePlaceContext featurePlaceContext) { + WorldGenLevel world = featurePlaceContext.level(); + BlockPos pos = be_updatePortalPos(world); + return new FeaturePlaceContext( + Optional.empty(), + world, + featurePlaceContext.chunkGenerator(), + featurePlaceContext.random(), + pos, + featurePlaceContext.config() + ); + } + + private BlockPos be_updatePortalPos(WorldGenLevel world) { + CompoundTag compound = WorldConfig.getRootTag(BetterEnd.MOD_ID).getCompound("portal"); + be_portalPosition = NbtUtils.readBlockPos(compound); + + if (be_portalPosition.getY() == 0) { + /*if (GeneratorOptions.useNewGenerator()) { + int y = TerrainGenerator.getHeight(0, 0, world.getLevel().getChunkSource().getGenerator().getBiomeSource()); + be_portalPosition = new BlockPos(0, y, 0); + } + else { + be_portalPosition = new BlockPos(0, 65, 0); + }*/ + int y = world.getHeight(Types.WORLD_SURFACE, 0, 0); + be_portalPosition = new BlockPos(0, y, 0); + WorldConfig.getRootTag(BetterEnd.MOD_ID).put("portal", NbtUtils.writeBlockPos(be_portalPosition)); + WorldConfig.saveFile(BetterEnd.MOD_ID); + } + + return be_portalPosition; + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/EndSpikeMixin.java b/src/main/java/org/betterx/betterend/mixin/common/EndSpikeMixin.java new file mode 100644 index 00000000..07e169cd --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/EndSpikeMixin.java @@ -0,0 +1,45 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.world.generator.GeneratorOptions; +import org.betterx.worlds.together.world.WorldConfig; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.levelgen.feature.SpikeFeature.EndSpike; + +import org.spongepowered.asm.mixin.Final; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(EndSpike.class) +public class EndSpikeMixin { + @Final + @Shadow + private int height; + + @Inject(method = "getHeight", at = @At("HEAD"), cancellable = true) + private void be_getSpikeHeight(CallbackInfoReturnable info) { + if (!GeneratorOptions.isDirectSpikeHeight()) { + int x = getCenterX(); + int z = getCenterZ(); + String pillarID = String.format("%d_%d", x, z); + CompoundTag pillar = WorldConfig.getCompoundTag(BetterEnd.MOD_ID, "pillars"); + int minY = pillar.contains(pillarID) ? pillar.getInt(pillarID) : 65; + int maxY = minY + height - 54; + info.setReturnValue(maxY); + } + } + + @Shadow + public int getCenterX() { + return 0; + } + + @Shadow + public int getCenterZ() { + return 0; + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/EnderManMixin.java b/src/main/java/org/betterx/betterend/mixin/common/EnderManMixin.java new file mode 100644 index 00000000..ebadcf9a --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/EnderManMixin.java @@ -0,0 +1,27 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.betterend.effects.EndStatusEffects; +import org.betterx.betterend.registry.EndEnchantments; + +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.monster.EnderMan; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.enchantment.EnchantmentHelper; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(EnderMan.class) +public abstract class EnderManMixin { + @Inject(method = "isLookingAtMe", at = @At("HEAD"), cancellable = true) + private void be_isLookingAtMe(Player player, CallbackInfoReturnable info) { + if (player.isCreative() || player.hasEffect(EndStatusEffects.END_VEIL) || EnchantmentHelper.getItemEnchantmentLevel( + EndEnchantments.END_VEIL, + player.getItemBySlot(EquipmentSlot.HEAD) + ) > 0) { + info.setReturnValue(false); + } + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/EntityMixin.java b/src/main/java/org/betterx/betterend/mixin/common/EntityMixin.java new file mode 100644 index 00000000..21261527 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/EntityMixin.java @@ -0,0 +1,111 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.betterend.interfaces.TeleportingEntity; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.portal.PortalInfo; +import net.minecraft.world.phys.Vec3; + +import org.spongepowered.asm.mixin.Final; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Entity.class) +public abstract class EntityMixin implements TeleportingEntity { + @Shadow + private float yRot; + @Shadow + private float xRot; + + @Shadow + public Level level; + + @Final + @Shadow + public abstract void unRide(); + + @Shadow + public abstract Vec3 getDeltaMovement(); + + @Shadow + public abstract EntityType getType(); + + @Shadow + protected abstract PortalInfo findDimensionEntryPoint(ServerLevel destination); + + @Shadow + protected abstract void removeAfterChangingDimensions(); + + @Shadow + public abstract boolean isRemoved(); + + private BlockPos exitPos; + + @Inject(method = "changeDimension", at = @At("HEAD"), cancellable = true) + public void be_changeDimension(ServerLevel destination, CallbackInfoReturnable info) { + if (!isRemoved() && be_canTeleport() && level instanceof ServerLevel) { + unRide(); + level.getProfiler().push("changeDimension"); + level.getProfiler().push("reposition"); + PortalInfo teleportTarget = findDimensionEntryPoint(destination); + if (teleportTarget != null) { + level.getProfiler().popPush("reloading"); + Entity entity = getType().create(destination); + if (entity != null) { + entity.restoreFrom(Entity.class.cast(this)); + entity.moveTo( + teleportTarget.pos.x, + teleportTarget.pos.y, + teleportTarget.pos.z, + teleportTarget.yRot, + entity.getXRot() + ); + entity.setDeltaMovement(teleportTarget.speed); + destination.addDuringTeleport(entity); + } + + this.removeAfterChangingDimensions(); + level.getProfiler().pop(); + ((ServerLevel) level).resetEmptyTime(); + destination.resetEmptyTime(); + level.getProfiler().pop(); + be_resetExitPos(); + info.setReturnValue(entity); + } + } + } + + @Inject(method = "findDimensionEntryPoint", at = @At("HEAD"), cancellable = true) + protected void be_findDimensionEntryPoint(ServerLevel destination, CallbackInfoReturnable info) { + if (be_canTeleport()) { + info.setReturnValue(new PortalInfo( + new Vec3(exitPos.getX() + 0.5, exitPos.getY(), exitPos.getZ() + 0.5), + getDeltaMovement(), + yRot, + xRot + )); + } + } + + @Override + public void be_setExitPos(BlockPos pos) { + this.exitPos = pos.immutable(); + } + + @Override + public void be_resetExitPos() { + this.exitPos = null; + } + + @Override + public boolean be_canTeleport() { + return this.exitPos != null; + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/LevelMixin.java b/src/main/java/org/betterx/betterend/mixin/common/LevelMixin.java new file mode 100644 index 00000000..327766f8 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/LevelMixin.java @@ -0,0 +1,28 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.betterend.world.generator.GeneratorOptions; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Level.class) +public class LevelMixin { + + @Inject(method = "getSharedSpawnPos", at = @At("HEAD"), cancellable = true) + private void be_getSharedSpawnPos(CallbackInfoReturnable info) { + if (GeneratorOptions.changeSpawn()) { + if ((Object) this instanceof ServerLevel server) { + if (server.dimension() == Level.END) { + BlockPos pos = GeneratorOptions.getSpawn(); + info.setReturnValue(pos); + } + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/LivingEntityMixin.java b/src/main/java/org/betterx/betterend/mixin/common/LivingEntityMixin.java new file mode 100644 index 00000000..6e0bede8 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/LivingEntityMixin.java @@ -0,0 +1,99 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.interfaces.MobEffectApplier; +import org.betterx.betterend.item.CrystaliteArmor; +import org.betterx.betterend.registry.EndAttributes; + +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.attributes.AttributeMap; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.Level; + +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.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Collection; + +@Mixin(value = LivingEntity.class, priority = 200) +public abstract class LivingEntityMixin extends Entity { + + public LivingEntityMixin(EntityType entityType, Level level) { + super(entityType, level); + } + + + @Shadow + public abstract AttributeMap getAttributes(); + + private Entity lastAttacker; + + @Inject(method = "createLivingAttributes", at = @At("RETURN"), cancellable = true) + private static void be_addLivingAttributes(CallbackInfoReturnable info) { + EndAttributes.addLivingEntityAttributes(info.getReturnValue()); + } + + @Inject(method = "tickEffects", at = @At("HEAD")) + protected void be_applyEffects(CallbackInfo info) { + if (!level.isClientSide()) { + LivingEntity owner = LivingEntity.class.cast(this); + if (CrystaliteArmor.hasFullSet(owner)) { + CrystaliteArmor.applySetEffect(owner); + } + getArmorSlots().forEach(itemStack -> { + if (itemStack.getItem() instanceof MobEffectApplier) { + ((MobEffectApplier) itemStack.getItem()).applyEffect(owner); + } + }); + } + } + + @Inject(method = "canBeAffected", at = @At("HEAD"), cancellable = true) + public void be_canBeAffected(MobEffectInstance mobEffectInstance, CallbackInfoReturnable info) { + try { + if (mobEffectInstance.getEffect() == MobEffects.BLINDNESS && getAttributes().getValue(EndAttributes.BLINDNESS_RESISTANCE) > 0.0) { + info.setReturnValue(false); + } + } catch (Exception ex) { + BetterEnd.LOGGER.warning("Blindness resistance attribute haven't been registered."); + } + } + + @Inject(method = "hurt", at = @At("HEAD")) + public void be_hurt(DamageSource source, float amount, CallbackInfoReturnable info) { + this.lastAttacker = source.getEntity(); + } + + @ModifyArg(method = "hurt", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;knockback(DDD)V"), index = 0) + private double be_increaseKnockback(double value, double x, double z) { + if (lastAttacker != null && lastAttacker instanceof LivingEntity) { + LivingEntity attacker = (LivingEntity) lastAttacker; + value += this.be_getKnockback(attacker.getMainHandItem().getItem()); + } + return value; + } + + private double be_getKnockback(Item tool) { + if (tool == null) return 0.0D; + Collection modifiers = tool.getDefaultAttributeModifiers(EquipmentSlot.MAINHAND) + .get(Attributes.ATTACK_KNOCKBACK); + if (modifiers.size() > 0) { + return modifiers.iterator().next().getAmount(); + } + return 0.0D; + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/MappedRegistryMixin.java b/src/main/java/org/betterx/betterend/mixin/common/MappedRegistryMixin.java new file mode 100644 index 00000000..6bd95c6e --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/MappedRegistryMixin.java @@ -0,0 +1,50 @@ +package org.betterx.betterend.mixin.common; + +import net.minecraft.core.MappedRegistry; +import net.minecraft.resources.ResourceKey; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(MappedRegistry.class) +public class MappedRegistryMixin { + // TODO Make this a part of BCLib (implement froze/unfroze methods) + @Inject(method = "validateWrite", at = @At("HEAD"), cancellable = true) + private void be_validateWrite(ResourceKey resourceKey, CallbackInfo info) { + //info.cancel(); + } + +// @Inject(method = "registerMapping(ILnet/minecraft/resources/ResourceKey;Ljava/lang/Object;Lcom/mojang/serialization/Lifecycle;Z)Lnet/minecraft/core/Holder;", at = @At("HEAD")) +// private void be_debugDummy( +// int i, +// ResourceKey resourceKey, +// T object, +// Lifecycle lifecycle, +// boolean bl, +// CallbackInfoReturnable> cir +// ) { +// if (resourceKey.location().getPath().equals("dark_amaranth_forest")) { +// System.out.println("Promenade registers: " + resourceKey); +// } +// } +// +// @Inject(method = "getOrCreateHolderOrThrow", at = @At("HEAD")) +// private void be_debugDummy2( +// ResourceKey resourceKey, CallbackInfoReturnable> cir +// ) { +// if (resourceKey.location().getPath().equals("dark_amaranth_forest")) { +// System.out.println("Promenade registers: " + resourceKey); +// } +// } +// +// @Inject(method = "getOrCreateHolder", at = @At("HEAD")) +// private void be_debugDummy3( +// ResourceKey resourceKey, CallbackInfoReturnable> cir +// ) { +// if (resourceKey.location().getPath().equals("dark_amaranth_forest")) { +// System.out.println("Promenade registers: " + resourceKey); +// } +// } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/MonsterMixin.java b/src/main/java/org/betterx/betterend/mixin/common/MonsterMixin.java new file mode 100644 index 00000000..15503c39 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/MonsterMixin.java @@ -0,0 +1,39 @@ +package org.betterx.betterend.mixin.common; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.monster.EnderMan; +import net.minecraft.world.entity.monster.Monster; +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.phys.AABB; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.List; + +@Mixin(Monster.class) +public class MonsterMixin { + @Inject(method = "checkMonsterSpawnRules", at = @At(value = "RETURN"), cancellable = true) + private static void be_checkMonsterSpawnRules( + EntityType type, + ServerLevelAccessor serverWorldAccess, + MobSpawnType spawnReason, + BlockPos pos, + RandomSource random, + CallbackInfoReturnable info + ) { + boolean canSpawn = info.getReturnValue(); + if (canSpawn && spawnReason == MobSpawnType.NATURAL && type == EntityType.ENDERMAN) { + AABB box = new AABB(pos).inflate(16); + List entities = serverWorldAccess.getEntitiesOfClass(EnderMan.class, box, (entity) -> { + return true; + }); + info.setReturnValue(entities.size() < 6); + } + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/NoiseBasedChunkGeneratorAccessor.java b/src/main/java/org/betterx/betterend/mixin/common/NoiseBasedChunkGeneratorAccessor.java new file mode 100644 index 00000000..2cd456cd --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/NoiseBasedChunkGeneratorAccessor.java @@ -0,0 +1,14 @@ +package org.betterx.betterend.mixin.common; + +import net.minecraft.core.Holder; +import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; +import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(NoiseBasedChunkGenerator.class) +public interface NoiseBasedChunkGeneratorAccessor { + @Accessor("settings") + Holder be_getSettings(); +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/NoiseChunkAccessor.java b/src/main/java/org/betterx/betterend/mixin/common/NoiseChunkAccessor.java new file mode 100644 index 00000000..73bdbfa6 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/NoiseChunkAccessor.java @@ -0,0 +1,25 @@ +package org.betterx.betterend.mixin.common; + +import net.minecraft.world.level.levelgen.NoiseChunk; +import net.minecraft.world.level.levelgen.NoiseSettings; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(NoiseChunk.class) +public interface NoiseChunkAccessor { + @Accessor("noiseSettings") + NoiseSettings bnv_getNoiseSettings(); + + @Accessor("cellCountXZ") + int bnv_getCellCountXZ(); + + @Accessor("cellCountY") + int bnv_getCellCountY(); + + @Accessor("firstCellZ") + int bnv_getFirstCellZ(); + + @Accessor("cellNoiseMinY") + int bnv_getCellNoiseMinY(); +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/NoiseChunkMixin.java b/src/main/java/org/betterx/betterend/mixin/common/NoiseChunkMixin.java new file mode 100644 index 00000000..4414ac55 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/NoiseChunkMixin.java @@ -0,0 +1,67 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.bclib.BCLib; +import org.betterx.betterend.interfaces.BETargetChecker; +import org.betterx.betterend.world.generator.TerrainGenerator; + +import net.minecraft.world.level.levelgen.*; +import net.minecraft.world.level.levelgen.blending.Blender; + +import org.spongepowered.asm.mixin.Final; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; + +@Mixin(NoiseChunk.class) +public class NoiseChunkMixin implements BETargetChecker { + private boolean be_isEndGenerator; + + @Inject(method = "*", at = @At("TAIL")) + private void be_onNoiseChunkInit( + int i, + RandomState randomState, + int j, + int k, + NoiseSettings noiseSettings, + DensityFunctions.BeardifierOrMarker beardifierOrMarker, + NoiseGeneratorSettings noiseGeneratorSettings, + Aquifer.FluidPicker fluidPicker, + Blender blender, + CallbackInfo ci + ) { + var o = BETargetChecker.class.cast(noiseGeneratorSettings); + if (o != null) be_isEndGenerator = o.be_isTarget(); + else BCLib.LOGGER.warning(noiseGeneratorSettings + " has unknown implementation."); + } + + @Override + public boolean be_isTarget() { + return be_isEndGenerator; + } + + @Override + public void be_setTarget(boolean target) { + be_isEndGenerator = target; + } + + @Shadow + @Final + private List interpolators; + + @Inject(method = "fillSlice", at = @At("HEAD"), cancellable = true) + private void be_fillSlice(boolean primarySlice, int x, CallbackInfo info) { + if (!be_isTarget()) return; + + info.cancel(); + + NoiseChunkAccessor accessor = (NoiseChunkAccessor) this; + NoiseSettings noiseSettings = accessor.bnv_getNoiseSettings(); + + TerrainGenerator.fillSlice(primarySlice, x, interpolators, accessor, noiseSettings); + } + +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/NoiseGeneratorSettingsMixin.java b/src/main/java/org/betterx/betterend/mixin/common/NoiseGeneratorSettingsMixin.java new file mode 100644 index 00000000..82fa21de --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/NoiseGeneratorSettingsMixin.java @@ -0,0 +1,22 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.betterend.interfaces.BETargetChecker; + +import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; + +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(NoiseGeneratorSettings.class) +public class NoiseGeneratorSettingsMixin implements BETargetChecker { + private boolean be_isTargetGenerator; + + @Override + public boolean be_isTarget() { + return be_isTargetGenerator; + } + + @Override + public void be_setTarget(boolean target) { + be_isTargetGenerator = target; + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/NoiseInterpolatorAccessor.java b/src/main/java/org/betterx/betterend/mixin/common/NoiseInterpolatorAccessor.java new file mode 100644 index 00000000..d94d8df7 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/NoiseInterpolatorAccessor.java @@ -0,0 +1,15 @@ +package org.betterx.betterend.mixin.common; + +import net.minecraft.world.level.levelgen.NoiseChunk; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(NoiseChunk.NoiseInterpolator.class) +public interface NoiseInterpolatorAccessor { + @Accessor("slice0") + double[][] be_getSlice0(); + + @Accessor("slice1") + double[][] be_getSlice1(); +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/PlayerAdvancementsMixin.java b/src/main/java/org/betterx/betterend/mixin/common/PlayerAdvancementsMixin.java new file mode 100644 index 00000000..0139bec2 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/PlayerAdvancementsMixin.java @@ -0,0 +1,30 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.betterend.events.PlayerAdvancementsCallback; + +import net.minecraft.advancements.Advancement; +import net.minecraft.server.PlayerAdvancements; +import net.minecraft.server.level.ServerPlayer; + +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(PlayerAdvancements.class) +public abstract class PlayerAdvancementsMixin { + @Shadow + private ServerPlayer player; + + @Inject(method = "award", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancements/AdvancementRewards;grant(Lnet/minecraft/server/level/ServerPlayer;)V", shift = Shift.AFTER)) + public void be_award(Advancement advancement, String criterionName, CallbackInfoReturnable info) { + PlayerAdvancementsCallback.PLAYER_ADVANCEMENT_COMPLETE.invoker() + .onAdvancementComplete( + player, + advancement, + criterionName + ); + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/PlayerMixin.java b/src/main/java/org/betterx/betterend/mixin/common/PlayerMixin.java new file mode 100644 index 00000000..4215864b --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/PlayerMixin.java @@ -0,0 +1,69 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; + +@Mixin(value = Player.class, priority = 200) +public abstract class PlayerMixin extends LivingEntity { + protected PlayerMixin(EntityType entityType, Level level) { + super(entityType, level); + } + + private static Direction[] horizontal; + + @Inject(method = "findRespawnPositionAndUseSpawnBlock", at = @At(value = "HEAD"), cancellable = true) + private static void be_findRespawnPositionAndUseSpawnBlock( + ServerLevel world, + BlockPos pos, + float f, + boolean bl, + boolean bl2, + CallbackInfoReturnable> info + ) { + BlockState blockState = world.getBlockState(pos); + if (blockState.is(EndBlocks.RESPAWN_OBELISK)) { + info.setReturnValue(be_obeliskRespawnPosition(world, pos, blockState)); + info.cancel(); + } + } + + private static Optional be_obeliskRespawnPosition(ServerLevel world, BlockPos pos, BlockState state) { + if (state.getValue(BlockProperties.TRIPLE_SHAPE) == TripleShape.TOP) { + pos = pos.below(2); + } else if (state.getValue(BlockProperties.TRIPLE_SHAPE) == TripleShape.MIDDLE) { + pos = pos.below(); + } + if (horizontal == null) { + horizontal = BlocksHelper.makeHorizontal(); + } + MHelper.shuffle(horizontal, world.getRandom()); + for (Direction dir : horizontal) { + BlockPos p = pos.relative(dir); + BlockState state2 = world.getBlockState(p); + if (!state2.getMaterial().blocksMotion() && state2.getCollisionShape(world, pos).isEmpty()) { + return Optional.of(Vec3.atLowerCornerOf(p).add(0.5, 0, 0.5)); + } + } + return Optional.empty(); + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/mixin/common/ServerLevelMixin.java b/src/main/java/org/betterx/betterend/mixin/common/ServerLevelMixin.java new file mode 100644 index 00000000..5c7d37d2 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/ServerLevelMixin.java @@ -0,0 +1,101 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.world.generator.GeneratorOptions; +import org.betterx.betterend.world.generator.TerrainGenerator; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.progress.ChunkProgressListener; +import net.minecraft.util.profiling.ProfilerFiller; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.dimension.BuiltinDimensionTypes; +import net.minecraft.world.level.dimension.DimensionType; +import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess; +import net.minecraft.world.level.storage.ServerLevelData; +import net.minecraft.world.level.storage.WritableLevelData; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; +import java.util.concurrent.Executor; +import java.util.function.Supplier; + +@Mixin(ServerLevel.class) +public abstract class ServerLevelMixin extends Level { + protected ServerLevelMixin( + WritableLevelData writableLevelData, + ResourceKey resourceKey, + Holder holder, + Supplier supplier, + boolean bl, + boolean bl2, + long l, + int i + ) { + super(writableLevelData, resourceKey, holder, supplier, bl, bl2, l, i); + } + + private final static List> BE_TEST_DIMENSIONS = List.of( + BuiltinDimensionTypes.OVERWORLD, + BuiltinDimensionTypes.OVERWORLD_CAVES, + BuiltinDimensionTypes.NETHER + ); + + @ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/Holder;is(Lnet/minecraft/resources/ResourceKey;)Z")) + ResourceKey be_dragonFight(ResourceKey resourceKey) { + if (!GeneratorOptions.hasDragonFights()) { + //this object would pass the test for the End-Dimension, so make sure we compare against something else to disabled the Dragon-Fight + if (this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END)) return BuiltinDimensionTypes.OVERWORLD; + } + return resourceKey; + } + + @Inject(method = "*", at = @At("TAIL")) + private void be_onServerWorldInit( + MinecraftServer minecraftServer, + Executor executor, + LevelStorageAccess levelStorageAccess, + ServerLevelData serverLevelData, + ResourceKey resourceKey, + LevelStem levelStem, + ChunkProgressListener chunkProgressListener, + boolean bl, + long seed, + List list, + boolean bl2, + CallbackInfo ci + ) { + TerrainGenerator.onServerLevelInit(ServerLevel.class.cast(this), levelStem, seed); + } + + + @Inject(method = "makeObsidianPlatform", at = @At("HEAD"), cancellable = true) + private static void be_createObsidianPlatform(ServerLevel serverLevel, CallbackInfo info) { + TerrainGenerator.makeObsidianPlatform(serverLevel, info); + } + + @ModifyArg(method = "tickChunk", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z")) + private BlockState be_modifyTickState(BlockPos pos, BlockState state) { + if (state.is(Blocks.ICE)) { + ResourceLocation biome = BiomeAPI.getBiomeID(getBiome(pos)); + if (biome.getNamespace().equals(BetterEnd.MOD_ID)) { + state = EndBlocks.EMERALD_ICE.defaultBlockState(); + } + } + return state; + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/ServerPlayerMixin.java b/src/main/java/org/betterx/betterend/mixin/common/ServerPlayerMixin.java new file mode 100644 index 00000000..0741f4a5 --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/ServerPlayerMixin.java @@ -0,0 +1,186 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.betterend.interfaces.TeleportingEntity; +import org.betterx.betterend.world.generator.GeneratorOptions; + +import com.mojang.authlib.GameProfile; +import net.minecraft.core.BlockPos; +import net.minecraft.network.protocol.game.*; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.level.ServerPlayerGameMode; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.server.players.PlayerList; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.player.ProfilePublicKey; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.portal.PortalInfo; +import net.minecraft.world.level.storage.LevelData; +import net.minecraft.world.phys.Vec3; + +import org.spongepowered.asm.mixin.Final; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; +import org.jetbrains.annotations.Nullable; + +@Mixin(ServerPlayer.class) +public abstract class ServerPlayerMixin extends Player implements TeleportingEntity { + @Shadow + public ServerGamePacketListenerImpl connection; + @Final + @Shadow + public ServerPlayerGameMode gameMode; + @Final + @Shadow + public MinecraftServer server; + @Shadow + private boolean isChangingDimension; + @Shadow + private float lastSentHealth; + @Shadow + private int lastSentFood; + @Shadow + private int lastSentExp; + + private BlockPos exitPos; + private int be_teleportDelay = 0; + + public ServerPlayerMixin( + Level level, + BlockPos blockPos, + float f, + GameProfile gameProfile, + @Nullable ProfilePublicKey profilePublicKey + ) { + super(level, blockPos, f, gameProfile, profilePublicKey); + } + + + @Inject(method = "createEndPlatform", at = @At("HEAD"), cancellable = true) + private void be_createEndSpawnPlatform(ServerLevel world, BlockPos centerPos, CallbackInfo info) { + if (!GeneratorOptions.generateObsidianPlatform()) { + info.cancel(); + } + } + + @Inject(method = "findDimensionEntryPoint", at = @At("HEAD"), cancellable = true) + protected void be_getTeleportTarget(ServerLevel destination, CallbackInfoReturnable info) { + if (be_canTeleport()) { + info.setReturnValue(new PortalInfo( + new Vec3(exitPos.getX() + 0.5, exitPos.getY(), exitPos.getZ() + 0.5), + getDeltaMovement(), + getYRot(), + getXRot() + )); + } else if (GeneratorOptions.changeSpawn() && destination.dimension() == Level.END) { + BlockPos spawn = GeneratorOptions.getSpawn(); + Vec3 pos = new Vec3(spawn.getX() + 0.5, spawn.getY(), spawn.getZ() + 0.5); + info.setReturnValue(new PortalInfo(pos, Vec3.ZERO, 90.0F, 0.0F)); + } + } + + @Inject(method = "changeDimension", at = @At("HEAD"), cancellable = true) + public void be_changeDimension(ServerLevel destination, CallbackInfoReturnable info) { + if (be_canTeleport() && level instanceof ServerLevel) { + isChangingDimension = true; + ServerLevel serverWorld = getLevel(); + LevelData worldProperties = destination.getLevelData(); + ServerPlayer player = ServerPlayer.class.cast(this); + connection.send(new ClientboundRespawnPacket( + destination.dimensionTypeId(), + destination.dimension(), + BiomeManager.obfuscateSeed(destination.getSeed()), + gameMode.getGameModeForPlayer(), + gameMode.getPreviousGameModeForPlayer(), + destination.isDebug(), + destination.isFlat(), + true, + Optional.empty() + )); + connection.send(new ClientboundChangeDifficultyPacket( + worldProperties.getDifficulty(), + worldProperties.isDifficultyLocked() + )); + PlayerList playerManager = server.getPlayerList(); + playerManager.sendPlayerPermissionLevel(player); + serverWorld.removePlayerImmediately(player, RemovalReason.CHANGED_DIMENSION); + unsetRemoved(); + PortalInfo teleportTarget = findDimensionEntryPoint(destination); + if (teleportTarget != null) { + serverWorld.getProfiler().push("moving"); + serverWorld.getProfiler().pop(); + serverWorld.getProfiler().push("placing"); + this.level = destination; + destination.addDuringPortalTeleport(player); + setRot(teleportTarget.yRot, teleportTarget.xRot); + moveTo(teleportTarget.pos.x, teleportTarget.pos.y, teleportTarget.pos.z); + serverWorld.getProfiler().pop(); + triggerDimensionChangeTriggers(serverWorld); + gameMode.setLevel(destination); + connection.send(new ClientboundPlayerAbilitiesPacket(getAbilities())); + playerManager.sendLevelInfo(player, destination); + playerManager.sendAllPlayerInfo(player); + + for (MobEffectInstance statusEffectInstance : getActiveEffects()) { + connection.send(new ClientboundUpdateMobEffectPacket(getId(), statusEffectInstance)); + } + + connection.send(new ClientboundLevelEventPacket(1032, BlockPos.ZERO, 0, false)); + lastSentExp = -1; + lastSentHealth = -1.0F; + lastSentFood = -1; + } + be_teleportDelay = 100; + be_resetExitPos(); + info.setReturnValue(player); + } + } + + @Inject(method = "tick", at = @At("TAIL")) + public void be_decreaseCooldawn(CallbackInfo info) { + if (be_teleportDelay > 0) be_teleportDelay--; + } + + @Override + public int getDimensionChangingDelay() { + if (be_teleportDelay > 0) { + return be_teleportDelay; + } + return super.getDimensionChangingDelay(); + } + + @Shadow + public abstract ServerLevel getLevel(); + + @Shadow + abstract void triggerDimensionChangeTriggers(ServerLevel origin); + + @Shadow + @Override + protected abstract PortalInfo findDimensionEntryPoint(ServerLevel destination); + + @Override + public void be_setExitPos(BlockPos pos) { + this.exitPos = pos.immutable(); + } + + @Override + public void be_resetExitPos() { + this.exitPos = null; + } + + @Override + public boolean be_canTeleport() { + return this.exitPos != null; + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/SlimeMixin.java b/src/main/java/org/betterx/betterend/mixin/common/SlimeMixin.java new file mode 100644 index 00000000..4f79a15a --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/SlimeMixin.java @@ -0,0 +1,32 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.betterend.interfaces.ISlime; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.monster.Slime; +import net.minecraft.world.level.Level; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(Slime.class) +public abstract class SlimeMixin extends Entity implements ISlime { + public SlimeMixin(EntityType entityType, Level level) { + super(entityType, level); + } + + @Shadow + public void setSize(int size, boolean heal) { + } + + @Override + public void be_setSlimeSize(int size, boolean heal) { + setSize(size, heal); + } + + @Override + public void entityRemove(Entity.RemovalReason removalReason) { + super.remove(removalReason); + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/SpikeFeatureMixin.java b/src/main/java/org/betterx/betterend/mixin/common/SpikeFeatureMixin.java new file mode 100644 index 00000000..c58cefee --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/SpikeFeatureMixin.java @@ -0,0 +1,192 @@ +package org.betterx.betterend.mixin.common; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.StructureHelper; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.world.generator.GeneratorOptions; +import org.betterx.worlds.together.world.WorldConfig; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Vec3i; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.boss.enderdragon.EndCrystal; +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.IronBarsBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.SpikeFeature; +import net.minecraft.world.level.levelgen.feature.configurations.SpikeConfiguration; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(SpikeFeature.class) +public class SpikeFeatureMixin { + @Inject(method = "place", at = @At("HEAD"), cancellable = true) + private void be_place( + FeaturePlaceContext featurePlaceContext, + CallbackInfoReturnable info + ) { + if (!GeneratorOptions.hasPillars()) { + info.setReturnValue(false); + } + } + + @Inject(method = "placeSpike", at = @At("HEAD"), cancellable = true) + private void be_placeSpike( + ServerLevelAccessor world, + RandomSource random, + SpikeConfiguration config, + SpikeFeature.EndSpike spike, + CallbackInfo info + ) { + int x = spike.getCenterX(); + int z = spike.getCenterZ(); + int radius = spike.getRadius(); + int minY = 0; + + long lx = x; + long lz = z; + if (lx * lx + lz * lz < 10000) { + String pillarID = String.format("%d_%d", x, z); + CompoundTag pillar = WorldConfig.getCompoundTag(BetterEnd.MOD_ID, "pillars"); + boolean haveValue = pillar.contains(pillarID); + minY = haveValue + ? pillar.getInt(pillarID) + : world.getChunk(x >> 4, z >> 4).getHeight(Types.WORLD_SURFACE, x & 15, z); + if (!haveValue) { + pillar.putInt(pillarID, minY); + WorldConfig.saveFile(BetterEnd.MOD_ID); + } + } else { + minY = world.getChunk(x >> 4, z >> 4).getHeight(Types.WORLD_SURFACE, x & 15, z); + } + + GeneratorOptions.setDirectSpikeHeight(); + int maxY = minY + spike.getHeight() - 64; + + if (GeneratorOptions.replacePillars() && be_radiusInRange(radius)) { + radius--; + StructureTemplate base = StructureHelper.readStructure(BetterEnd.makeID("pillars/pillar_base_" + radius)); + StructureTemplate top = StructureHelper.readStructure(BetterEnd.makeID("pillars/pillar_top_" + radius + ( + spike + .isGuarded() + ? "_cage" + : ""))); + Vec3i side = base.getSize(); + BlockPos pos1 = new BlockPos(x - (side.getX() >> 1), minY - 3, z - (side.getZ() >> 1)); + minY = pos1.getY() + side.getY(); + side = top.getSize(); + BlockPos pos2 = new BlockPos(x - (side.getX() >> 1), maxY, z - (side.getZ() >> 1)); + maxY = pos2.getY(); + + StructurePlaceSettings data = new StructurePlaceSettings(); + base.placeInWorld(world, pos1, pos1, data, random, 2); + top.placeInWorld(world, pos2, pos2, data, random, 2); + + int r2 = radius * radius + 1; + MutableBlockPos mut = new MutableBlockPos(); + for (int px = -radius; px <= radius; px++) { + mut.setX(x + px); + int x2 = px * px; + for (int pz = -radius; pz <= radius; pz++) { + mut.setZ(z + pz); + int z2 = pz * pz; + if (x2 + z2 <= r2) { + for (int py = minY; py < maxY; py++) { + mut.setY(py); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + if ((px == radius || px == -radius || pz == radius || pz == -radius) && random.nextInt( + 24) == 0) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.CRYING_OBSIDIAN); + } else { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.OBSIDIAN); + } + } + } + } + } + } + } else { + minY -= 15; + int r2 = radius * radius + 1; + MutableBlockPos mut = new MutableBlockPos(); + for (int px = -radius; px <= radius; px++) { + mut.setX(x + px); + int x2 = px * px; + for (int pz = -radius; pz <= radius; pz++) { + mut.setZ(z + pz); + int z2 = pz * pz; + if (x2 + z2 <= r2) { + for (int py = minY; py < maxY; py++) { + mut.setY(py); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.OBSIDIAN); + } + } + } + } + } + mut.setX(x); + mut.setZ(z); + mut.setY(maxY); + BlocksHelper.setWithoutUpdate(world, mut, Blocks.BEDROCK); + + EndCrystal crystal = EntityType.END_CRYSTAL.create(world.getLevel()); + crystal.setBeamTarget(config.getCrystalBeamTarget()); + crystal.setInvulnerable(config.isCrystalInvulnerable()); + crystal.moveTo(x + 0.5D, maxY + 1, z + 0.5D, random.nextFloat() * 360.0F, 0.0F); + world.addFreshEntity(crystal); + + if (spike.isGuarded()) { + for (int px = -2; px <= 2; ++px) { + boolean bl = Mth.abs(px) == 2; + for (int pz = -2; pz <= 2; ++pz) { + boolean bl2 = Mth.abs(pz) == 2; + for (int py = 0; py <= 3; ++py) { + boolean bl3 = py == 3; + if (bl || bl2 || bl3) { + boolean bl4 = px == -2 || px == 2 || bl3; + boolean bl5 = pz == -2 || pz == 2 || bl3; + BlockState blockState = Blocks.IRON_BARS + .defaultBlockState() + .setValue(IronBarsBlock.NORTH, bl4 && pz != -2).setValue( + IronBarsBlock.SOUTH, + bl4 && pz != 2 + ).setValue( + IronBarsBlock.WEST, + bl5 && px != -2 + ).setValue( + IronBarsBlock.EAST, + bl5 && px != 2 + ); + BlocksHelper.setWithoutUpdate( + world, + mut.set(spike.getCenterX() + px, maxY + py, spike.getCenterZ() + pz), + blockState + ); + } + } + } + } + } + } + + info.cancel(); + } + + private boolean be_radiusInRange(int radius) { + return radius > 1 && radius < 6; + } +} diff --git a/src/main/java/org/betterx/betterend/mixin/common/WorldGenRegionMixin.java b/src/main/java/org/betterx/betterend/mixin/common/WorldGenRegionMixin.java new file mode 100644 index 00000000..744e1ffc --- /dev/null +++ b/src/main/java/org/betterx/betterend/mixin/common/WorldGenRegionMixin.java @@ -0,0 +1,29 @@ +package org.betterx.betterend.mixin.common; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.WorldGenRegion; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.ChunkAccess; + +import org.spongepowered.asm.mixin.Final; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(WorldGenRegion.class) +public class WorldGenRegionMixin { + @Final + @Shadow + private ChunkAccess center; + + @Inject(method = "ensureCanWrite", at = @At("HEAD"), cancellable = true) + private void be_alterBlockCheck(BlockPos blockPos, CallbackInfoReturnable info) { + ChunkPos cPos = center.getPos(); + int x = blockPos.getX() >> 4; + int z = blockPos.getZ() >> 4; + WorldGenRegion region = (WorldGenRegion) (Object) this; + info.setReturnValue(Math.abs(x - cPos.x) < 2 && Math.abs(z - cPos.z) < 2); + } +} diff --git a/src/main/java/org/betterx/betterend/noise/OpenSimplexNoise.java b/src/main/java/org/betterx/betterend/noise/OpenSimplexNoise.java new file mode 100644 index 00000000..3479e43b --- /dev/null +++ b/src/main/java/org/betterx/betterend/noise/OpenSimplexNoise.java @@ -0,0 +1,2528 @@ +package org.betterx.betterend.noise; + +/* + * OpenSimplex Noise in Java. + * by Kurt Spencer + * + * v1.1 (October 5, 2014) + * - Added 2D and 4D implementations. + * - Proper gradient sets for all dimensions, from a + * dimensionally-generalizable scheme with an actual + * rhyme and reason behind it. + * - Removed default permutation array in favor of + * default seed. + * - Changed seed-based constructor to be independent + * of any particular randomization library, so results + * will be the same when ported to other languages. + */ + +public final class OpenSimplexNoise { + private static final double STRETCH_CONSTANT_2D = -0.211324865405187; // (1/Math.sqrt(2+1)-1)/2; + private static final double SQUISH_CONSTANT_2D = 0.366025403784439; // (Math.sqrt(2+1)-1)/2; + private static final double STRETCH_CONSTANT_3D = -1.0 / 6; // (1/Math.sqrt(3+1)-1)/3; + private static final double SQUISH_CONSTANT_3D = 1.0 / 3; // (Math.sqrt(3+1)-1)/3; + private static final double STRETCH_CONSTANT_4D = -0.138196601125011; // (1/Math.sqrt(4+1)-1)/4; + private static final double SQUISH_CONSTANT_4D = 0.309016994374947; // (Math.sqrt(4+1)-1)/4; + + private static final double NORM_CONSTANT_2D = 47; + private static final double NORM_CONSTANT_3D = 103; + private static final double NORM_CONSTANT_4D = 30; + + private static final long DEFAULT_SEED = 0; + + private final short[] perm; + private final short[] permGradIndex3D; + + public OpenSimplexNoise() { + this(DEFAULT_SEED); + } + + public OpenSimplexNoise(short[] perm) { + this.perm = perm; + permGradIndex3D = new short[256]; + + for (int i = 0; i < 256; i++) { + // Since 3D has 24 gradients, simple bitmask won't work, so + // precompute modulo array. + permGradIndex3D[i] = (short) ((perm[i] % (gradients3D.length / 3)) * 3); + } + } + + // Initializes the class using a permutation array generated from a 64-bit + // seed. + // Generates a proper permutation (i.e. doesn't merely perform N successive + // pair swaps on a base array) + // Uses a simple 64-bit LCG. + public OpenSimplexNoise(long seed) { + perm = new short[256]; + permGradIndex3D = new short[256]; + short[] source = new short[256]; + for (short i = 0; i < 256; i++) { + source[i] = i; + } + seed = seed * 6364136223846793005l + 1442695040888963407l; + seed = seed * 6364136223846793005l + 1442695040888963407l; + seed = seed * 6364136223846793005l + 1442695040888963407l; + for (int i = 255; i >= 0; i--) { + seed = seed * 6364136223846793005l + 1442695040888963407l; + int r = (int) ((seed + 31) % (i + 1)); + if (r < 0) r += (i + 1); + perm[i] = source[r]; + permGradIndex3D[i] = (short) ((perm[i] % (gradients3D.length / 3)) * 3); + source[r] = source[i]; + } + } + + // 2D OpenSimplex Noise. + public double eval(double x, double y) { + + // Place input coordinates onto grid. + double stretchOffset = (x + y) * STRETCH_CONSTANT_2D; + double xs = x + stretchOffset; + double ys = y + stretchOffset; + + // Floor to get grid coordinates of rhombus (stretched square) + // super-cell origin. + int xsb = fastFloor(xs); + int ysb = fastFloor(ys); + + // Skew out to get actual coordinates of rhombus origin. We'll need + // these later. + double squishOffset = (xsb + ysb) * SQUISH_CONSTANT_2D; + double xb = xsb + squishOffset; + double yb = ysb + squishOffset; + + // Compute grid coordinates relative to rhombus origin. + double xins = xs - xsb; + double yins = ys - ysb; + + // Sum those together to get a value that determines which region we're + // in. + double inSum = xins + yins; + + // Positions relative to origin point. + double dx0 = x - xb; + double dy0 = y - yb; + + // We'll be defining these inside the next block and using them + // afterwards. + double dx_ext, dy_ext; + int xsv_ext, ysv_ext; + + double value = 0; + + // Contribution (1,0) + double dx1 = dx0 - 1 - SQUISH_CONSTANT_2D; + double dy1 = dy0 - 0 - SQUISH_CONSTANT_2D; + double attn1 = 2 - dx1 * dx1 - dy1 * dy1; + if (attn1 > 0) { + attn1 *= attn1; + value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, dx1, dy1); + } + + // Contribution (0,1) + double dx2 = dx0 - 0 - SQUISH_CONSTANT_2D; + double dy2 = dy0 - 1 - SQUISH_CONSTANT_2D; + double attn2 = 2 - dx2 * dx2 - dy2 * dy2; + if (attn2 > 0) { + attn2 *= attn2; + value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, dx2, dy2); + } + + if (inSum <= 1) { // We're inside the triangle (2-Simplex) at (0,0) + double zins = 1 - inSum; + if (zins > xins || zins > yins) { // (0,0) is one of the closest two + // triangular vertices + if (xins > yins) { + xsv_ext = xsb + 1; + ysv_ext = ysb - 1; + dx_ext = dx0 - 1; + dy_ext = dy0 + 1; + } else { + xsv_ext = xsb - 1; + ysv_ext = ysb + 1; + dx_ext = dx0 + 1; + dy_ext = dy0 - 1; + } + } else { // (1,0) and (0,1) are the closest two vertices. + xsv_ext = xsb + 1; + ysv_ext = ysb + 1; + dx_ext = dx0 - 1 - 2 * SQUISH_CONSTANT_2D; + dy_ext = dy0 - 1 - 2 * SQUISH_CONSTANT_2D; + } + } else { // We're inside the triangle (2-Simplex) at (1,1) + double zins = 2 - inSum; + if (zins < xins || zins < yins) { // (0,0) is one of the closest two + // triangular vertices + if (xins > yins) { + xsv_ext = xsb + 2; + ysv_ext = ysb + 0; + dx_ext = dx0 - 2 - 2 * SQUISH_CONSTANT_2D; + dy_ext = dy0 + 0 - 2 * SQUISH_CONSTANT_2D; + } else { + xsv_ext = xsb + 0; + ysv_ext = ysb + 2; + dx_ext = dx0 + 0 - 2 * SQUISH_CONSTANT_2D; + dy_ext = dy0 - 2 - 2 * SQUISH_CONSTANT_2D; + } + } else { // (1,0) and (0,1) are the closest two vertices. + dx_ext = dx0; + dy_ext = dy0; + xsv_ext = xsb; + ysv_ext = ysb; + } + xsb += 1; + ysb += 1; + dx0 = dx0 - 1 - 2 * SQUISH_CONSTANT_2D; + dy0 = dy0 - 1 - 2 * SQUISH_CONSTANT_2D; + } + + // Contribution (0,0) or (1,1) + double attn0 = 2 - dx0 * dx0 - dy0 * dy0; + if (attn0 > 0) { + attn0 *= attn0; + value += attn0 * attn0 * extrapolate(xsb, ysb, dx0, dy0); + } + + // Extra Vertex + double attn_ext = 2 - dx_ext * dx_ext - dy_ext * dy_ext; + if (attn_ext > 0) { + attn_ext *= attn_ext; + value += attn_ext * attn_ext * extrapolate(xsv_ext, ysv_ext, dx_ext, dy_ext); + } + + return value / NORM_CONSTANT_2D; + } + + // 3D OpenSimplex Noise. + public double eval(double x, double y, double z) { + + // Place input coordinates on simplectic honeycomb. + double stretchOffset = (x + y + z) * STRETCH_CONSTANT_3D; + double xs = x + stretchOffset; + double ys = y + stretchOffset; + double zs = z + stretchOffset; + + // Floor to get simplectic honeycomb coordinates of rhombohedron + // (stretched cube) super-cell origin. + int xsb = fastFloor(xs); + int ysb = fastFloor(ys); + int zsb = fastFloor(zs); + + // Skew out to get actual coordinates of rhombohedron origin. We'll need + // these later. + double squishOffset = (xsb + ysb + zsb) * SQUISH_CONSTANT_3D; + double xb = xsb + squishOffset; + double yb = ysb + squishOffset; + double zb = zsb + squishOffset; + + // Compute simplectic honeycomb coordinates relative to rhombohedral + // origin. + double xins = xs - xsb; + double yins = ys - ysb; + double zins = zs - zsb; + + // Sum those together to get a value that determines which region we're + // in. + double inSum = xins + yins + zins; + + // Positions relative to origin point. + double dx0 = x - xb; + double dy0 = y - yb; + double dz0 = z - zb; + + // We'll be defining these inside the next block and using them + // afterwards. + double dx_ext0, dy_ext0, dz_ext0; + double dx_ext1, dy_ext1, dz_ext1; + int xsv_ext0, ysv_ext0, zsv_ext0; + int xsv_ext1, ysv_ext1, zsv_ext1; + + double value = 0; + if (inSum <= 1) { // We're inside the tetrahedron (3-Simplex) at (0,0,0) + + // Determine which two of (0,0,1), (0,1,0), (1,0,0) are closest. + byte aPoint = 0x01; + double aScore = xins; + byte bPoint = 0x02; + double bScore = yins; + if (aScore >= bScore && zins > bScore) { + bScore = zins; + bPoint = 0x04; + } else if (aScore < bScore && zins > aScore) { + aScore = zins; + aPoint = 0x04; + } + + // Now we determine the two lattice points not part of the + // tetrahedron that may contribute. + // This depends on the closest two tetrahedral vertices, including + // (0,0,0) + double wins = 1 - inSum; + if (wins > aScore || wins > bScore) { // (0,0,0) is one of the + // closest two tetrahedral + // vertices. + byte c = (bScore > aScore ? bPoint : aPoint); // Our other + // closest + // vertex is the + // closest out + // of a and b. + + if ((c & 0x01) == 0) { + xsv_ext0 = xsb - 1; + xsv_ext1 = xsb; + dx_ext0 = dx0 + 1; + dx_ext1 = dx0; + } else { + xsv_ext0 = xsv_ext1 = xsb + 1; + dx_ext0 = dx_ext1 = dx0 - 1; + } + + if ((c & 0x02) == 0) { + ysv_ext0 = ysv_ext1 = ysb; + dy_ext0 = dy_ext1 = dy0; + if ((c & 0x01) == 0) { + ysv_ext1 -= 1; + dy_ext1 += 1; + } else { + ysv_ext0 -= 1; + dy_ext0 += 1; + } + } else { + ysv_ext0 = ysv_ext1 = ysb + 1; + dy_ext0 = dy_ext1 = dy0 - 1; + } + + if ((c & 0x04) == 0) { + zsv_ext0 = zsb; + zsv_ext1 = zsb - 1; + dz_ext0 = dz0; + dz_ext1 = dz0 + 1; + } else { + zsv_ext0 = zsv_ext1 = zsb + 1; + dz_ext0 = dz_ext1 = dz0 - 1; + } + } else { // (0,0,0) is not one of the closest two tetrahedral + // vertices. + byte c = (byte) (aPoint | bPoint); // Our two extra vertices are + // determined by the closest + // two. + + if ((c & 0x01) == 0) { + xsv_ext0 = xsb; + xsv_ext1 = xsb - 1; + dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_3D; + dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D; + } else { + xsv_ext0 = xsv_ext1 = xsb + 1; + dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; + dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; + } + + if ((c & 0x02) == 0) { + ysv_ext0 = ysb; + ysv_ext1 = ysb - 1; + dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_3D; + dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D; + } else { + ysv_ext0 = ysv_ext1 = ysb + 1; + dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; + dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; + } + + if ((c & 0x04) == 0) { + zsv_ext0 = zsb; + zsv_ext1 = zsb - 1; + dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_3D; + dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D; + } else { + zsv_ext0 = zsv_ext1 = zsb + 1; + dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; + dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; + } + } + + // Contribution (0,0,0) + double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0; + if (attn0 > 0) { + attn0 *= attn0; + value += attn0 * attn0 * extrapolate(xsb + 0, ysb + 0, zsb + 0, dx0, dy0, dz0); + } + + // Contribution (1,0,0) + double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D; + double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D; + double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D; + double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; + if (attn1 > 0) { + attn1 *= attn1; + value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1); + } + + // Contribution (0,1,0) + double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D; + double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D; + double dz2 = dz1; + double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; + if (attn2 > 0) { + attn2 *= attn2; + value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2); + } + + // Contribution (0,0,1) + double dx3 = dx2; + double dy3 = dy1; + double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D; + double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; + if (attn3 > 0) { + attn3 *= attn3; + value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3); + } + } else if (inSum >= 2) { // We're inside the tetrahedron (3-Simplex) at + // (1,1,1) + + // Determine which two tetrahedral vertices are the closest, out of + // (1,1,0), (1,0,1), (0,1,1) but not (1,1,1). + byte aPoint = 0x06; + double aScore = xins; + byte bPoint = 0x05; + double bScore = yins; + if (aScore <= bScore && zins < bScore) { + bScore = zins; + bPoint = 0x03; + } else if (aScore > bScore && zins < aScore) { + aScore = zins; + aPoint = 0x03; + } + + // Now we determine the two lattice points not part of the + // tetrahedron that may contribute. + // This depends on the closest two tetrahedral vertices, including + // (1,1,1) + double wins = 3 - inSum; + if (wins < aScore || wins < bScore) { // (1,1,1) is one of the + // closest two tetrahedral + // vertices. + byte c = (bScore < aScore ? bPoint : aPoint); // Our other + // closest + // vertex is the + // closest out + // of a and b. + + if ((c & 0x01) != 0) { + xsv_ext0 = xsb + 2; + xsv_ext1 = xsb + 1; + dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_3D; + dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; + } else { + xsv_ext0 = xsv_ext1 = xsb; + dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_3D; + } + + if ((c & 0x02) != 0) { + ysv_ext0 = ysv_ext1 = ysb + 1; + dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; + if ((c & 0x01) != 0) { + ysv_ext1 += 1; + dy_ext1 -= 1; + } else { + ysv_ext0 += 1; + dy_ext0 -= 1; + } + } else { + ysv_ext0 = ysv_ext1 = ysb; + dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_3D; + } + + if ((c & 0x04) != 0) { + zsv_ext0 = zsb + 1; + zsv_ext1 = zsb + 2; + dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; + dz_ext1 = dz0 - 2 - 3 * SQUISH_CONSTANT_3D; + } else { + zsv_ext0 = zsv_ext1 = zsb; + dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_3D; + } + } else { // (1,1,1) is not one of the closest two tetrahedral + // vertices. + byte c = (byte) (aPoint & bPoint); // Our two extra vertices are + // determined by the closest + // two. + + if ((c & 0x01) != 0) { + xsv_ext0 = xsb + 1; + xsv_ext1 = xsb + 2; + dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; + dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D; + } else { + xsv_ext0 = xsv_ext1 = xsb; + dx_ext0 = dx0 - SQUISH_CONSTANT_3D; + dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; + } + + if ((c & 0x02) != 0) { + ysv_ext0 = ysb + 1; + ysv_ext1 = ysb + 2; + dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; + dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D; + } else { + ysv_ext0 = ysv_ext1 = ysb; + dy_ext0 = dy0 - SQUISH_CONSTANT_3D; + dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; + } + + if ((c & 0x04) != 0) { + zsv_ext0 = zsb + 1; + zsv_ext1 = zsb + 2; + dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; + dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D; + } else { + zsv_ext0 = zsv_ext1 = zsb; + dz_ext0 = dz0 - SQUISH_CONSTANT_3D; + dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; + } + } + + // Contribution (1,1,0) + double dx3 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; + double dy3 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; + double dz3 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D; + double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; + if (attn3 > 0) { + attn3 *= attn3; + value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx3, dy3, dz3); + } + + // Contribution (1,0,1) + double dx2 = dx3; + double dy2 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D; + double dz2 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; + double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; + if (attn2 > 0) { + attn2 *= attn2; + value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx2, dy2, dz2); + } + + // Contribution (0,1,1) + double dx1 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D; + double dy1 = dy3; + double dz1 = dz2; + double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; + if (attn1 > 0) { + attn1 *= attn1; + value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx1, dy1, dz1); + } + + // Contribution (1,1,1) + dx0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; + dy0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; + dz0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; + double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0; + if (attn0 > 0) { + attn0 *= attn0; + value += attn0 * attn0 * extrapolate(xsb + 1, ysb + 1, zsb + 1, dx0, dy0, dz0); + } + } else { // We're inside the octahedron (Rectified 3-Simplex) in + // between. + double aScore; + byte aPoint; + boolean aIsFurtherSide; + double bScore; + byte bPoint; + boolean bIsFurtherSide; + + // Decide between point (0,0,1) and (1,1,0) as closest + double p1 = xins + yins; + if (p1 > 1) { + aScore = p1 - 1; + aPoint = 0x03; + aIsFurtherSide = true; + } else { + aScore = 1 - p1; + aPoint = 0x04; + aIsFurtherSide = false; + } + + // Decide between point (0,1,0) and (1,0,1) as closest + double p2 = xins + zins; + if (p2 > 1) { + bScore = p2 - 1; + bPoint = 0x05; + bIsFurtherSide = true; + } else { + bScore = 1 - p2; + bPoint = 0x02; + bIsFurtherSide = false; + } + + // The closest out of the two (1,0,0) and (0,1,1) will replace the + // furthest out of the two decided above, if closer. + double p3 = yins + zins; + if (p3 > 1) { + double score = p3 - 1; + if (aScore <= bScore && aScore < score) { + aScore = score; + aPoint = 0x06; + aIsFurtherSide = true; + } else if (aScore > bScore && bScore < score) { + bScore = score; + bPoint = 0x06; + bIsFurtherSide = true; + } + } else { + double score = 1 - p3; + if (aScore <= bScore && aScore < score) { + aScore = score; + aPoint = 0x01; + aIsFurtherSide = false; + } else if (aScore > bScore && bScore < score) { + bScore = score; + bPoint = 0x01; + bIsFurtherSide = false; + } + } + + // Where each of the two closest points are determines how the extra + // two vertices are calculated. + if (aIsFurtherSide == bIsFurtherSide) { + if (aIsFurtherSide) { // Both closest points on (1,1,1) side + + // One of the two extra points is (1,1,1) + dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; + dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; + dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; + xsv_ext0 = xsb + 1; + ysv_ext0 = ysb + 1; + zsv_ext0 = zsb + 1; + + // Other extra point is based on the shared axis. + byte c = (byte) (aPoint & bPoint); + if ((c & 0x01) != 0) { + dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D; + dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; + dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; + xsv_ext1 = xsb + 2; + ysv_ext1 = ysb; + zsv_ext1 = zsb; + } else if ((c & 0x02) != 0) { + dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; + dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D; + dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; + xsv_ext1 = xsb; + ysv_ext1 = ysb + 2; + zsv_ext1 = zsb; + } else { + dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; + dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; + dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D; + xsv_ext1 = xsb; + ysv_ext1 = ysb; + zsv_ext1 = zsb + 2; + } + } else {// Both closest points on (0,0,0) side + + // One of the two extra points is (0,0,0) + dx_ext0 = dx0; + dy_ext0 = dy0; + dz_ext0 = dz0; + xsv_ext0 = xsb; + ysv_ext0 = ysb; + zsv_ext0 = zsb; + + // Other extra point is based on the omitted axis. + byte c = (byte) (aPoint | bPoint); + if ((c & 0x01) == 0) { + dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D; + dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; + dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; + xsv_ext1 = xsb - 1; + ysv_ext1 = ysb + 1; + zsv_ext1 = zsb + 1; + } else if ((c & 0x02) == 0) { + dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; + dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D; + dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; + xsv_ext1 = xsb + 1; + ysv_ext1 = ysb - 1; + zsv_ext1 = zsb + 1; + } else { + dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; + dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; + dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D; + xsv_ext1 = xsb + 1; + ysv_ext1 = ysb + 1; + zsv_ext1 = zsb - 1; + } + } + } else { // One point on (0,0,0) side, one point on (1,1,1) side + byte c1, c2; + if (aIsFurtherSide) { + c1 = aPoint; + c2 = bPoint; + } else { + c1 = bPoint; + c2 = aPoint; + } + + // One contribution is a permutation of (1,1,-1) + if ((c1 & 0x01) == 0) { + dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_3D; + dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; + dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; + xsv_ext0 = xsb - 1; + ysv_ext0 = ysb + 1; + zsv_ext0 = zsb + 1; + } else if ((c1 & 0x02) == 0) { + dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; + dy_ext0 = dy0 + 1 - SQUISH_CONSTANT_3D; + dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; + xsv_ext0 = xsb + 1; + ysv_ext0 = ysb - 1; + zsv_ext0 = zsb + 1; + } else { + dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; + dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; + dz_ext0 = dz0 + 1 - SQUISH_CONSTANT_3D; + xsv_ext0 = xsb + 1; + ysv_ext0 = ysb + 1; + zsv_ext0 = zsb - 1; + } + + // One contribution is a permutation of (0,0,2) + dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; + dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; + dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; + xsv_ext1 = xsb; + ysv_ext1 = ysb; + zsv_ext1 = zsb; + if ((c2 & 0x01) != 0) { + dx_ext1 -= 2; + xsv_ext1 += 2; + } else if ((c2 & 0x02) != 0) { + dy_ext1 -= 2; + ysv_ext1 += 2; + } else { + dz_ext1 -= 2; + zsv_ext1 += 2; + } + } + + // Contribution (1,0,0) + double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D; + double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D; + double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D; + double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; + if (attn1 > 0) { + attn1 *= attn1; + value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1); + } + + // Contribution (0,1,0) + double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D; + double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D; + double dz2 = dz1; + double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; + if (attn2 > 0) { + attn2 *= attn2; + value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2); + } + + // Contribution (0,0,1) + double dx3 = dx2; + double dy3 = dy1; + double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D; + double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; + if (attn3 > 0) { + attn3 *= attn3; + value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3); + } + + // Contribution (1,1,0) + double dx4 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; + double dy4 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; + double dz4 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D; + double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4; + if (attn4 > 0) { + attn4 *= attn4; + value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx4, dy4, dz4); + } + + // Contribution (1,0,1) + double dx5 = dx4; + double dy5 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D; + double dz5 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; + double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5; + if (attn5 > 0) { + attn5 *= attn5; + value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx5, dy5, dz5); + } + + // Contribution (0,1,1) + double dx6 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D; + double dy6 = dy4; + double dz6 = dz5; + double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6; + if (attn6 > 0) { + attn6 *= attn6; + value += attn6 * attn6 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx6, dy6, dz6); + } + } + + // First extra vertex + double attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0; + if (attn_ext0 > 0) { + attn_ext0 *= attn_ext0; + value += attn_ext0 * attn_ext0 * extrapolate(xsv_ext0, ysv_ext0, zsv_ext0, dx_ext0, dy_ext0, dz_ext0); + } + + // Second extra vertex + double attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1; + if (attn_ext1 > 0) { + attn_ext1 *= attn_ext1; + value += attn_ext1 * attn_ext1 * extrapolate(xsv_ext1, ysv_ext1, zsv_ext1, dx_ext1, dy_ext1, dz_ext1); + } + + return value / NORM_CONSTANT_3D; + } + + // 4D OpenSimplex Noise. + public double eval(double x, double y, double z, double w) { + + // Place input coordinates on simplectic honeycomb. + double stretchOffset = (x + y + z + w) * STRETCH_CONSTANT_4D; + double xs = x + stretchOffset; + double ys = y + stretchOffset; + double zs = z + stretchOffset; + double ws = w + stretchOffset; + + // Floor to get simplectic honeycomb coordinates of rhombo-hypercube + // super-cell origin. + int xsb = fastFloor(xs); + int ysb = fastFloor(ys); + int zsb = fastFloor(zs); + int wsb = fastFloor(ws); + + // Skew out to get actual coordinates of stretched rhombo-hypercube + // origin. We'll need these later. + double squishOffset = (xsb + ysb + zsb + wsb) * SQUISH_CONSTANT_4D; + double xb = xsb + squishOffset; + double yb = ysb + squishOffset; + double zb = zsb + squishOffset; + double wb = wsb + squishOffset; + + // Compute simplectic honeycomb coordinates relative to rhombo-hypercube + // origin. + double xins = xs - xsb; + double yins = ys - ysb; + double zins = zs - zsb; + double wins = ws - wsb; + + // Sum those together to get a value that determines which region we're + // in. + double inSum = xins + yins + zins + wins; + + // Positions relative to origin point. + double dx0 = x - xb; + double dy0 = y - yb; + double dz0 = z - zb; + double dw0 = w - wb; + + // We'll be defining these inside the next block and using them + // afterwards. + double dx_ext0, dy_ext0, dz_ext0, dw_ext0; + double dx_ext1, dy_ext1, dz_ext1, dw_ext1; + double dx_ext2, dy_ext2, dz_ext2, dw_ext2; + int xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0; + int xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1; + int xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2; + + double value = 0; + if (inSum <= 1) { // We're inside the pentachoron (4-Simplex) at + // (0,0,0,0) + + // Determine which two of (0,0,0,1), (0,0,1,0), (0,1,0,0), (1,0,0,0) + // are closest. + byte aPoint = 0x01; + double aScore = xins; + byte bPoint = 0x02; + double bScore = yins; + if (aScore >= bScore && zins > bScore) { + bScore = zins; + bPoint = 0x04; + } else if (aScore < bScore && zins > aScore) { + aScore = zins; + aPoint = 0x04; + } + if (aScore >= bScore && wins > bScore) { + bScore = wins; + bPoint = 0x08; + } else if (aScore < bScore && wins > aScore) { + aScore = wins; + aPoint = 0x08; + } + + // Now we determine the three lattice points not part of the + // pentachoron that may contribute. + // This depends on the closest two pentachoron vertices, including + // (0,0,0,0) + double uins = 1 - inSum; + if (uins > aScore || uins > bScore) { // (0,0,0,0) is one of the + // closest two pentachoron + // vertices. + byte c = (bScore > aScore ? bPoint : aPoint); // Our other + // closest + // vertex is the + // closest out + // of a and b. + if ((c & 0x01) == 0) { + xsv_ext0 = xsb - 1; + xsv_ext1 = xsv_ext2 = xsb; + dx_ext0 = dx0 + 1; + dx_ext1 = dx_ext2 = dx0; + } else { + xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1; + dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 1; + } + + if ((c & 0x02) == 0) { + ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; + dy_ext0 = dy_ext1 = dy_ext2 = dy0; + if ((c & 0x01) == 0x01) { + ysv_ext0 -= 1; + dy_ext0 += 1; + } else { + ysv_ext1 -= 1; + dy_ext1 += 1; + } + } else { + ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; + dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1; + } + + if ((c & 0x04) == 0) { + zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; + dz_ext0 = dz_ext1 = dz_ext2 = dz0; + if ((c & 0x03) != 0) { + if ((c & 0x03) == 0x03) { + zsv_ext0 -= 1; + dz_ext0 += 1; + } else { + zsv_ext1 -= 1; + dz_ext1 += 1; + } + } else { + zsv_ext2 -= 1; + dz_ext2 += 1; + } + } else { + zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; + dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1; + } + + if ((c & 0x08) == 0) { + wsv_ext0 = wsv_ext1 = wsb; + wsv_ext2 = wsb - 1; + dw_ext0 = dw_ext1 = dw0; + dw_ext2 = dw0 + 1; + } else { + wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1; + dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 1; + } + } else { // (0,0,0,0) is not one of the closest two pentachoron + // vertices. + byte c = (byte) (aPoint | bPoint); // Our three extra vertices + // are determined by the + // closest two. + + if ((c & 0x01) == 0) { + xsv_ext0 = xsv_ext2 = xsb; + xsv_ext1 = xsb - 1; + dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D; + dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_4D; + dx_ext2 = dx0 - SQUISH_CONSTANT_4D; + } else { + xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1; + dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; + dx_ext1 = dx_ext2 = dx0 - 1 - SQUISH_CONSTANT_4D; + } + + if ((c & 0x02) == 0) { + ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; + dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D; + dy_ext1 = dy_ext2 = dy0 - SQUISH_CONSTANT_4D; + if ((c & 0x01) == 0x01) { + ysv_ext1 -= 1; + dy_ext1 += 1; + } else { + ysv_ext2 -= 1; + dy_ext2 += 1; + } + } else { + ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; + dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; + dy_ext1 = dy_ext2 = dy0 - 1 - SQUISH_CONSTANT_4D; + } + + if ((c & 0x04) == 0) { + zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; + dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D; + dz_ext1 = dz_ext2 = dz0 - SQUISH_CONSTANT_4D; + if ((c & 0x03) == 0x03) { + zsv_ext1 -= 1; + dz_ext1 += 1; + } else { + zsv_ext2 -= 1; + dz_ext2 += 1; + } + } else { + zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; + dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; + dz_ext1 = dz_ext2 = dz0 - 1 - SQUISH_CONSTANT_4D; + } + + if ((c & 0x08) == 0) { + wsv_ext0 = wsv_ext1 = wsb; + wsv_ext2 = wsb - 1; + dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D; + dw_ext1 = dw0 - SQUISH_CONSTANT_4D; + dw_ext2 = dw0 + 1 - SQUISH_CONSTANT_4D; + } else { + wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1; + dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; + dw_ext1 = dw_ext2 = dw0 - 1 - SQUISH_CONSTANT_4D; + } + } + + // Contribution (0,0,0,0) + double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0; + if (attn0 > 0) { + attn0 *= attn0; + value += attn0 * attn0 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 0, dx0, dy0, dz0, dw0); + } + + // Contribution (1,0,0,0) + double dx1 = dx0 - 1 - SQUISH_CONSTANT_4D; + double dy1 = dy0 - 0 - SQUISH_CONSTANT_4D; + double dz1 = dz0 - 0 - SQUISH_CONSTANT_4D; + double dw1 = dw0 - 0 - SQUISH_CONSTANT_4D; + double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; + if (attn1 > 0) { + attn1 *= attn1; + value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1); + } + + // Contribution (0,1,0,0) + double dx2 = dx0 - 0 - SQUISH_CONSTANT_4D; + double dy2 = dy0 - 1 - SQUISH_CONSTANT_4D; + double dz2 = dz1; + double dw2 = dw1; + double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; + if (attn2 > 0) { + attn2 *= attn2; + value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2); + } + + // Contribution (0,0,1,0) + double dx3 = dx2; + double dy3 = dy1; + double dz3 = dz0 - 1 - SQUISH_CONSTANT_4D; + double dw3 = dw1; + double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; + if (attn3 > 0) { + attn3 *= attn3; + value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3); + } + + // Contribution (0,0,0,1) + double dx4 = dx2; + double dy4 = dy1; + double dz4 = dz1; + double dw4 = dw0 - 1 - SQUISH_CONSTANT_4D; + double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; + if (attn4 > 0) { + attn4 *= attn4; + value += attn4 * attn4 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4); + } + } else if (inSum >= 3) { // We're inside the pentachoron (4-Simplex) at + // (1,1,1,1) + // Determine which two of (1,1,1,0), + // (1,1,0,1), (1,0,1,1), (0,1,1,1) + // are closest. + byte aPoint = 0x0E; + double aScore = xins; + byte bPoint = 0x0D; + double bScore = yins; + if (aScore <= bScore && zins < bScore) { + bScore = zins; + bPoint = 0x0B; + } else if (aScore > bScore && zins < aScore) { + aScore = zins; + aPoint = 0x0B; + } + if (aScore <= bScore && wins < bScore) { + bScore = wins; + bPoint = 0x07; + } else if (aScore > bScore && wins < aScore) { + aScore = wins; + aPoint = 0x07; + } + + // Now we determine the three lattice points not part of the + // pentachoron that may contribute. + // This depends on the closest two pentachoron vertices, including + // (0,0,0,0) + double uins = 4 - inSum; + if (uins < aScore || uins < bScore) { // (1,1,1,1) is one of the + // closest two pentachoron + // vertices. + byte c = (bScore < aScore ? bPoint : aPoint); // Our other + // closest + // vertex is the + // closest out + // of a and b. + + if ((c & 0x01) != 0) { + xsv_ext0 = xsb + 2; + xsv_ext1 = xsv_ext2 = xsb + 1; + dx_ext0 = dx0 - 2 - 4 * SQUISH_CONSTANT_4D; + dx_ext1 = dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D; + } else { + xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb; + dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 4 * SQUISH_CONSTANT_4D; + } + + if ((c & 0x02) != 0) { + ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; + dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D; + if ((c & 0x01) != 0) { + ysv_ext1 += 1; + dy_ext1 -= 1; + } else { + ysv_ext0 += 1; + dy_ext0 -= 1; + } + } else { + ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; + dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 4 * SQUISH_CONSTANT_4D; + } + + if ((c & 0x04) != 0) { + zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; + dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D; + if ((c & 0x03) != 0x03) { + if ((c & 0x03) == 0) { + zsv_ext0 += 1; + dz_ext0 -= 1; + } else { + zsv_ext1 += 1; + dz_ext1 -= 1; + } + } else { + zsv_ext2 += 1; + dz_ext2 -= 1; + } + } else { + zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; + dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 4 * SQUISH_CONSTANT_4D; + } + + if ((c & 0x08) != 0) { + wsv_ext0 = wsv_ext1 = wsb + 1; + wsv_ext2 = wsb + 2; + dw_ext0 = dw_ext1 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D; + dw_ext2 = dw0 - 2 - 4 * SQUISH_CONSTANT_4D; + } else { + wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb; + dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 4 * SQUISH_CONSTANT_4D; + } + } else { // (1,1,1,1) is not one of the closest two pentachoron + // vertices. + byte c = (byte) (aPoint & bPoint); // Our three extra vertices + // are determined by the + // closest two. + + if ((c & 0x01) != 0) { + xsv_ext0 = xsv_ext2 = xsb + 1; + xsv_ext1 = xsb + 2; + dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; + dx_ext1 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D; + dx_ext2 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; + } else { + xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb; + dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D; + dx_ext1 = dx_ext2 = dx0 - 3 * SQUISH_CONSTANT_4D; + } + + if ((c & 0x02) != 0) { + ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; + dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; + dy_ext1 = dy_ext2 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; + if ((c & 0x01) != 0) { + ysv_ext2 += 1; + dy_ext2 -= 1; + } else { + ysv_ext1 += 1; + dy_ext1 -= 1; + } + } else { + ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; + dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D; + dy_ext1 = dy_ext2 = dy0 - 3 * SQUISH_CONSTANT_4D; + } + + if ((c & 0x04) != 0) { + zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; + dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; + dz_ext1 = dz_ext2 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; + if ((c & 0x03) != 0) { + zsv_ext2 += 1; + dz_ext2 -= 1; + } else { + zsv_ext1 += 1; + dz_ext1 -= 1; + } + } else { + zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; + dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D; + dz_ext1 = dz_ext2 = dz0 - 3 * SQUISH_CONSTANT_4D; + } + + if ((c & 0x08) != 0) { + wsv_ext0 = wsv_ext1 = wsb + 1; + wsv_ext2 = wsb + 2; + dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; + dw_ext1 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; + dw_ext2 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D; + } else { + wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb; + dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D; + dw_ext1 = dw_ext2 = dw0 - 3 * SQUISH_CONSTANT_4D; + } + } + + // Contribution (1,1,1,0) + double dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; + double dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; + double dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; + double dw4 = dw0 - 3 * SQUISH_CONSTANT_4D; + double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; + if (attn4 > 0) { + attn4 *= attn4; + value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4); + } + + // Contribution (1,1,0,1) + double dx3 = dx4; + double dy3 = dy4; + double dz3 = dz0 - 3 * SQUISH_CONSTANT_4D; + double dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; + double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; + if (attn3 > 0) { + attn3 *= attn3; + value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3); + } + + // Contribution (1,0,1,1) + double dx2 = dx4; + double dy2 = dy0 - 3 * SQUISH_CONSTANT_4D; + double dz2 = dz4; + double dw2 = dw3; + double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; + if (attn2 > 0) { + attn2 *= attn2; + value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2); + } + + // Contribution (0,1,1,1) + double dx1 = dx0 - 3 * SQUISH_CONSTANT_4D; + double dz1 = dz4; + double dy1 = dy4; + double dw1 = dw3; + double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; + if (attn1 > 0) { + attn1 *= attn1; + value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1); + } + + // Contribution (1,1,1,1) + dx0 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D; + dy0 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D; + dz0 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D; + dw0 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D; + double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0; + if (attn0 > 0) { + attn0 *= attn0; + value += attn0 * attn0 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 1, dx0, dy0, dz0, dw0); + } + } else if (inSum <= 2) { // We're inside the first dispentachoron + // (Rectified 4-Simplex) + double aScore; + byte aPoint; + boolean aIsBiggerSide = true; + double bScore; + byte bPoint; + boolean bIsBiggerSide = true; + + // Decide between (1,1,0,0) and (0,0,1,1) + if (xins + yins > zins + wins) { + aScore = xins + yins; + aPoint = 0x03; + } else { + aScore = zins + wins; + aPoint = 0x0C; + } + + // Decide between (1,0,1,0) and (0,1,0,1) + if (xins + zins > yins + wins) { + bScore = xins + zins; + bPoint = 0x05; + } else { + bScore = yins + wins; + bPoint = 0x0A; + } + + // Closer between (1,0,0,1) and (0,1,1,0) will replace the further + // of a and b, if closer. + if (xins + wins > yins + zins) { + double score = xins + wins; + if (aScore >= bScore && score > bScore) { + bScore = score; + bPoint = 0x09; + } else if (aScore < bScore && score > aScore) { + aScore = score; + aPoint = 0x09; + } + } else { + double score = yins + zins; + if (aScore >= bScore && score > bScore) { + bScore = score; + bPoint = 0x06; + } else if (aScore < bScore && score > aScore) { + aScore = score; + aPoint = 0x06; + } + } + + // Decide if (1,0,0,0) is closer. + double p1 = 2 - inSum + xins; + if (aScore >= bScore && p1 > bScore) { + bScore = p1; + bPoint = 0x01; + bIsBiggerSide = false; + } else if (aScore < bScore && p1 > aScore) { + aScore = p1; + aPoint = 0x01; + aIsBiggerSide = false; + } + + // Decide if (0,1,0,0) is closer. + double p2 = 2 - inSum + yins; + if (aScore >= bScore && p2 > bScore) { + bScore = p2; + bPoint = 0x02; + bIsBiggerSide = false; + } else if (aScore < bScore && p2 > aScore) { + aScore = p2; + aPoint = 0x02; + aIsBiggerSide = false; + } + + // Decide if (0,0,1,0) is closer. + double p3 = 2 - inSum + zins; + if (aScore >= bScore && p3 > bScore) { + bScore = p3; + bPoint = 0x04; + bIsBiggerSide = false; + } else if (aScore < bScore && p3 > aScore) { + aScore = p3; + aPoint = 0x04; + aIsBiggerSide = false; + } + + // Decide if (0,0,0,1) is closer. + double p4 = 2 - inSum + wins; + if (aScore >= bScore && p4 > bScore) { + bScore = p4; + bPoint = 0x08; + bIsBiggerSide = false; + } else if (aScore < bScore && p4 > aScore) { + aScore = p4; + aPoint = 0x08; + aIsBiggerSide = false; + } + + // Where each of the two closest points are determines how the extra + // three vertices are calculated. + if (aIsBiggerSide == bIsBiggerSide) { + if (aIsBiggerSide) { // Both closest points on the bigger side + byte c1 = (byte) (aPoint | bPoint); + byte c2 = (byte) (aPoint & bPoint); + if ((c1 & 0x01) == 0) { + xsv_ext0 = xsb; + xsv_ext1 = xsb - 1; + dx_ext0 = dx0 - 3 * SQUISH_CONSTANT_4D; + dx_ext1 = dx0 + 1 - 2 * SQUISH_CONSTANT_4D; + } else { + xsv_ext0 = xsv_ext1 = xsb + 1; + dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; + dx_ext1 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; + } + + if ((c1 & 0x02) == 0) { + ysv_ext0 = ysb; + ysv_ext1 = ysb - 1; + dy_ext0 = dy0 - 3 * SQUISH_CONSTANT_4D; + dy_ext1 = dy0 + 1 - 2 * SQUISH_CONSTANT_4D; + } else { + ysv_ext0 = ysv_ext1 = ysb + 1; + dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; + dy_ext1 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; + } + + if ((c1 & 0x04) == 0) { + zsv_ext0 = zsb; + zsv_ext1 = zsb - 1; + dz_ext0 = dz0 - 3 * SQUISH_CONSTANT_4D; + dz_ext1 = dz0 + 1 - 2 * SQUISH_CONSTANT_4D; + } else { + zsv_ext0 = zsv_ext1 = zsb + 1; + dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; + dz_ext1 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; + } + + if ((c1 & 0x08) == 0) { + wsv_ext0 = wsb; + wsv_ext1 = wsb - 1; + dw_ext0 = dw0 - 3 * SQUISH_CONSTANT_4D; + dw_ext1 = dw0 + 1 - 2 * SQUISH_CONSTANT_4D; + } else { + wsv_ext0 = wsv_ext1 = wsb + 1; + dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; + dw_ext1 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; + } + + // One combination is a permutation of (0,0,0,2) based on c2 + xsv_ext2 = xsb; + ysv_ext2 = ysb; + zsv_ext2 = zsb; + wsv_ext2 = wsb; + dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D; + dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D; + dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D; + dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D; + if ((c2 & 0x01) != 0) { + xsv_ext2 += 2; + dx_ext2 -= 2; + } else if ((c2 & 0x02) != 0) { + ysv_ext2 += 2; + dy_ext2 -= 2; + } else if ((c2 & 0x04) != 0) { + zsv_ext2 += 2; + dz_ext2 -= 2; + } else { + wsv_ext2 += 2; + dw_ext2 -= 2; + } + + } else { // Both closest points on the smaller side + // One of the two extra points is (0,0,0,0) + xsv_ext2 = xsb; + ysv_ext2 = ysb; + zsv_ext2 = zsb; + wsv_ext2 = wsb; + dx_ext2 = dx0; + dy_ext2 = dy0; + dz_ext2 = dz0; + dw_ext2 = dw0; + + // Other two points are based on the omitted axes. + byte c = (byte) (aPoint | bPoint); + + if ((c & 0x01) == 0) { + xsv_ext0 = xsb - 1; + xsv_ext1 = xsb; + dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D; + dx_ext1 = dx0 - SQUISH_CONSTANT_4D; + } else { + xsv_ext0 = xsv_ext1 = xsb + 1; + dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D; + } + + if ((c & 0x02) == 0) { + ysv_ext0 = ysv_ext1 = ysb; + dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D; + if ((c & 0x01) == 0x01) { + ysv_ext0 -= 1; + dy_ext0 += 1; + } else { + ysv_ext1 -= 1; + dy_ext1 += 1; + } + } else { + ysv_ext0 = ysv_ext1 = ysb + 1; + dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D; + } + + if ((c & 0x04) == 0) { + zsv_ext0 = zsv_ext1 = zsb; + dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D; + if ((c & 0x03) == 0x03) { + zsv_ext0 -= 1; + dz_ext0 += 1; + } else { + zsv_ext1 -= 1; + dz_ext1 += 1; + } + } else { + zsv_ext0 = zsv_ext1 = zsb + 1; + dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D; + } + + if ((c & 0x08) == 0) { + wsv_ext0 = wsb; + wsv_ext1 = wsb - 1; + dw_ext0 = dw0 - SQUISH_CONSTANT_4D; + dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D; + } else { + wsv_ext0 = wsv_ext1 = wsb + 1; + dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D; + } + + } + } else { // One point on each "side" + byte c1, c2; + if (aIsBiggerSide) { + c1 = aPoint; + c2 = bPoint; + } else { + c1 = bPoint; + c2 = aPoint; + } + + // Two contributions are the bigger-sided point with each 0 + // replaced with -1. + if ((c1 & 0x01) == 0) { + xsv_ext0 = xsb - 1; + xsv_ext1 = xsb; + dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D; + dx_ext1 = dx0 - SQUISH_CONSTANT_4D; + } else { + xsv_ext0 = xsv_ext1 = xsb + 1; + dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D; + } + + if ((c1 & 0x02) == 0) { + ysv_ext0 = ysv_ext1 = ysb; + dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D; + if ((c1 & 0x01) == 0x01) { + ysv_ext0 -= 1; + dy_ext0 += 1; + } else { + ysv_ext1 -= 1; + dy_ext1 += 1; + } + } else { + ysv_ext0 = ysv_ext1 = ysb + 1; + dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D; + } + + if ((c1 & 0x04) == 0) { + zsv_ext0 = zsv_ext1 = zsb; + dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D; + if ((c1 & 0x03) == 0x03) { + zsv_ext0 -= 1; + dz_ext0 += 1; + } else { + zsv_ext1 -= 1; + dz_ext1 += 1; + } + } else { + zsv_ext0 = zsv_ext1 = zsb + 1; + dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D; + } + + if ((c1 & 0x08) == 0) { + wsv_ext0 = wsb; + wsv_ext1 = wsb - 1; + dw_ext0 = dw0 - SQUISH_CONSTANT_4D; + dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D; + } else { + wsv_ext0 = wsv_ext1 = wsb + 1; + dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D; + } + + // One contribution is a permutation of (0,0,0,2) based on the + // smaller-sided point + xsv_ext2 = xsb; + ysv_ext2 = ysb; + zsv_ext2 = zsb; + wsv_ext2 = wsb; + dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D; + dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D; + dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D; + dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D; + if ((c2 & 0x01) != 0) { + xsv_ext2 += 2; + dx_ext2 -= 2; + } else if ((c2 & 0x02) != 0) { + ysv_ext2 += 2; + dy_ext2 -= 2; + } else if ((c2 & 0x04) != 0) { + zsv_ext2 += 2; + dz_ext2 -= 2; + } else { + wsv_ext2 += 2; + dw_ext2 -= 2; + } + } + + // Contribution (1,0,0,0) + double dx1 = dx0 - 1 - SQUISH_CONSTANT_4D; + double dy1 = dy0 - 0 - SQUISH_CONSTANT_4D; + double dz1 = dz0 - 0 - SQUISH_CONSTANT_4D; + double dw1 = dw0 - 0 - SQUISH_CONSTANT_4D; + double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; + if (attn1 > 0) { + attn1 *= attn1; + value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1); + } + + // Contribution (0,1,0,0) + double dx2 = dx0 - 0 - SQUISH_CONSTANT_4D; + double dy2 = dy0 - 1 - SQUISH_CONSTANT_4D; + double dz2 = dz1; + double dw2 = dw1; + double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; + if (attn2 > 0) { + attn2 *= attn2; + value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2); + } + + // Contribution (0,0,1,0) + double dx3 = dx2; + double dy3 = dy1; + double dz3 = dz0 - 1 - SQUISH_CONSTANT_4D; + double dw3 = dw1; + double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; + if (attn3 > 0) { + attn3 *= attn3; + value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3); + } + + // Contribution (0,0,0,1) + double dx4 = dx2; + double dy4 = dy1; + double dz4 = dz1; + double dw4 = dw0 - 1 - SQUISH_CONSTANT_4D; + double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; + if (attn4 > 0) { + attn4 *= attn4; + value += attn4 * attn4 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4); + } + + // Contribution (1,1,0,0) + double dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; + double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5; + if (attn5 > 0) { + attn5 *= attn5; + value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5); + } + + // Contribution (1,0,1,0) + double dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; + double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6; + if (attn6 > 0) { + attn6 *= attn6; + value += attn6 * attn6 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6); + } + + // Contribution (1,0,0,1) + double dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; + double attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7; + if (attn7 > 0) { + attn7 *= attn7; + value += attn7 * attn7 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7); + } + + // Contribution (0,1,1,0) + double dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; + double attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8; + if (attn8 > 0) { + attn8 *= attn8; + value += attn8 * attn8 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8); + } + + // Contribution (0,1,0,1) + double dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; + double attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9; + if (attn9 > 0) { + attn9 *= attn9; + value += attn9 * attn9 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9); + } + + // Contribution (0,0,1,1) + double dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; + double attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10; + if (attn10 > 0) { + attn10 *= attn10; + value += attn10 * attn10 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10); + } + } else { // We're inside the second dispentachoron (Rectified 4-Simplex) + double aScore; + byte aPoint; + boolean aIsBiggerSide = true; + double bScore; + byte bPoint; + boolean bIsBiggerSide = true; + + // Decide between (0,0,1,1) and (1,1,0,0) + if (xins + yins < zins + wins) { + aScore = xins + yins; + aPoint = 0x0C; + } else { + aScore = zins + wins; + aPoint = 0x03; + } + + // Decide between (0,1,0,1) and (1,0,1,0) + if (xins + zins < yins + wins) { + bScore = xins + zins; + bPoint = 0x0A; + } else { + bScore = yins + wins; + bPoint = 0x05; + } + + // Closer between (0,1,1,0) and (1,0,0,1) will replace the further + // of a and b, if closer. + if (xins + wins < yins + zins) { + double score = xins + wins; + if (aScore <= bScore && score < bScore) { + bScore = score; + bPoint = 0x06; + } else if (aScore > bScore && score < aScore) { + aScore = score; + aPoint = 0x06; + } + } else { + double score = yins + zins; + if (aScore <= bScore && score < bScore) { + bScore = score; + bPoint = 0x09; + } else if (aScore > bScore && score < aScore) { + aScore = score; + aPoint = 0x09; + } + } + + // Decide if (0,1,1,1) is closer. + double p1 = 3 - inSum + xins; + if (aScore <= bScore && p1 < bScore) { + bScore = p1; + bPoint = 0x0E; + bIsBiggerSide = false; + } else if (aScore > bScore && p1 < aScore) { + aScore = p1; + aPoint = 0x0E; + aIsBiggerSide = false; + } + + // Decide if (1,0,1,1) is closer. + double p2 = 3 - inSum + yins; + if (aScore <= bScore && p2 < bScore) { + bScore = p2; + bPoint = 0x0D; + bIsBiggerSide = false; + } else if (aScore > bScore && p2 < aScore) { + aScore = p2; + aPoint = 0x0D; + aIsBiggerSide = false; + } + + // Decide if (1,1,0,1) is closer. + double p3 = 3 - inSum + zins; + if (aScore <= bScore && p3 < bScore) { + bScore = p3; + bPoint = 0x0B; + bIsBiggerSide = false; + } else if (aScore > bScore && p3 < aScore) { + aScore = p3; + aPoint = 0x0B; + aIsBiggerSide = false; + } + + // Decide if (1,1,1,0) is closer. + double p4 = 3 - inSum + wins; + if (aScore <= bScore && p4 < bScore) { + bScore = p4; + bPoint = 0x07; + bIsBiggerSide = false; + } else if (aScore > bScore && p4 < aScore) { + aScore = p4; + aPoint = 0x07; + aIsBiggerSide = false; + } + + // Where each of the two closest points are determines how the extra + // three vertices are calculated. + if (aIsBiggerSide == bIsBiggerSide) { + if (aIsBiggerSide) { // Both closest points on the bigger side + byte c1 = (byte) (aPoint & bPoint); + byte c2 = (byte) (aPoint | bPoint); + + // Two contributions are permutations of (0,0,0,1) and + // (0,0,0,2) based on c1 + xsv_ext0 = xsv_ext1 = xsb; + ysv_ext0 = ysv_ext1 = ysb; + zsv_ext0 = zsv_ext1 = zsb; + wsv_ext0 = wsv_ext1 = wsb; + dx_ext0 = dx0 - SQUISH_CONSTANT_4D; + dy_ext0 = dy0 - SQUISH_CONSTANT_4D; + dz_ext0 = dz0 - SQUISH_CONSTANT_4D; + dw_ext0 = dw0 - SQUISH_CONSTANT_4D; + dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_4D; + dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_4D; + dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_4D; + dw_ext1 = dw0 - 2 * SQUISH_CONSTANT_4D; + if ((c1 & 0x01) != 0) { + xsv_ext0 += 1; + dx_ext0 -= 1; + xsv_ext1 += 2; + dx_ext1 -= 2; + } else if ((c1 & 0x02) != 0) { + ysv_ext0 += 1; + dy_ext0 -= 1; + ysv_ext1 += 2; + dy_ext1 -= 2; + } else if ((c1 & 0x04) != 0) { + zsv_ext0 += 1; + dz_ext0 -= 1; + zsv_ext1 += 2; + dz_ext1 -= 2; + } else { + wsv_ext0 += 1; + dw_ext0 -= 1; + wsv_ext1 += 2; + dw_ext1 -= 2; + } + + // One contribution is a permutation of (1,1,1,-1) based on + // c2 + xsv_ext2 = xsb + 1; + ysv_ext2 = ysb + 1; + zsv_ext2 = zsb + 1; + wsv_ext2 = wsb + 1; + dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; + dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; + dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; + dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; + if ((c2 & 0x01) == 0) { + xsv_ext2 -= 2; + dx_ext2 += 2; + } else if ((c2 & 0x02) == 0) { + ysv_ext2 -= 2; + dy_ext2 += 2; + } else if ((c2 & 0x04) == 0) { + zsv_ext2 -= 2; + dz_ext2 += 2; + } else { + wsv_ext2 -= 2; + dw_ext2 += 2; + } + } else { // Both closest points on the smaller side + // One of the two extra points is (1,1,1,1) + xsv_ext2 = xsb + 1; + ysv_ext2 = ysb + 1; + zsv_ext2 = zsb + 1; + wsv_ext2 = wsb + 1; + dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D; + dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D; + dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D; + dw_ext2 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D; + + // Other two points are based on the shared axes. + byte c = (byte) (aPoint & bPoint); + + if ((c & 0x01) != 0) { + xsv_ext0 = xsb + 2; + xsv_ext1 = xsb + 1; + dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D; + dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; + } else { + xsv_ext0 = xsv_ext1 = xsb; + dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D; + } + + if ((c & 0x02) != 0) { + ysv_ext0 = ysv_ext1 = ysb + 1; + dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; + if ((c & 0x01) == 0) { + ysv_ext0 += 1; + dy_ext0 -= 1; + } else { + ysv_ext1 += 1; + dy_ext1 -= 1; + } + } else { + ysv_ext0 = ysv_ext1 = ysb; + dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D; + } + + if ((c & 0x04) != 0) { + zsv_ext0 = zsv_ext1 = zsb + 1; + dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; + if ((c & 0x03) == 0) { + zsv_ext0 += 1; + dz_ext0 -= 1; + } else { + zsv_ext1 += 1; + dz_ext1 -= 1; + } + } else { + zsv_ext0 = zsv_ext1 = zsb; + dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D; + } + + if ((c & 0x08) != 0) { + wsv_ext0 = wsb + 1; + wsv_ext1 = wsb + 2; + dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; + dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D; + } else { + wsv_ext0 = wsv_ext1 = wsb; + dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D; + } + } + } else { // One point on each "side" + byte c1, c2; + if (aIsBiggerSide) { + c1 = aPoint; + c2 = bPoint; + } else { + c1 = bPoint; + c2 = aPoint; + } + + // Two contributions are the bigger-sided point with each 1 + // replaced with 2. + if ((c1 & 0x01) != 0) { + xsv_ext0 = xsb + 2; + xsv_ext1 = xsb + 1; + dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D; + dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; + } else { + xsv_ext0 = xsv_ext1 = xsb; + dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D; + } + + if ((c1 & 0x02) != 0) { + ysv_ext0 = ysv_ext1 = ysb + 1; + dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; + if ((c1 & 0x01) == 0) { + ysv_ext0 += 1; + dy_ext0 -= 1; + } else { + ysv_ext1 += 1; + dy_ext1 -= 1; + } + } else { + ysv_ext0 = ysv_ext1 = ysb; + dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D; + } + + if ((c1 & 0x04) != 0) { + zsv_ext0 = zsv_ext1 = zsb + 1; + dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; + if ((c1 & 0x03) == 0) { + zsv_ext0 += 1; + dz_ext0 -= 1; + } else { + zsv_ext1 += 1; + dz_ext1 -= 1; + } + } else { + zsv_ext0 = zsv_ext1 = zsb; + dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D; + } + + if ((c1 & 0x08) != 0) { + wsv_ext0 = wsb + 1; + wsv_ext1 = wsb + 2; + dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; + dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D; + } else { + wsv_ext0 = wsv_ext1 = wsb; + dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D; + } + + // One contribution is a permutation of (1,1,1,-1) based on the + // smaller-sided point + xsv_ext2 = xsb + 1; + ysv_ext2 = ysb + 1; + zsv_ext2 = zsb + 1; + wsv_ext2 = wsb + 1; + dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; + dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; + dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; + dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; + if ((c2 & 0x01) == 0) { + xsv_ext2 -= 2; + dx_ext2 += 2; + } else if ((c2 & 0x02) == 0) { + ysv_ext2 -= 2; + dy_ext2 += 2; + } else if ((c2 & 0x04) == 0) { + zsv_ext2 -= 2; + dz_ext2 += 2; + } else { + wsv_ext2 -= 2; + dw_ext2 += 2; + } + } + + // Contribution (1,1,1,0) + double dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; + double dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; + double dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; + double dw4 = dw0 - 3 * SQUISH_CONSTANT_4D; + double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; + if (attn4 > 0) { + attn4 *= attn4; + value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4); + } + + // Contribution (1,1,0,1) + double dx3 = dx4; + double dy3 = dy4; + double dz3 = dz0 - 3 * SQUISH_CONSTANT_4D; + double dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; + double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; + if (attn3 > 0) { + attn3 *= attn3; + value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3); + } + + // Contribution (1,0,1,1) + double dx2 = dx4; + double dy2 = dy0 - 3 * SQUISH_CONSTANT_4D; + double dz2 = dz4; + double dw2 = dw3; + double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; + if (attn2 > 0) { + attn2 *= attn2; + value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2); + } + + // Contribution (0,1,1,1) + double dx1 = dx0 - 3 * SQUISH_CONSTANT_4D; + double dz1 = dz4; + double dy1 = dy4; + double dw1 = dw3; + double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; + if (attn1 > 0) { + attn1 *= attn1; + value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1); + } + + // Contribution (1,1,0,0) + double dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; + double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5; + if (attn5 > 0) { + attn5 *= attn5; + value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5); + } + + // Contribution (1,0,1,0) + double dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; + double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6; + if (attn6 > 0) { + attn6 *= attn6; + value += attn6 * attn6 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6); + } + + // Contribution (1,0,0,1) + double dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; + double attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7; + if (attn7 > 0) { + attn7 *= attn7; + value += attn7 * attn7 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7); + } + + // Contribution (0,1,1,0) + double dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; + double attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8; + if (attn8 > 0) { + attn8 *= attn8; + value += attn8 * attn8 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8); + } + + // Contribution (0,1,0,1) + double dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; + double attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9; + if (attn9 > 0) { + attn9 *= attn9; + value += attn9 * attn9 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9); + } + + // Contribution (0,0,1,1) + double dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; + double dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; + double dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; + double attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10; + if (attn10 > 0) { + attn10 *= attn10; + value += attn10 * attn10 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10); + } + } + + // First extra vertex + double attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0 - dw_ext0 * dw_ext0; + if (attn_ext0 > 0) { + attn_ext0 *= attn_ext0; + value += attn_ext0 * attn_ext0 * extrapolate( + xsv_ext0, + ysv_ext0, + zsv_ext0, + wsv_ext0, + dx_ext0, + dy_ext0, + dz_ext0, + dw_ext0 + ); + } + + // Second extra vertex + double attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1 - dw_ext1 * dw_ext1; + if (attn_ext1 > 0) { + attn_ext1 *= attn_ext1; + value += attn_ext1 * attn_ext1 * extrapolate( + xsv_ext1, + ysv_ext1, + zsv_ext1, + wsv_ext1, + dx_ext1, + dy_ext1, + dz_ext1, + dw_ext1 + ); + } + + // Third extra vertex + double attn_ext2 = 2 - dx_ext2 * dx_ext2 - dy_ext2 * dy_ext2 - dz_ext2 * dz_ext2 - dw_ext2 * dw_ext2; + if (attn_ext2 > 0) { + attn_ext2 *= attn_ext2; + value += attn_ext2 * attn_ext2 * extrapolate( + xsv_ext2, + ysv_ext2, + zsv_ext2, + wsv_ext2, + dx_ext2, + dy_ext2, + dz_ext2, + dw_ext2 + ); + } + + return value / NORM_CONSTANT_4D; + } + + private double extrapolate(int xsb, int ysb, double dx, double dy) { + int index = perm[(perm[xsb & 0xFF] + ysb) & 0xFF] & 0x0E; + return gradients2D[index] * dx + gradients2D[index + 1] * dy; + } + + private double extrapolate(int xsb, int ysb, int zsb, double dx, double dy, double dz) { + int index = permGradIndex3D[(perm[(perm[xsb & 0xFF] + ysb) & 0xFF] + zsb) & 0xFF]; + return gradients3D[index] * dx + gradients3D[index + 1] * dy + gradients3D[index + 2] * dz; + } + + private double extrapolate(int xsb, int ysb, int zsb, int wsb, double dx, double dy, double dz, double dw) { + int index = perm[(perm[(perm[(perm[xsb & 0xFF] + ysb) & 0xFF] + zsb) & 0xFF] + wsb) & 0xFF] & 0xFC; + return gradients4D[index] * dx + gradients4D[index + 1] * dy + gradients4D[index + 2] * dz + gradients4D[index + 3] * dw; + } + + private static int fastFloor(double x) { + int xi = (int) x; + return x < xi ? xi - 1 : xi; + } + + // Gradients for 2D. They approximate the directions to the + // vertices of an octagon from the center. + private static final byte[] gradients2D = new byte[]{5, 2, 2, 5, -5, 2, -2, 5, 5, -2, 2, -5, -5, -2, -2, -5,}; + + // Gradients for 3D. They approximate the directions to the + // vertices of a rhombicuboctahedron from the center, skewed so + // that the triangular and square facets can be inscribed inside + // circles of the same radius. + private static final byte[] gradients3D = new byte[]{ + -11, + 4, + 4, + -4, + 11, + 4, + -4, + 4, + 11, + 11, + 4, + 4, + 4, + 11, + 4, + 4, + 4, + 11, + -11, + -4, + 4, + -4, + -11, + 4, + -4, + -4, + 11, + 11, + -4, + 4, + 4, + -11, + 4, + 4, + -4, + 11, + -11, + 4, + -4, + -4, + 11, + -4, + -4, + 4, + -11, + 11, + 4, + -4, + 4, + 11, + -4, + 4, + 4, + -11, + -11, + -4, + -4, + -4, + -11, + -4, + -4, + -4, + -11, + 11, + -4, + -4, + 4, + -11, + -4, + 4, + -4, + -11, + }; + + // Gradients for 4D. They approximate the directions to the + // vertices of a disprismatotesseractihexadecachoron from the center, + // skewed so that the tetrahedral and cubic facets can be inscribed inside + // spheres of the same radius. + private static final byte[] gradients4D = new byte[]{ + 3, + 1, + 1, + 1, + 1, + 3, + 1, + 1, + 1, + 1, + 3, + 1, + 1, + 1, + 1, + 3, + -3, + 1, + 1, + 1, + -1, + 3, + 1, + 1, + -1, + 1, + 3, + 1, + -1, + 1, + 1, + 3, + 3, + -1, + 1, + 1, + 1, + -3, + 1, + 1, + 1, + -1, + 3, + 1, + 1, + -1, + 1, + 3, + -3, + -1, + 1, + 1, + -1, + -3, + 1, + 1, + -1, + -1, + 3, + 1, + -1, + -1, + 1, + 3, + 3, + 1, + -1, + 1, + 1, + 3, + -1, + 1, + 1, + 1, + -3, + 1, + 1, + 1, + -1, + 3, + -3, + 1, + -1, + 1, + -1, + 3, + -1, + 1, + -1, + 1, + -3, + 1, + -1, + 1, + -1, + 3, + 3, + -1, + -1, + 1, + 1, + -3, + -1, + 1, + 1, + -1, + -3, + 1, + 1, + -1, + -1, + 3, + -3, + -1, + -1, + 1, + -1, + -3, + -1, + 1, + -1, + -1, + -3, + 1, + -1, + -1, + -1, + 3, + 3, + 1, + 1, + -1, + 1, + 3, + 1, + -1, + 1, + 1, + 3, + -1, + 1, + 1, + 1, + -3, + -3, + 1, + 1, + -1, + -1, + 3, + 1, + -1, + -1, + 1, + 3, + -1, + -1, + 1, + 1, + -3, + 3, + -1, + 1, + -1, + 1, + -3, + 1, + -1, + 1, + -1, + 3, + -1, + 1, + -1, + 1, + -3, + -3, + -1, + 1, + -1, + -1, + -3, + 1, + -1, + -1, + -1, + 3, + -1, + -1, + -1, + 1, + -3, + 3, + 1, + -1, + -1, + 1, + 3, + -1, + -1, + 1, + 1, + -3, + -1, + 1, + 1, + -1, + -3, + -3, + 1, + -1, + -1, + -1, + 3, + -1, + -1, + -1, + 1, + -3, + -1, + -1, + 1, + -1, + -3, + 3, + -1, + -1, + -1, + 1, + -3, + -1, + -1, + 1, + -1, + -3, + -1, + 1, + -1, + -1, + -3, + -3, + -1, + -1, + -1, + -1, + -3, + -1, + -1, + -1, + -1, + -3, + -1, + -1, + -1, + -1, + -3, + }; +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/particle/FireflyParticle.java b/src/main/java/org/betterx/betterend/particle/FireflyParticle.java new file mode 100644 index 00000000..5d0be84a --- /dev/null +++ b/src/main/java/org/betterx/betterend/particle/FireflyParticle.java @@ -0,0 +1,100 @@ +package org.betterx.betterend.particle; + +import org.betterx.bclib.util.MHelper; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.SimpleAnimatedParticle; +import net.minecraft.client.particle.SpriteSet; +import net.minecraft.core.particles.SimpleParticleType; +import net.minecraft.util.Mth; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class FireflyParticle extends SimpleAnimatedParticle { + private double preVX; + private double preVY; + private double preVZ; + private double nextVX; + private double nextVY; + private double nextVZ; + + protected FireflyParticle( + ClientLevel world, + double x, + double y, + double z, + SpriteSet sprites, + double r, + double g, + double b + ) { + super(world, x, y, z, sprites, 0); + setSprite(sprites.get(random)); + this.lifetime = MHelper.randRange(150, 300, random); + this.quadSize = MHelper.randRange(0.05F, 0.15F, random); + this.setFadeColor(15916745); + this.setSpriteFromAge(sprites); + this.setAlpha(0); + + preVX = random.nextGaussian() * 0.02; + preVY = random.nextGaussian() * 0.02; + preVZ = random.nextGaussian() * 0.02; + + nextVX = random.nextGaussian() * 0.02; + nextVY = random.nextGaussian() * 0.02; + nextVZ = random.nextGaussian() * 0.02; + } + + @Override + public void tick() { + int ticks = this.age & 31; + if (ticks == 0) { + preVX = nextVX; + preVY = nextVY; + preVZ = nextVZ; + nextVX = random.nextGaussian() * 0.02; + nextVY = random.nextGaussian() * 0.02; + nextVZ = random.nextGaussian() * 0.02; + } + double delta = (double) ticks / 31.0; + + this.xd = Mth.lerp(delta, preVX, nextVX); + this.yd = Mth.lerp(delta, preVY, nextVY); + this.zd = Mth.lerp(delta, preVZ, nextVZ); + + if (this.age <= 60) { + this.setAlpha(this.age / 60F); + } else if (this.age > lifetime - 60) { + this.setAlpha((lifetime - this.age) / 60F); + } + + super.tick(); + } + + @Environment(EnvType.CLIENT) + public static class FireflyParticleFactory implements ParticleProvider { + private final SpriteSet sprites; + + public FireflyParticleFactory(SpriteSet sprites) { + this.sprites = sprites; + } + + @Override + public Particle createParticle( + SimpleParticleType type, + ClientLevel world, + double x, + double y, + double z, + double vX, + double vY, + double vZ + ) { + return new FireflyParticle(world, x, y, z, sprites, 1, 1, 1); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/particle/InfusionParticle.java b/src/main/java/org/betterx/betterend/particle/InfusionParticle.java new file mode 100644 index 00000000..66f66f6f --- /dev/null +++ b/src/main/java/org/betterx/betterend/particle/InfusionParticle.java @@ -0,0 +1,78 @@ +package org.betterx.betterend.particle; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.*; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class InfusionParticle extends TextureSheetParticle { + + private final SpriteSet spriteProvider; + + public InfusionParticle( + ClientLevel clientWorld, + double x, + double y, + double z, + double velocityX, + double velocityY, + double velocityZ, + float[] palette, + SpriteSet spriteProvider + ) { + super(clientWorld, x, y, z, 0.0, 0.0, 0.0); + this.setSpriteFromAge(spriteProvider); + this.spriteProvider = spriteProvider; + this.setColor(palette[0], palette[1], palette[2]); + this.setAlpha(palette[3]); + this.xd = velocityX * 0.1D; + this.yd = velocityY * 0.1D; + this.zd = velocityZ * 0.1D; + this.lifetime = (int) (3.0F / (this.random.nextFloat() * 0.9F + 0.1F)); + this.quadSize *= 0.9F; + } + + @Override + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; + } + + @Override + public void tick() { + this.xo = this.x; + this.yo = this.y; + this.zo = this.z; + if (this.age++ >= this.lifetime) { + this.remove(); + } else { + this.setSpriteFromAge(spriteProvider); + double velocityX = 2.0D * this.xd * this.random.nextDouble(); + double velocityY = 3.0D * this.yd * this.random.nextDouble(); + double velocityZ = 2.0D * this.zd * this.random.nextDouble(); + this.move(velocityX, velocityY, velocityZ); + } + } + + @Environment(EnvType.CLIENT) + public static class InfusionFactory implements ParticleProvider { + private final SpriteSet spriteProvider; + + public InfusionFactory(SpriteSet spriteProvider) { + this.spriteProvider = spriteProvider; + } + + public Particle createParticle( + InfusionParticleType particleType, + ClientLevel clientWorld, + double d, + double e, + double f, + double g, + double h, + double i + ) { + return new InfusionParticle(clientWorld, d, e, f, g, h, i, particleType.getPalette(), this.spriteProvider); + } + } +} diff --git a/src/main/java/org/betterx/betterend/particle/InfusionParticleType.java b/src/main/java/org/betterx/betterend/particle/InfusionParticleType.java new file mode 100644 index 00000000..2b0e4f32 --- /dev/null +++ b/src/main/java/org/betterx/betterend/particle/InfusionParticleType.java @@ -0,0 +1,89 @@ +package org.betterx.betterend.particle; + +import org.betterx.betterend.registry.EndParticles; +import org.betterx.ui.ColorUtil; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.serialization.Codec; +import net.minecraft.commands.arguments.item.ItemInput; +import net.minecraft.commands.arguments.item.ItemParser; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.Registry; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleType; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.item.ItemStack; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class InfusionParticleType extends ParticleType implements ParticleOptions { + public static final Codec CODEC = ItemStack.CODEC.xmap(itemStack -> new InfusionParticleType( + EndParticles.INFUSION, + itemStack + ), infusionParticleType -> infusionParticleType.itemStack); + + @SuppressWarnings("deprecation") + public static final ParticleOptions.Deserializer PARAMETERS_FACTORY = new ParticleOptions.Deserializer() { + public InfusionParticleType fromCommand( + ParticleType particleType, + StringReader stringReader + ) throws CommandSyntaxException { + stringReader.expect(' '); + ItemParser.ItemResult itemResult = ItemParser.parseForItem( + HolderLookup.forRegistry(Registry.ITEM), + stringReader + ); + ItemStack itemStack = new ItemInput(itemResult.item(), itemResult.nbt()).createItemStack(1, false); + + return new InfusionParticleType(particleType, itemStack); + } + + public InfusionParticleType fromNetwork( + ParticleType particleType, + FriendlyByteBuf packetByteBuf + ) { + return new InfusionParticleType(particleType, packetByteBuf.readItem()); + } + }; + + private final ParticleType type; + private final ItemStack itemStack; + + public InfusionParticleType(ParticleType particleType, ItemStack stack) { + super(true, PARAMETERS_FACTORY); + this.type = particleType; + this.itemStack = stack; + } + + public InfusionParticleType(ItemStack stack) { + this(EndParticles.INFUSION, stack); + } + + @Environment(EnvType.CLIENT) + public float[] getPalette() { + int color = ColorUtil.extractColor(itemStack.getItem()); + return ColorUtil.toFloatArray(color); + } + + @Override + public ParticleType getType() { + return this.type; + } + + @Override + public void writeToNetwork(FriendlyByteBuf buffer) { + buffer.writeItem(itemStack); + } + + @Override + public String writeToString() { + return Registry.PARTICLE_TYPE.getKey(this).toString(); + } + + @Override + public Codec codec() { + return CODEC; + } +} diff --git a/src/main/java/org/betterx/betterend/particle/ParticleBlackSpore.java b/src/main/java/org/betterx/betterend/particle/ParticleBlackSpore.java new file mode 100644 index 00000000..c32f38ff --- /dev/null +++ b/src/main/java/org/betterx/betterend/particle/ParticleBlackSpore.java @@ -0,0 +1,107 @@ +package org.betterx.betterend.particle; + +import org.betterx.bclib.util.MHelper; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.*; +import net.minecraft.core.particles.SimpleParticleType; +import net.minecraft.util.Mth; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class ParticleBlackSpore extends SimpleAnimatedParticle { + private double preVX; + private double preVY; + private double preVZ; + private double nextVX; + private double nextVY; + private double nextVZ; + + protected ParticleBlackSpore( + ClientLevel world, + double x, + double y, + double z, + double r, + double g, + double b, + SpriteSet sprites + ) { + super(world, x, y, z, sprites, 0); + setSprite(sprites.get(random)); + + this.lifetime = MHelper.randRange(30, 60, random); + this.quadSize = MHelper.randRange(0.05F, 0.15F, random); + this.setColor(1, 1, 1); + this.setAlpha(0); + + preVX = random.nextGaussian() * 0.015; + preVY = 0; + preVZ = random.nextGaussian() * 0.015; + + nextVX = random.nextGaussian() * 0.015; + nextVY = random.nextFloat() * 0.02 + 0.01; + nextVZ = random.nextGaussian() * 0.015; + } + + @Override + public void tick() { + int ticks = this.age & 15; + if (ticks == 0) { + preVX = nextVX; + preVY = nextVY; + preVZ = nextVZ; + nextVX = random.nextGaussian() * 0.015; + nextVY = random.nextFloat() * 0.02 + 0.01; + nextVZ = random.nextGaussian() * 0.015; + } + double delta = (double) ticks / 15.0; + + if (this.age <= 15) { + this.setAlpha(this.age / 15F); + } else if (this.age >= this.lifetime - 15) { + this.setAlpha((this.lifetime - this.age) / 15F); + } + + if (this.age >= this.lifetime) { + this.remove(); + } + + this.xd = Mth.lerp(delta, preVX, nextVX); + this.yd = Mth.lerp(delta, preVY, nextVY); + this.zd = Mth.lerp(delta, preVZ, nextVZ); + + super.tick(); + } + + @Override + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; + } + + @Environment(EnvType.CLIENT) + public static class FactoryBlackSpore implements ParticleProvider { + + private final SpriteSet sprites; + + public FactoryBlackSpore(SpriteSet sprites) { + this.sprites = sprites; + } + + @Override + public Particle createParticle( + SimpleParticleType type, + ClientLevel world, + double x, + double y, + double z, + double vX, + double vY, + double vZ + ) { + return new ParticleBlackSpore(world, x, y, z, 1, 1, 1, sprites); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/particle/ParticleGeyser.java b/src/main/java/org/betterx/betterend/particle/ParticleGeyser.java new file mode 100644 index 00000000..4ce6b320 --- /dev/null +++ b/src/main/java/org/betterx/betterend/particle/ParticleGeyser.java @@ -0,0 +1,93 @@ +package org.betterx.betterend.particle; + +import org.betterx.bclib.util.MHelper; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.*; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.particles.SimpleParticleType; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class ParticleGeyser extends TextureSheetParticle { + private final MutableBlockPos mut = new MutableBlockPos(); + private boolean changeDir = false; + private boolean check = true; + + protected ParticleGeyser( + ClientLevel world, + double x, + double y, + double z, + double vx, + double vy, + double vz, + SpriteSet sprites + ) { + super(world, x, y, z, vx, vy, vz); + pickSprite(sprites); + this.lifetime = MHelper.randRange(400, 800, random); + this.quadSize = MHelper.randRange(0.5F, 1.0F, random); + this.xd = vx; + this.zd = vz; + this.yo = y - 0.125; + } + + @Override + public void tick() { + + if (this.yo == this.y || this.age > this.lifetime) { + this.remove(); + } else { + if (this.age >= this.lifetime - 200) { + this.setAlpha((this.lifetime - this.age) / 200F); + } + + this.quadSize += 0.005F; + this.yd = 0.125; + + if (changeDir) { + changeDir = false; + check = false; + this.xd += MHelper.randRange(-0.2, 0.2, random); + this.zd += MHelper.randRange(-0.2, 0.2, random); + } else if (check) { + changeDir = level.getBlockState(mut.set(x, y, z)).getFluidState().isEmpty(); + this.xd = 0; + this.zd = 0; + } + } + super.tick(); + } + + @Override + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; + } + + @Environment(EnvType.CLIENT) + public static class FactoryGeyser implements ParticleProvider { + + private final SpriteSet sprites; + + public FactoryGeyser(SpriteSet sprites) { + this.sprites = sprites; + } + + @Override + public Particle createParticle( + SimpleParticleType type, + ClientLevel world, + double x, + double y, + double z, + double vX, + double vY, + double vZ + ) { + return new ParticleGeyser(world, x, y, z, 0, 0.125, 0, sprites); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/particle/ParticleGlowingSphere.java b/src/main/java/org/betterx/betterend/particle/ParticleGlowingSphere.java new file mode 100644 index 00000000..c649c688 --- /dev/null +++ b/src/main/java/org/betterx/betterend/particle/ParticleGlowingSphere.java @@ -0,0 +1,96 @@ +package org.betterx.betterend.particle; + +import org.betterx.bclib.util.MHelper; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.SimpleAnimatedParticle; +import net.minecraft.client.particle.SpriteSet; +import net.minecraft.core.particles.SimpleParticleType; +import net.minecraft.util.Mth; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class ParticleGlowingSphere extends SimpleAnimatedParticle { + private int ticks; + private double preVX; + private double preVY; + private double preVZ; + private double nextVX; + private double nextVY; + private double nextVZ; + + protected ParticleGlowingSphere( + ClientLevel world, + double x, + double y, + double z, + SpriteSet sprites, + double r, + double g, + double b + ) { + super(world, x, y, z, sprites, 0); + setSprite(sprites.get(random)); + this.lifetime = MHelper.randRange(150, 300, random); + this.quadSize = MHelper.randRange(0.05F, 0.15F, random); + this.setFadeColor(15916745); + this.setSpriteFromAge(sprites); + + preVX = random.nextGaussian() * 0.02; + preVY = random.nextGaussian() * 0.02; + preVZ = random.nextGaussian() * 0.02; + + nextVX = random.nextGaussian() * 0.02; + nextVY = random.nextGaussian() * 0.02; + nextVZ = random.nextGaussian() * 0.02; + } + + @Override + public void tick() { + ticks++; + if (ticks > 30) { + preVX = nextVX; + preVY = nextVY; + preVZ = nextVZ; + nextVX = random.nextGaussian() * 0.02; + nextVY = random.nextGaussian() * 0.02; + nextVZ = random.nextGaussian() * 0.02; + ticks = 0; + } + double delta = (double) ticks / 30.0; + + this.xd = Mth.lerp(delta, preVX, nextVX); + this.yd = Mth.lerp(delta, preVY, nextVY); + this.zd = Mth.lerp(delta, preVZ, nextVZ); + + super.tick(); + } + + @Environment(EnvType.CLIENT) + public static class FactoryGlowingSphere implements ParticleProvider { + + private final SpriteSet sprites; + + public FactoryGlowingSphere(SpriteSet sprites) { + this.sprites = sprites; + } + + @Override + public Particle createParticle( + SimpleParticleType type, + ClientLevel world, + double x, + double y, + double z, + double vX, + double vY, + double vZ + ) { + return new ParticleGlowingSphere(world, x, y, z, sprites, 1, 1, 1); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/particle/ParticleJungleSpore.java b/src/main/java/org/betterx/betterend/particle/ParticleJungleSpore.java new file mode 100644 index 00000000..1cb75ee5 --- /dev/null +++ b/src/main/java/org/betterx/betterend/particle/ParticleJungleSpore.java @@ -0,0 +1,87 @@ +package org.betterx.betterend.particle; + +import org.betterx.bclib.util.MHelper; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.SimpleAnimatedParticle; +import net.minecraft.client.particle.SpriteSet; +import net.minecraft.core.particles.SimpleParticleType; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class ParticleJungleSpore extends SimpleAnimatedParticle { + + protected ParticleJungleSpore( + ClientLevel world, + double x, + double y, + double z, + SpriteSet sprites, + double r, + double g, + double b + ) { + super(world, x, y, z, sprites, 0); + setSprite(sprites.get(random)); + this.lifetime = MHelper.randRange(150, 300, random); + this.quadSize = MHelper.randRange(0.05F, 0.15F, random); + this.setFadeColor(15916745); + this.setSpriteFromAge(sprites); + this.setAlpha(0); + } + + @Override + public void tick() { + super.tick(); + + int ticks = this.age % 30; + if (ticks == 0) { + this.xd = random.nextGaussian() * 0.02; + this.yd = random.nextFloat() * 0.02 + 0.02; + this.zd = random.nextGaussian() * 0.02; + ticks = 0; + } + + if (this.age <= 30) { + float delta = ticks / 30F; + this.setAlpha(delta); + } else if (this.age >= this.lifetime) { + this.setAlpha(0); + } else if (this.age >= this.lifetime - 30) { + this.setAlpha((this.lifetime - this.age) / 30F); + } else { + this.setAlpha(1); + } + + this.yd -= 0.001F; + this.xd *= 0.99F; + this.zd *= 0.99F; + } + + @Environment(EnvType.CLIENT) + public static class FactoryJungleSpore implements ParticleProvider { + private final SpriteSet sprites; + + public FactoryJungleSpore(SpriteSet sprites) { + this.sprites = sprites; + } + + @Override + public Particle createParticle( + SimpleParticleType type, + ClientLevel world, + double x, + double y, + double z, + double vX, + double vY, + double vZ + ) { + return new ParticleJungleSpore(world, x, y, z, sprites, 1, 1, 1); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/particle/ParticleSnowflake.java b/src/main/java/org/betterx/betterend/particle/ParticleSnowflake.java new file mode 100644 index 00000000..e0d8b926 --- /dev/null +++ b/src/main/java/org/betterx/betterend/particle/ParticleSnowflake.java @@ -0,0 +1,111 @@ +package org.betterx.betterend.particle; + +import org.betterx.bclib.util.MHelper; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.*; +import net.minecraft.core.particles.SimpleParticleType; +import net.minecraft.util.Mth; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class ParticleSnowflake extends TextureSheetParticle { + private int ticks; + private double preVX; + private double preVY; + private double preVZ; + private double nextVX; + private double nextVY; + private double nextVZ; + + protected ParticleSnowflake( + ClientLevel world, + double x, + double y, + double z, + double r, + double g, + double b, + SpriteSet sprites + ) { + super(world, x, y, z, r, g, b); + pickSprite(sprites); + + this.lifetime = MHelper.randRange(150, 300, random); + this.quadSize = MHelper.randRange(0.05F, 0.2F, random); + this.setAlpha(0F); + + preVX = random.nextGaussian() * 0.015; + preVY = random.nextGaussian() * 0.015; + preVZ = random.nextGaussian() * 0.015; + + nextVX = random.nextGaussian() * 0.015; + nextVY = random.nextGaussian() * 0.015; + nextVZ = random.nextGaussian() * 0.015; + } + + @Override + public void tick() { + ticks++; + if (ticks > 200) { + preVX = nextVX; + preVY = nextVY; + preVZ = nextVZ; + nextVX = random.nextGaussian() * 0.015; + nextVY = random.nextGaussian() * 0.015; + nextVZ = random.nextGaussian() * 0.015; + if (random.nextInt(4) == 0) { + nextVY = Math.abs(nextVY); + } + ticks = 0; + } + double delta = (double) ticks / 200.0; + + if (this.age <= 40) { + this.setAlpha(this.age / 40F); + } else if (this.age >= this.lifetime - 40) { + this.setAlpha((this.lifetime - this.age) / 40F); + } + + if (this.age >= this.lifetime) { + this.remove(); + } + + this.xd = Mth.lerp(delta, preVX, nextVX); + this.yd = Mth.lerp(delta, preVY, nextVY); + this.zd = Mth.lerp(delta, preVZ, nextVZ); + + super.tick(); + } + + @Override + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; + } + + @Environment(EnvType.CLIENT) + public static class FactorySnowflake implements ParticleProvider { + + private final SpriteSet sprites; + + public FactorySnowflake(SpriteSet sprites) { + this.sprites = sprites; + } + + @Override + public Particle createParticle( + SimpleParticleType type, + ClientLevel world, + double x, + double y, + double z, + double vX, + double vY, + double vZ + ) { + return new ParticleSnowflake(world, x, y, z, 1, 1, 1, sprites); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/particle/ParticleSulphur.java b/src/main/java/org/betterx/betterend/particle/ParticleSulphur.java new file mode 100644 index 00000000..dd8c5aaf --- /dev/null +++ b/src/main/java/org/betterx/betterend/particle/ParticleSulphur.java @@ -0,0 +1,112 @@ +package org.betterx.betterend.particle; + +import org.betterx.bclib.util.MHelper; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.*; +import net.minecraft.core.particles.SimpleParticleType; +import net.minecraft.util.Mth; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class ParticleSulphur extends TextureSheetParticle { + private int ticks; + private double preVX; + private double preVY; + private double preVZ; + private double nextVX; + private double nextVY; + private double nextVZ; + + protected ParticleSulphur( + ClientLevel world, + double x, + double y, + double z, + double r, + double g, + double b, + SpriteSet sprites + ) { + super(world, x, y, z, r, g, b); + pickSprite(sprites); + + this.lifetime = MHelper.randRange(150, 300, random); + this.quadSize = MHelper.randRange(0.05F, 0.15F, random); + this.setColor(1, 1, 1); + this.setAlpha(0); + + preVX = random.nextGaussian() * 0.015; + preVY = random.nextGaussian() * 0.015; + preVZ = random.nextGaussian() * 0.015; + + nextVX = random.nextGaussian() * 0.015; + nextVY = random.nextGaussian() * 0.015; + nextVZ = random.nextGaussian() * 0.015; + } + + @Override + public void tick() { + ticks++; + if (ticks > 200) { + preVX = nextVX; + preVY = nextVY; + preVZ = nextVZ; + nextVX = random.nextGaussian() * 0.015; + nextVY = random.nextGaussian() * 0.015; + nextVZ = random.nextGaussian() * 0.015; + if (random.nextInt(4) == 0) { + nextVY = Math.abs(nextVY); + } + ticks = 0; + } + double delta = (double) ticks / 200.0; + + if (this.age <= 40) { + this.setAlpha(this.age / 40F); + } else if (this.age >= this.lifetime - 40) { + this.setAlpha((this.lifetime - this.age) / 40F); + } + + if (this.age >= this.lifetime) { + this.remove(); + } + + this.xd = Mth.lerp(delta, preVX, nextVX); + this.yd = Mth.lerp(delta, preVY, nextVY); + this.zd = Mth.lerp(delta, preVZ, nextVZ); + + super.tick(); + } + + @Override + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; + } + + @Environment(EnvType.CLIENT) + public static class FactorySulphur implements ParticleProvider { + + private final SpriteSet sprites; + + public FactorySulphur(SpriteSet sprites) { + this.sprites = sprites; + } + + @Override + public Particle createParticle( + SimpleParticleType type, + ClientLevel world, + double x, + double y, + double z, + double vX, + double vY, + double vZ + ) { + return new ParticleSulphur(world, x, y, z, 1, 1, 1, sprites); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/particle/ParticleTenaneaPetal.java b/src/main/java/org/betterx/betterend/particle/ParticleTenaneaPetal.java new file mode 100644 index 00000000..be8c6bee --- /dev/null +++ b/src/main/java/org/betterx/betterend/particle/ParticleTenaneaPetal.java @@ -0,0 +1,126 @@ +package org.betterx.betterend.particle; + +import org.betterx.bclib.interfaces.CustomColorProvider; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.*; +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.SimpleParticleType; +import net.minecraft.util.Mth; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class ParticleTenaneaPetal extends TextureSheetParticle { + private static BlockColor provider; + + private double preVX; + private double preVY; + private double preVZ; + private double nextVX; + private double nextVY; + private double nextVZ; + + protected ParticleTenaneaPetal( + ClientLevel world, + double x, + double y, + double z, + double r, + double g, + double b, + SpriteSet sprites + ) { + super(world, x, y, z, r, g, b); + pickSprite(sprites); + + if (provider == null) { + CustomColorProvider block = (CustomColorProvider) EndBlocks.TENANEA_FLOWERS; + provider = block.getProvider(); + } + int color = provider.getColor(null, null, new BlockPos(x, y, z), 0); + this.rCol = ((color >> 16) & 255) / 255F; + this.gCol = ((color >> 8) & 255) / 255F; + this.bCol = ((color) & 255) / 255F; + + this.lifetime = MHelper.randRange(120, 200, random); + this.quadSize = MHelper.randRange(0.05F, 0.15F, random); + this.setAlpha(0); + + preVX = 0; + preVY = 0; + preVZ = 0; + + nextVX = random.nextGaussian() * 0.02; + nextVY = -random.nextDouble() * 0.02 - 0.02; + nextVZ = random.nextGaussian() * 0.02; + } + + @Override + public int getLightColor(float tint) { + return 15728880; + } + + @Override + public void tick() { + int ticks = this.age & 63; + if (ticks == 0) { + preVX = nextVX; + preVY = nextVY; + preVZ = nextVZ; + nextVX = random.nextGaussian() * 0.02; + nextVY = -random.nextDouble() * 0.02 - 0.02; + nextVZ = random.nextGaussian() * 0.02; + } + double delta = (double) ticks / 63.0; + + if (this.age <= 40) { + this.setAlpha(this.age / 40F); + } else if (this.age >= this.lifetime - 40) { + this.setAlpha((this.lifetime - this.age) / 40F); + } + + if (this.age >= this.lifetime) { + this.remove(); + } + + this.xd = Mth.lerp(delta, preVX, nextVX); + this.yd = Mth.lerp(delta, preVY, nextVY); + this.zd = Mth.lerp(delta, preVZ, nextVZ); + + super.tick(); + } + + @Override + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; + } + + @Environment(EnvType.CLIENT) + public static class FactoryTenaneaPetal implements ParticleProvider { + + private final SpriteSet sprites; + + public FactoryTenaneaPetal(SpriteSet sprites) { + this.sprites = sprites; + } + + @Override + public Particle createParticle( + SimpleParticleType type, + ClientLevel world, + double x, + double y, + double z, + double vX, + double vY, + double vZ + ) { + return new ParticleTenaneaPetal(world, x, y, z, 1, 1, 1, sprites); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/particle/PaticlePortalSphere.java b/src/main/java/org/betterx/betterend/particle/PaticlePortalSphere.java new file mode 100644 index 00000000..d06f37a5 --- /dev/null +++ b/src/main/java/org/betterx/betterend/particle/PaticlePortalSphere.java @@ -0,0 +1,87 @@ +package org.betterx.betterend.particle; + +import org.betterx.bclib.util.MHelper; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.SimpleAnimatedParticle; +import net.minecraft.client.particle.SpriteSet; +import net.minecraft.core.particles.SimpleParticleType; +import net.minecraft.util.Mth; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +public class PaticlePortalSphere extends SimpleAnimatedParticle { + private int ticks; + private double preVX; + private double preVY; + private double preVZ; + private double nextVX; + private double nextVY; + private double nextVZ; + + public PaticlePortalSphere(ClientLevel world, double x, double y, double z, SpriteSet spriteProvider) { + super(world, x, y, z, spriteProvider, 0); + setSprite(spriteProvider.get(random)); + this.lifetime = MHelper.randRange(20, 80, random); + this.quadSize = MHelper.randRange(0.05F, 0.15F, random); + this.setColor(0xFEBBD5); + this.setFadeColor(0xBBFEE4); + this.setSpriteFromAge(spriteProvider); + + preVX = random.nextGaussian() * 0.02; + preVY = random.nextGaussian() * 0.02; + preVZ = random.nextGaussian() * 0.02; + + nextVX = random.nextGaussian() * 0.02; + nextVY = random.nextGaussian() * 0.02; + nextVZ = random.nextGaussian() * 0.02; + } + + @Override + public void tick() { + ticks++; + if (ticks > 30) { + preVX = nextVX; + preVY = nextVY; + preVZ = nextVZ; + nextVX = random.nextGaussian() * 0.02; + nextVY = random.nextGaussian() * 0.02; + nextVZ = random.nextGaussian() * 0.02; + ticks = 0; + } + double delta = (double) ticks / 30.0; + + this.xd = Mth.lerp(delta, preVX, nextVX); + this.yd = Mth.lerp(delta, preVY, nextVY); + this.zd = Mth.lerp(delta, preVZ, nextVZ); + + super.tick(); + } + + @Environment(EnvType.CLIENT) + public static class FactoryPortalSphere implements ParticleProvider { + + private final SpriteSet sprites; + + public FactoryPortalSphere(SpriteSet sprites) { + this.sprites = sprites; + } + + @Override + public Particle createParticle( + SimpleParticleType type, + ClientLevel world, + double x, + double y, + double z, + double vX, + double vY, + double vZ + ) { + return new PaticlePortalSphere(world, x, y, z, sprites); + } + } +} diff --git a/src/main/java/org/betterx/betterend/particle/SmaragdantParticle.java b/src/main/java/org/betterx/betterend/particle/SmaragdantParticle.java new file mode 100644 index 00000000..b372aa63 --- /dev/null +++ b/src/main/java/org/betterx/betterend/particle/SmaragdantParticle.java @@ -0,0 +1,107 @@ +package org.betterx.betterend.particle; + +import org.betterx.bclib.util.MHelper; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.*; +import net.minecraft.core.particles.SimpleParticleType; +import net.minecraft.util.Mth; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class SmaragdantParticle extends SimpleAnimatedParticle { + private double preVX; + private double preVY; + private double preVZ; + private double nextVX; + private double nextVY; + private double nextVZ; + + protected SmaragdantParticle( + ClientLevel world, + double x, + double y, + double z, + double r, + double g, + double b, + SpriteSet sprites + ) { + super(world, x, y, z, sprites, 0); + setSprite(sprites.get(random)); + + this.lifetime = MHelper.randRange(60, 120, random); + this.quadSize = MHelper.randRange(0.05F, 0.15F, random); + this.setColor(1, 1, 1); + this.setAlpha(0); + + preVX = random.nextGaussian() * 0.01; + preVY = random.nextGaussian() * 0.01; + preVZ = random.nextGaussian() * 0.01; + + nextVX = random.nextGaussian() * 0.01; + nextVY = random.nextGaussian() * 0.01; + nextVZ = random.nextGaussian() * 0.01; + } + + @Override + public void tick() { + int ticks = this.age & 31; + if (ticks == 0) { + preVX = nextVX; + preVY = nextVY; + preVZ = nextVZ; + nextVX = random.nextGaussian() * 0.015; + nextVY = random.nextFloat() * 0.02 + 0.01; + nextVZ = random.nextGaussian() * 0.015; + } + double delta = (double) ticks / 31.0; + + if (this.age <= 31) { + this.setAlpha(this.age / 31F); + } else if (this.age >= this.lifetime - 31) { + this.setAlpha((this.lifetime - this.age) / 31F); + } + + if (this.age >= this.lifetime) { + this.remove(); + } + + this.xd = Mth.lerp(delta, preVX, nextVX); + this.yd = Mth.lerp(delta, preVY, nextVY); + this.zd = Mth.lerp(delta, preVZ, nextVZ); + + super.tick(); + } + + @Override + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; + } + + @Environment(EnvType.CLIENT) + public static class SmaragdantParticleFactory implements ParticleProvider { + + private final SpriteSet sprites; + + public SmaragdantParticleFactory(SpriteSet sprites) { + this.sprites = sprites; + } + + @Override + public Particle createParticle( + SimpleParticleType type, + ClientLevel world, + double x, + double y, + double z, + double vX, + double vY, + double vZ + ) { + return new SmaragdantParticle(world, x, y, z, 1, 1, 1, sprites); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/recipe/AlloyingRecipes.java b/src/main/java/org/betterx/betterend/recipe/AlloyingRecipes.java new file mode 100644 index 00000000..1a520779 --- /dev/null +++ b/src/main/java/org/betterx/betterend/recipe/AlloyingRecipes.java @@ -0,0 +1,53 @@ +package org.betterx.betterend.recipe; + +import org.betterx.betterend.recipe.builders.AlloyingRecipeBuilder; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; +import org.betterx.betterend.registry.EndTags; + +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Blocks; + +public class AlloyingRecipes { + public static void register() { + AlloyingRecipeBuilder.create("additional_iron") + .setInput(EndTags.ALLOYING_IRON, EndTags.ALLOYING_IRON) + .setOutput(Items.IRON_INGOT, 3) + .setExpiriense(2.1F) + .build(); + AlloyingRecipeBuilder.create("additional_gold") + .setInput(EndTags.ALLOYING_GOLD, EndTags.ALLOYING_GOLD) + .setOutput(Items.GOLD_INGOT, 3) + .setExpiriense(3F) + .build(); + AlloyingRecipeBuilder.create("additional_copper") + .setInput(EndTags.ALLOYING_COPPER, EndTags.ALLOYING_COPPER) + .setOutput(Items.COPPER_INGOT, 3) + .setExpiriense(3F) + .build(); + AlloyingRecipeBuilder.create("additional_netherite") + .setInput(Blocks.ANCIENT_DEBRIS, Blocks.ANCIENT_DEBRIS) + .setOutput(Items.NETHERITE_SCRAP, 3) + .setExpiriense(6F) + .setSmeltTime(1000) + .build(); + AlloyingRecipeBuilder.create("terminite_ingot") + .setInput(Items.IRON_INGOT, EndItems.ENDER_DUST) + .setOutput(EndBlocks.TERMINITE.ingot, 1) + .setExpiriense(2.5F) + .setSmeltTime(450) + .build(); + AlloyingRecipeBuilder.create("aeternium_ingot") + .setInput(EndBlocks.TERMINITE.ingot, Items.NETHERITE_INGOT) + .setOutput(EndItems.AETERNIUM_INGOT, 1) + .setExpiriense(4.5F) + .setSmeltTime(850) + .build(); + AlloyingRecipeBuilder.create("terminite_ingot_thallasium") + .setInput(EndBlocks.THALLASIUM.ingot, EndItems.ENDER_DUST) + .setOutput(EndBlocks.TERMINITE.ingot, 1) + .setExpiriense(2.5F) + .setSmeltTime(450) + .build(); + } +} diff --git a/src/main/java/org/betterx/betterend/recipe/AnvilRecipes.java b/src/main/java/org/betterx/betterend/recipe/AnvilRecipes.java new file mode 100644 index 00000000..b645c5b4 --- /dev/null +++ b/src/main/java/org/betterx/betterend/recipe/AnvilRecipes.java @@ -0,0 +1,88 @@ +package org.betterx.betterend.recipe; + +import org.betterx.bclib.recipes.AnvilRecipe; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.item.material.EndToolMaterial; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.world.item.Items; +import net.minecraft.world.item.Tiers; + +public class AnvilRecipes { + public static void register() { + AnvilRecipe.create("ender_pearl_to_dust") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(Items.ENDER_PEARL) + .setOutput(EndItems.ENDER_DUST) + .setAnvilLevel(Tiers.IRON.getLevel()) + .setToolLevel(4) + .setDamage(5) + .build(); + AnvilRecipe.create("ender_shard_to_dust") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(EndItems.ENDER_SHARD) + .setOutput(EndItems.ENDER_DUST) + .setAnvilLevel(Tiers.IRON.getLevel()) + .setToolLevel(0) + .setDamage(3) + .build(); + + int anvilLevel = EndToolMaterial.AETERNIUM.getLevel(); + AnvilRecipe.create("aeternium_axe_head") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(EndItems.AETERNIUM_INGOT) + .setOutput(EndItems.AETERNIUM_AXE_HEAD) + .setAnvilLevel(anvilLevel) + .setToolLevel(anvilLevel) + .setDamage(6) + .build(); + AnvilRecipe.create("aeternium_pickaxe_head") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(EndItems.AETERNIUM_INGOT) + .setOutput(EndItems.AETERNIUM_PICKAXE_HEAD) + .setAnvilLevel(anvilLevel) + .setToolLevel(anvilLevel) + .setDamage(6) + .build(); + AnvilRecipe.create("aeternium_shovel_head") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(EndItems.AETERNIUM_INGOT) + .setOutput(EndItems.AETERNIUM_SHOVEL_HEAD) + .setAnvilLevel(anvilLevel) + .setToolLevel(anvilLevel) + .setDamage(6) + .build(); + AnvilRecipe.create("aeternium_hoe_head") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(EndItems.AETERNIUM_INGOT) + .setOutput(EndItems.AETERNIUM_HOE_HEAD) + .setAnvilLevel(anvilLevel) + .setToolLevel(anvilLevel) + .setDamage(6) + .build(); + AnvilRecipe.create("aeternium_hammer_head") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(EndItems.AETERNIUM_INGOT) + .setOutput(EndItems.AETERNIUM_HAMMER_HEAD) + .setAnvilLevel(anvilLevel) + .setToolLevel(EndToolMaterial.THALLASIUM.getLevel()) + .setDamage(6) + .build(); + AnvilRecipe.create("aeternium_sword_blade") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(EndItems.AETERNIUM_INGOT) + .setOutput(EndItems.AETERNIUM_SWORD_BLADE) + .setAnvilLevel(anvilLevel) + .setToolLevel(anvilLevel) + .setDamage(6) + .build(); + AnvilRecipe.create("aeternium_forged_plate") + .checkConfig(Configs.RECIPE_CONFIG) + .setInput(EndItems.AETERNIUM_INGOT) + .setOutput(EndItems.AETERNIUM_FORGED_PLATE) + .setAnvilLevel(anvilLevel) + .setToolLevel(anvilLevel) + .setDamage(6) + .build(); + } +} diff --git a/src/main/java/org/betterx/betterend/recipe/CraftingRecipes.java b/src/main/java/org/betterx/betterend/recipe/CraftingRecipes.java new file mode 100644 index 00000000..e783753d --- /dev/null +++ b/src/main/java/org/betterx/betterend/recipe/CraftingRecipes.java @@ -0,0 +1,484 @@ +package org.betterx.betterend.recipe; + +import org.betterx.bclib.recipes.GridRecipe; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; +import org.betterx.worlds.together.tag.v3.CommonItemTags; + +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.alchemy.PotionUtils; +import net.minecraft.world.item.alchemy.Potions; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; + +public class CraftingRecipes { + + public static void register() { + GridRecipe.make(BetterEnd.MOD_ID, "ender_perl_to_block", EndBlocks.ENDER_BLOCK) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("OO", "OO") + .addMaterial('O', Items.ENDER_PEARL) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "ender_block_to_perl", Items.ENDER_PEARL) + .checkConfig(Configs.RECIPE_CONFIG) + .addMaterial('#', EndBlocks.ENDER_BLOCK) + .setOutputCount(4) + .setList("#") + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "end_stone_smelter", EndBlocks.END_STONE_SMELTER) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("T#T", "V V", "T#T") + .addMaterial('#', Blocks.END_STONE_BRICKS) + .addMaterial('T', EndBlocks.THALLASIUM.ingot) + .addMaterial('V', CommonItemTags.FURNACES) + .build(); + + registerPedestal( + "andesite_pedestal", + EndBlocks.ANDESITE_PEDESTAL, + Blocks.POLISHED_ANDESITE_SLAB, + Blocks.POLISHED_ANDESITE + ); + registerPedestal( + "diorite_pedestal", + EndBlocks.DIORITE_PEDESTAL, + Blocks.POLISHED_DIORITE_SLAB, + Blocks.POLISHED_DIORITE + ); + registerPedestal( + "granite_pedestal", + EndBlocks.GRANITE_PEDESTAL, + Blocks.POLISHED_GRANITE_SLAB, + Blocks.POLISHED_GRANITE + ); + registerPedestal("quartz_pedestal", EndBlocks.QUARTZ_PEDESTAL, Blocks.QUARTZ_SLAB, Blocks.QUARTZ_PILLAR); + registerPedestal("purpur_pedestal", EndBlocks.PURPUR_PEDESTAL, Blocks.PURPUR_SLAB, Blocks.PURPUR_PILLAR); + + GridRecipe.make(BetterEnd.MOD_ID, "infusion_pedestal", EndBlocks.INFUSION_PEDESTAL) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape(" Y ", "O#O", " # ") + .addMaterial('O', Items.ENDER_PEARL) + .addMaterial('Y', Items.ENDER_EYE) + .addMaterial('#', Blocks.OBSIDIAN) + .build(); + + String material = "aeternium"; + GridRecipe.make(BetterEnd.MOD_ID, material + "_block", EndBlocks.AETERNIUM_BLOCK) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("III", "III", "III") + .addMaterial('I', EndItems.AETERNIUM_INGOT) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, material + "_block_to_ingot", EndItems.AETERNIUM_INGOT) + .checkConfig(Configs.RECIPE_CONFIG) + .addMaterial('#', EndBlocks.AETERNIUM_BLOCK) + .setOutputCount(9) + .setList("#") + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "blue_vine_seed_dye", Items.BLUE_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.BLUE_VINE_SEED) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "creeping_moss_dye", Items.CYAN_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.CREEPING_MOSS) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "umbrella_moss_dye", Items.YELLOW_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.UMBRELLA_MOSS) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "umbrella_moss_tall_dye", Items.YELLOW_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(2) + .setList("#") + .addMaterial('#', EndBlocks.UMBRELLA_MOSS_TALL) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "shadow_plant_dye", Items.BLACK_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.SHADOW_PLANT) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "paper", Items.PAPER) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("###") + .addMaterial('#', EndItems.END_LILY_LEAF_DRIED) + .setOutputCount(3) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "aurora_block", EndBlocks.AURORA_CRYSTAL) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("##", "##") + .addMaterial('#', EndItems.CRYSTAL_SHARDS) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "lotus_block", EndBlocks.END_LOTUS.getLog()) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("##", "##") + .addMaterial('#', EndBlocks.END_LOTUS_STEM) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "needlegrass_stick", Items.STICK) + .setList("#") + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(2) + .addMaterial('#', EndBlocks.NEEDLEGRASS) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "shadow_berry_seeds", EndBlocks.SHADOW_BERRY) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .setOutputCount(4) + .addMaterial('#', EndItems.SHADOW_BERRY_RAW) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "purple_polypore_dye", Items.PURPLE_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.PURPLE_POLYPORE) + .build(); + + registerLantern("end_stone_lantern", EndBlocks.END_STONE_LANTERN, Blocks.END_STONE_BRICK_SLAB); + registerLantern("andesite_lantern", EndBlocks.ANDESITE_LANTERN, Blocks.ANDESITE_SLAB); + registerLantern("diorite_lantern", EndBlocks.DIORITE_LANTERN, Blocks.DIORITE_SLAB); + registerLantern("granite_lantern", EndBlocks.GRANITE_LANTERN, Blocks.GRANITE_SLAB); + registerLantern("quartz_lantern", EndBlocks.QUARTZ_LANTERN, Blocks.QUARTZ_SLAB); + registerLantern("purpur_lantern", EndBlocks.PURPUR_LANTERN, Blocks.PURPUR_SLAB); + registerLantern("blackstone_lantern", EndBlocks.BLACKSTONE_LANTERN, Blocks.BLACKSTONE_SLAB); + + GridRecipe.make(BetterEnd.MOD_ID, "amber_gem", EndItems.AMBER_GEM) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("##", "##") + .addMaterial('#', EndItems.RAW_AMBER) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "amber_block", EndBlocks.AMBER_BLOCK) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("##", "##") + .addMaterial('#', EndItems.AMBER_GEM) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "amber_gem_block", EndItems.AMBER_GEM) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setList("#") + .addMaterial('#', EndBlocks.AMBER_BLOCK) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "iron_bulb_lantern", EndBlocks.IRON_BULB_LANTERN) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("C", "I", "#") + .addMaterial('C', Items.CHAIN) + .addMaterial('I', Items.IRON_INGOT) + .addMaterial('#', EndItems.GLOWING_BULB) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "twisted_moss_dye", Items.PINK_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.TWISTED_MOSS) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "byshy_grass_dye", Items.MAGENTA_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.BUSHY_GRASS) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "tail_moss_dye", Items.GRAY_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.TAIL_MOSS) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "petal_block", EndBlocks.HYDRALUX_PETAL_BLOCK) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("##", "##") + .addMaterial('#', EndItems.HYDRALUX_PETAL) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "petal_white_dye", Items.WHITE_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndItems.HYDRALUX_PETAL) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "sweet_berry_jelly", EndItems.SWEET_BERRY_JELLY) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("JWSB") + .addMaterial('J', EndItems.GELATINE) + .addMaterial('W', PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)) + .addMaterial('S', Items.SUGAR) + .addMaterial('B', Items.SWEET_BERRIES) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "shadow_berry_jelly", EndItems.SHADOW_BERRY_JELLY) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("JWSB") + .addMaterial('J', EndItems.GELATINE) + .addMaterial('W', PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)) + .addMaterial('S', Items.SUGAR) + .addMaterial('B', EndItems.SHADOW_BERRY_COOKED) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "shadow_berry_jelly", EndItems.BLOSSOM_BERRY_JELLY) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("JWSB") + .addMaterial('J', EndItems.GELATINE) + .addMaterial('W', PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)) + .addMaterial('S', Items.SUGAR) + .addMaterial('B', EndItems.BLOSSOM_BERRY) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "sulphur_gunpowder", Items.GUNPOWDER) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("SCB") + .addMaterial('S', EndItems.CRYSTALLINE_SULPHUR) + .addMaterial('C', Items.COAL, Items.CHARCOAL) + .addMaterial('B', Items.BONE_MEAL) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "dense_emerald_ice", EndBlocks.DENSE_EMERALD_ICE) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("##", "##") + .addMaterial('#', EndBlocks.EMERALD_ICE) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "ancient_emerald_ice", EndBlocks.ANCIENT_EMERALD_ICE) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("###", "###", "###") + .addMaterial('#', EndBlocks.DENSE_EMERALD_ICE) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "charnia_cyan_dye", Items.CYAN_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.CHARNIA_CYAN) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "charnia_green_dye", Items.GREEN_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.CHARNIA_GREEN) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "charnia_light_blue_dye", Items.LIGHT_BLUE_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.CHARNIA_LIGHT_BLUE) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "charnia_orange_dye", Items.ORANGE_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.CHARNIA_ORANGE) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "charnia_purple_dye", Items.PURPLE_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.CHARNIA_PURPLE) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "charnia_red_dye", Items.RED_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.CHARNIA_RED) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "respawn_obelisk", EndBlocks.RESPAWN_OBELISK) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("CSC", "CSC", "AAA") + .addMaterial('C', EndBlocks.AURORA_CRYSTAL) + .addMaterial('S', EndItems.ETERNAL_CRYSTAL) + .addMaterial('A', EndBlocks.AMBER_BLOCK) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "twisted_umbrella_moss_dye", Items.PURPLE_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("#") + .addMaterial('#', EndBlocks.TWISTED_UMBRELLA_MOSS) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "twisted_umbrella_moss_dye_tall", Items.PURPLE_DYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(2) + .setList("#") + .addMaterial('#', EndBlocks.TWISTED_UMBRELLA_MOSS_TALL) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "leather_to_stripes", EndItems.LEATHER_STRIPE) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("L") + .addMaterial('L', Items.LEATHER) + .setOutputCount(3) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "stripes_to_leather", Items.LEATHER) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("SSS") + .addMaterial('S', EndItems.LEATHER_STRIPE) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "leather_wrapped_stick", EndItems.LEATHER_WRAPPED_STICK) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("SL") + .addMaterial('S', Items.STICK) + .addMaterial('L', EndItems.LEATHER_STRIPE) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "fiber_string", Items.STRING) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(6) + .setShape("#", "#", "#") + .addMaterial('#', EndItems.SILK_FIBER) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "ender_eye_amber", Items.ENDER_EYE) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("SAS", "APA", "SAS") + .addMaterial('S', EndItems.CRYSTAL_SHARDS) + .addMaterial('A', EndItems.AMBER_GEM) + .addMaterial('P', Items.ENDER_PEARL) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "iron_chandelier", EndBlocks.IRON_CHANDELIER) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("I#I", " # ") + .addMaterial('#', Items.IRON_INGOT) + .addMaterial('I', EndItems.LUMECORN_ROD) + .setGroup("end_metal_chandelier") + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "gold_chandelier", EndBlocks.GOLD_CHANDELIER) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("I#I", " # ") + .addMaterial('#', Items.GOLD_INGOT) + .addMaterial('I', EndItems.LUMECORN_ROD) + .setGroup("end_metal_chandelier") + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "missing_tile", EndBlocks.MISSING_TILE) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setShape("#P", "P#") + .addMaterial('#', EndBlocks.VIOLECITE.stone, EndBlocks.VIOLECITE.bricks, EndBlocks.VIOLECITE.tiles) + .addMaterial('P', Blocks.PURPUR_BLOCK) + .build(); + + registerHammer("iron", Items.IRON_INGOT, EndItems.IRON_HAMMER); + registerHammer("golden", Items.GOLD_INGOT, EndItems.GOLDEN_HAMMER); + registerHammer("diamond", Items.DIAMOND, EndItems.DIAMOND_HAMMER); + + GridRecipe.make(BetterEnd.MOD_ID, "charcoal_block", EndBlocks.CHARCOAL_BLOCK) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("###", "###", "###") + .addMaterial('#', Items.CHARCOAL) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "charcoal_from_block", Items.CHARCOAL) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(9) + .setList("#") + .addMaterial('#', EndBlocks.CHARCOAL_BLOCK) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "end_stone_furnace", EndBlocks.END_STONE_FURNACE) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("###", "# #", "###") + .addMaterial('#', Blocks.END_STONE) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "filalux_lantern", EndBlocks.FILALUX_LANTERN) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("###", "###", "###") + .addMaterial('#', EndBlocks.FILALUX) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "silk_moth_hive", EndBlocks.SILK_MOTH_HIVE) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("#L#", "LML", "#L#") + .addMaterial('#', EndBlocks.TENANEA.getBlock("planks")) + .addMaterial('L', EndBlocks.TENANEA_LEAVES) + .addMaterial('M', EndItems.SILK_MOTH_MATRIX) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "cave_pumpkin_pie", EndItems.CAVE_PUMPKIN_PIE) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("SBS", "BPB", "SBS") + .addMaterial('P', EndBlocks.CAVE_PUMPKIN) + .addMaterial('B', EndItems.BLOSSOM_BERRY, EndItems.SHADOW_BERRY_RAW) + .addMaterial('S', Items.SUGAR) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "cave_pumpkin_seeds", EndBlocks.CAVE_PUMPKIN_SEED) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(4) + .setList("#") + .addMaterial('#', EndBlocks.CAVE_PUMPKIN) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "neon_cactus_block", EndBlocks.NEON_CACTUS_BLOCK) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("##", "##") + .addMaterial('#', EndBlocks.NEON_CACTUS) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "neon_cactus_block_slab", EndBlocks.NEON_CACTUS_BLOCK_SLAB) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("###") + .setOutputCount(6) + .addMaterial('#', EndBlocks.NEON_CACTUS_BLOCK) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "neon_cactus_block_stairs", EndBlocks.NEON_CACTUS_BLOCK_STAIRS) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("# ", "## ", "###") + .setOutputCount(4) + .addMaterial('#', EndBlocks.NEON_CACTUS_BLOCK) + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "sugar_from_root", Items.SUGAR) + .checkConfig(Configs.RECIPE_CONFIG) + .setList("###") + .addMaterial('#', EndItems.AMBER_ROOT_RAW) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "endstone_flower_pot", EndBlocks.ENDSTONE_FLOWER_POT) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(3) + .setShape("# #", " # ") + .addMaterial('#', Blocks.END_STONE_BRICKS) + .setGroup("end_pots") + .build(); + + GridRecipe.make(BetterEnd.MOD_ID, "dragon_bone_block", EndBlocks.DRAGON_BONE_BLOCK) + .checkConfig(Configs.RECIPE_CONFIG) + .setOutputCount(8) + .setShape("###", "#D#", "###") + .addMaterial('#', Blocks.BONE_BLOCK) + .addMaterial('D', Items.DRAGON_BREATH) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "dragon_bone_slab", EndBlocks.DRAGON_BONE_SLAB) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("###") + .setOutputCount(6) + .addMaterial('#', EndBlocks.DRAGON_BONE_BLOCK) + .build(); + GridRecipe.make(BetterEnd.MOD_ID, "dragon_bone_stairs", EndBlocks.DRAGON_BONE_STAIRS) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("# ", "## ", "###") + .setOutputCount(4) + .addMaterial('#', EndBlocks.DRAGON_BONE_BLOCK) + .build(); + } + + private static void registerLantern(String name, Block lantern, Block slab) { + GridRecipe.make(BetterEnd.MOD_ID, name, lantern) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("S", "#", "S") + .addMaterial('#', EndItems.CRYSTAL_SHARDS) + .addMaterial('S', slab) + .setGroup("end_stone_lanterns") + .build(); + } + + public static void registerPedestal(String name, Block pedestal, Block slab, Block pillar) { + GridRecipe.make(BetterEnd.MOD_ID, name, pedestal) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("S", "#", "S") + .addMaterial('S', slab) + .addMaterial('#', pillar) + .setOutputCount(2) + .build(); + } + + private static void registerHammer(String name, Item material, Item result) { + GridRecipe.make(BetterEnd.MOD_ID, name + "_hammer", result) + .checkConfig(Configs.RECIPE_CONFIG) + .setShape("I I", "I#I", " # ") + .addMaterial('I', material) + .addMaterial('#', Items.STICK) + .build(); + } +} diff --git a/src/main/java/org/betterx/betterend/recipe/FurnaceRecipes.java b/src/main/java/org/betterx/betterend/recipe/FurnaceRecipes.java new file mode 100644 index 00000000..f7f0b155 --- /dev/null +++ b/src/main/java/org/betterx/betterend/recipe/FurnaceRecipes.java @@ -0,0 +1,45 @@ +package org.betterx.betterend.recipe; + +import org.betterx.bclib.recipes.FurnaceRecipe; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Blocks; + +public class FurnaceRecipes { + public static void register() { + FurnaceRecipe.make( + BetterEnd.MOD_ID, + "end_lily_leaf_dried", + EndItems.END_LILY_LEAF, + EndItems.END_LILY_LEAF_DRIED + ).checkConfig(Configs.RECIPE_CONFIG).build(); + FurnaceRecipe.make(BetterEnd.MOD_ID, "end_glass", EndBlocks.ENDSTONE_DUST, Blocks.GLASS) + .checkConfig(Configs.RECIPE_CONFIG) + .build(); + FurnaceRecipe.make(BetterEnd.MOD_ID, "end_berry", EndItems.SHADOW_BERRY_RAW, EndItems.SHADOW_BERRY_COOKED) + .checkConfig(Configs.RECIPE_CONFIG) + .buildFoodlike(); + FurnaceRecipe.make(BetterEnd.MOD_ID, "end_fish", EndItems.END_FISH_RAW, EndItems.END_FISH_COOKED) + .checkConfig(Configs.RECIPE_CONFIG) + .buildFoodlike(); + FurnaceRecipe.make(BetterEnd.MOD_ID, "slime_ball", EndBlocks.JELLYSHROOM_CAP_PURPLE, Items.SLIME_BALL) + .checkConfig(Configs.RECIPE_CONFIG) + .build(); + FurnaceRecipe.make(BetterEnd.MOD_ID, "menger_sponge", EndBlocks.MENGER_SPONGE_WET, EndBlocks.MENGER_SPONGE) + .checkConfig(Configs.RECIPE_CONFIG) + .build(); + FurnaceRecipe.make( + BetterEnd.MOD_ID, + "chorus_mushroom", + EndItems.CHORUS_MUSHROOM_RAW, + EndItems.CHORUS_MUSHROOM_COOKED + ).checkConfig(Configs.RECIPE_CONFIG).buildFoodlike(); + FurnaceRecipe.make(BetterEnd.MOD_ID, "bolux_mushroom", EndBlocks.BOLUX_MUSHROOM, EndItems.BOLUX_MUSHROOM_COOKED) + .checkConfig(Configs.RECIPE_CONFIG) + .buildFoodlike(); + } +} diff --git a/src/main/java/org/betterx/betterend/recipe/InfusionRecipes.java b/src/main/java/org/betterx/betterend/recipe/InfusionRecipes.java new file mode 100644 index 00000000..32a09c62 --- /dev/null +++ b/src/main/java/org/betterx/betterend/recipe/InfusionRecipes.java @@ -0,0 +1,615 @@ +package org.betterx.betterend.recipe; + +import org.betterx.betterend.recipe.builders.InfusionRecipe; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.world.item.EnchantedBookItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.EnchantmentInstance; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.block.Blocks; + +public class InfusionRecipes { + public static void register() { + InfusionRecipe.Builder.create("runed_flavolite") + .setInput(EndBlocks.FLAVOLITE.polished) + .setOutput(EndBlocks.FLAVOLITE_RUNED) + .addCatalyst(0, EndItems.CRYSTAL_SHARDS) + .addCatalyst(2, EndItems.CRYSTAL_SHARDS) + .addCatalyst(4, EndItems.CRYSTAL_SHARDS) + .addCatalyst(6, EndItems.CRYSTAL_SHARDS) + .setTime(100) + .build(); + + InfusionRecipe.Builder.create("eternal_crystal") + .setInput(Items.END_CRYSTAL) + .setOutput(EndItems.ETERNAL_CRYSTAL) + .addCatalyst(0, EndItems.CRYSTAL_SHARDS) + .addCatalyst(2, EndItems.CRYSTAL_SHARDS) + .addCatalyst(4, EndItems.CRYSTAL_SHARDS) + .addCatalyst(6, EndItems.CRYSTAL_SHARDS) + .addCatalyst(1, EndItems.ENDER_SHARD) + .addCatalyst(3, EndItems.ENDER_SHARD) + .addCatalyst(5, EndItems.ENDER_SHARD) + .addCatalyst(7, EndItems.ENDER_SHARD) + .setTime(250) + .build(); + + InfusionRecipe.Builder.create("crystalite_helmet") + .setInput(EndBlocks.TERMINITE.helmet) + .setOutput(EndItems.CRYSTALITE_HELMET) + .addCatalyst(0, EndItems.AMBER_GEM) + .addCatalyst(2, EndItems.CRYSTAL_SHARDS) + .addCatalyst(6, EndItems.CRYSTAL_SHARDS) + .setTime(150) + .build(); + InfusionRecipe.Builder.create("crystalite_chestplate") + .setInput(EndBlocks.TERMINITE.chestplate) + .setOutput(EndItems.CRYSTALITE_CHESTPLATE) + .addCatalyst(0, EndItems.AMBER_GEM) + .addCatalyst(1, EndItems.CRYSTAL_SHARDS) + .addCatalyst(3, EndItems.CRYSTAL_SHARDS) + .addCatalyst(5, EndItems.CRYSTAL_SHARDS) + .addCatalyst(7, EndItems.CRYSTAL_SHARDS) + .setTime(300) + .build(); + InfusionRecipe.Builder.create("crystalite_leggings") + .setInput(EndBlocks.TERMINITE.leggings) + .setOutput(EndItems.CRYSTALITE_LEGGINGS) + .addCatalyst(0, EndItems.AMBER_GEM) + .addCatalyst(2, EndItems.CRYSTAL_SHARDS) + .addCatalyst(4, EndItems.CRYSTAL_SHARDS) + .addCatalyst(6, EndItems.CRYSTAL_SHARDS) + .setTime(225) + .build(); + InfusionRecipe.Builder.create("crystalite_boots") + .setInput(EndBlocks.TERMINITE.boots) + .setOutput(EndItems.CRYSTALITE_BOOTS) + .addCatalyst(0, EndItems.AMBER_GEM) + .addCatalyst(2, EndItems.CRYSTAL_SHARDS) + .addCatalyst(6, EndItems.CRYSTAL_SHARDS) + .setTime(150) + .build(); + + InfusionRecipe.Builder.create("crystalite_elytra") + .setInput(Items.ELYTRA) + .setOutput(EndItems.CRYSTALITE_ELYTRA) + .addCatalyst(0, EndItems.AMBER_GEM) + .addCatalyst(1, EndItems.CRYSTAL_SHARDS) + .addCatalyst(2, EndItems.ENCHANTED_MEMBRANE) + .addCatalyst(3, EndItems.CRYSTAL_SHARDS) + .addCatalyst(4, EndItems.ENCHANTED_MEMBRANE) + .addCatalyst(5, EndItems.CRYSTAL_SHARDS) + .addCatalyst(6, EndItems.ENCHANTED_MEMBRANE) + .addCatalyst(7, EndItems.CRYSTAL_SHARDS) + .setTime(500) + .build(); + + InfusionRecipe.Builder.create("enchanted_petal") + .setInput(EndItems.HYDRALUX_PETAL) + .setOutput(EndItems.ENCHANTED_PETAL) + .addCatalyst(0, EndItems.CRYSTAL_SHARDS) + .addCatalyst(2, EndItems.CRYSTAL_SHARDS) + .addCatalyst(4, EndItems.CRYSTAL_SHARDS) + .addCatalyst(6, EndItems.CRYSTAL_SHARDS) + .setTime(75) + .build(); + InfusionRecipe.Builder.create("enchanted_membrane") + .setInput(Items.PHANTOM_MEMBRANE) + .setOutput(EndItems.ENCHANTED_MEMBRANE) + .addCatalyst(0, EndItems.CRYSTAL_SHARDS) + .addCatalyst(2, EndItems.CRYSTAL_SHARDS) + .addCatalyst(4, EndItems.CRYSTAL_SHARDS) + .addCatalyst(6, EndItems.CRYSTAL_SHARDS) + .setTime(75) + .build(); + + InfusionRecipe.Builder.create("protection_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.ALL_DAMAGE_PROTECTION, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(4, Items.TURTLE_HELMET) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("fire_protection_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.FIRE_PROTECTION, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.BLAZE_ROD) + .addCatalyst(4, Items.BLAZE_ROD) + .addCatalyst(6, Items.BLAZE_ROD) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("feather_falling_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.FALL_PROTECTION, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.FEATHER) + .addCatalyst(4, Items.FEATHER) + .addCatalyst(6, Items.FEATHER) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("blast_protection_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.BLAST_PROTECTION, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Blocks.OBSIDIAN) + .addCatalyst(4, Blocks.OBSIDIAN) + .addCatalyst(6, Blocks.OBSIDIAN) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("projectile_protection_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.PROJECTILE_PROTECTION, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.SCUTE) + .addCatalyst(4, Items.SHIELD) + .addCatalyst(6, Items.SCUTE) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("respiration_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.RESPIRATION, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.NAUTILUS_SHELL) + .addCatalyst(4, Items.NAUTILUS_SHELL) + .addCatalyst(6, Items.NAUTILUS_SHELL) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("aqua_affinity_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.AQUA_AFFINITY, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.PRISMARINE_CRYSTALS) + .addCatalyst(4, Items.PRISMARINE_CRYSTALS) + .addCatalyst(6, Items.PRISMARINE_CRYSTALS) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("thorns_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.THORNS, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Blocks.CACTUS) + .addCatalyst(4, Blocks.CACTUS) + .addCatalyst(6, Blocks.CACTUS) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("depth_strider_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.DEPTH_STRIDER, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Blocks.LILY_PAD) + .addCatalyst(4, EndBlocks.END_LILY_SEED) + .addCatalyst(6, Blocks.LILY_PAD) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("frost_walker_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.FROST_WALKER, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(4, EndBlocks.ANCIENT_EMERALD_ICE) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("soul_speed_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.SOUL_SPEED, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Blocks.SOUL_SAND, Blocks.SOUL_SOIL) + .addCatalyst(4, Blocks.SOUL_SAND, Blocks.SOUL_SOIL) + .addCatalyst(6, Blocks.SOUL_SAND, Blocks.SOUL_SOIL) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("sharpness_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.SHARPNESS, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(4, Items.NETHERITE_SCRAP) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("smite_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.SMITE, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Blocks.SUNFLOWER) + .addCatalyst(4, Items.GOLD_INGOT) + .addCatalyst(6, Blocks.SUNFLOWER) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("bane_of_arthropods_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.BANE_OF_ARTHROPODS, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.FERMENTED_SPIDER_EYE) + .addCatalyst(4, Items.IRON_INGOT) + .addCatalyst(6, Items.FERMENTED_SPIDER_EYE) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("knockback_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.KNOCKBACK, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.REDSTONE) + .addCatalyst(4, Blocks.PISTON) + .addCatalyst(6, Items.REDSTONE) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("fire_aspect_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.FIRE_ASPECT, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.BLAZE_POWDER) + .addCatalyst(4, Items.MAGMA_CREAM) + .addCatalyst(6, Items.BLAZE_POWDER) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("looting_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.MOB_LOOTING, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.EMERALD) + .addCatalyst(4, Items.GOLD_INGOT) + .addCatalyst(6, Items.EMERALD) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("sweeping_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.SWEEPING_EDGE, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.GOLDEN_SWORD) + .addCatalyst(4, Items.IRON_SWORD) + .addCatalyst(6, Items.GOLDEN_SWORD) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("efficiency_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.BLOCK_EFFICIENCY, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, EndItems.AMBER_GEM) + .addCatalyst(4, EndItems.AMBER_GEM) + .addCatalyst(6, EndItems.AMBER_GEM) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("silk_touch_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.SILK_TOUCH, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Blocks.COBWEB) + .addCatalyst(4, EndItems.ETERNAL_CRYSTAL) + .addCatalyst(6, Blocks.COBWEB) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(375) + .build(); + InfusionRecipe.Builder.create("unbreaking_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.UNBREAKING, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.DIAMOND) + .addCatalyst(4, Items.DIAMOND) + .addCatalyst(6, Items.DIAMOND) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("fortune_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.BLOCK_FORTUNE, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.EMERALD) + .addCatalyst(4, Items.RABBIT_FOOT) + .addCatalyst(6, Items.EMERALD) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("power_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.POWER_ARROWS, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, EndItems.AMBER_GEM) + .addCatalyst(4, Items.DIAMOND_SWORD) + .addCatalyst(6, EndItems.AMBER_GEM) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("punch_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.PUNCH_ARROWS, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.POPPED_CHORUS_FRUIT) + .addCatalyst(4, Items.SPECTRAL_ARROW) + .addCatalyst(6, Items.POPPED_CHORUS_FRUIT) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("flame_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.FLAMING_ARROWS, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.BLAZE_POWDER) + .addCatalyst(4, Items.SPECTRAL_ARROW) + .addCatalyst(6, Items.BLAZE_POWDER) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("infinity_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.INFINITY_ARROWS, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.SPECTRAL_ARROW) + .addCatalyst(4, EndItems.ETERNAL_CRYSTAL) + .addCatalyst(6, Items.SPECTRAL_ARROW) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(375) + .build(); + InfusionRecipe.Builder.create("luck_of_sea_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.FISHING_LUCK, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.EMERALD) + .addCatalyst(4, Items.FISHING_ROD) + .addCatalyst(6, Items.EMERALD) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("lure_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.FISHING_SPEED, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.GOLD_NUGGET) + .addCatalyst(4, Items.FISHING_ROD) + .addCatalyst(6, Items.GOLD_NUGGET) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("loyalty_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.LOYALTY, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.ENDER_EYE) + .addCatalyst(4, Items.HEART_OF_THE_SEA) + .addCatalyst(6, Items.ENDER_EYE) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(375) + .build(); + InfusionRecipe.Builder.create("impaling_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.IMPALING, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.PRISMARINE_SHARD) + .addCatalyst(4, Items.IRON_SWORD) + .addCatalyst(6, Items.PRISMARINE_SHARD) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("riptide_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.RIPTIDE, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.LEAD) + .addCatalyst(4, Items.HEART_OF_THE_SEA) + .addCatalyst(6, Items.LEAD) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(375) + .build(); + InfusionRecipe.Builder.create("channeling_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.CHANNELING, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.CHAIN) + .addCatalyst(4, Items.HEART_OF_THE_SEA) + .addCatalyst(6, Items.CHAIN) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(375) + .build(); + InfusionRecipe.Builder.create("multishot_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.MULTISHOT, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.ARROW) + .addCatalyst(4, Items.SPECTRAL_ARROW) + .addCatalyst(6, Items.ARROW) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("quick_charge_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.QUICK_CHARGE, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.QUARTZ) + .addCatalyst(4, Items.GLOWSTONE_DUST) + .addCatalyst(6, Items.QUARTZ) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("piercing_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.PIERCING, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.GLOWSTONE_DUST) + .addCatalyst(4, Items.SPECTRAL_ARROW) + .addCatalyst(6, Items.GLOWSTONE_DUST) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(300) + .build(); + InfusionRecipe.Builder.create("mending_book") + .setInput(Items.BOOK) + .setOutput(createEnchantedBook(Enchantments.MENDING, 1)) + .addCatalyst(0, EndItems.ENCHANTED_PETAL) + .addCatalyst(2, Items.EXPERIENCE_BOTTLE) + .addCatalyst(4, Blocks.ANVIL) + .addCatalyst(6, Items.EXPERIENCE_BOTTLE) + .addCatalyst(1, Items.LAPIS_LAZULI) + .addCatalyst(3, Items.LAPIS_LAZULI) + .addCatalyst(5, Items.LAPIS_LAZULI) + .addCatalyst(7, Items.LAPIS_LAZULI) + .setGroup("enchantment") + .setTime(375) + .build(); + } + + private static ItemStack createEnchantedBook(Enchantment enchantment, int level) { + ItemStack book = new ItemStack(Items.ENCHANTED_BOOK); + EnchantedBookItem.addEnchantment(book, new EnchantmentInstance(enchantment, level)); + return book; + } +} diff --git a/src/main/java/org/betterx/betterend/recipe/SmithingRecipes.java b/src/main/java/org/betterx/betterend/recipe/SmithingRecipes.java new file mode 100644 index 00000000..9ed7e7cd --- /dev/null +++ b/src/main/java/org/betterx/betterend/recipe/SmithingRecipes.java @@ -0,0 +1,110 @@ +package org.betterx.betterend.recipe; + +import org.betterx.bclib.recipes.SmithingTableRecipe; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.world.item.Items; + +public class SmithingRecipes { + + public static void register() { + SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_sword_handle") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndItems.AETERNIUM_SWORD_HANDLE) + .setBase(EndBlocks.TERMINITE.ingot) + .setAddition(EndItems.LEATHER_WRAPPED_STICK) + .build(); + + SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_sword") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndItems.AETERNIUM_SWORD) + .setBase(EndItems.AETERNIUM_SWORD_BLADE) + .setAddition(EndItems.AETERNIUM_SWORD_HANDLE) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_pickaxe") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndItems.AETERNIUM_PICKAXE) + .setBase(EndItems.AETERNIUM_PICKAXE_HEAD) + .setAddition(EndItems.LEATHER_WRAPPED_STICK) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_axe") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndItems.AETERNIUM_AXE) + .setBase(EndItems.AETERNIUM_AXE_HEAD) + .setAddition(EndItems.LEATHER_WRAPPED_STICK) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_shovel") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndItems.AETERNIUM_SHOVEL) + .setBase(EndItems.AETERNIUM_SHOVEL_HEAD) + .setAddition(EndItems.LEATHER_WRAPPED_STICK) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_hoe") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndItems.AETERNIUM_HOE) + .setBase(EndItems.AETERNIUM_HOE_HEAD) + .setAddition(EndItems.LEATHER_WRAPPED_STICK) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_hammer") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndItems.AETERNIUM_HAMMER) + .setBase(EndItems.AETERNIUM_HAMMER_HEAD) + .setAddition(EndItems.LEATHER_WRAPPED_STICK) + .build(); + + SmithingTableRecipe.create(BetterEnd.MOD_ID, "netherite_hammer") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndItems.NETHERITE_HAMMER) + .setBase(EndItems.DIAMOND_HAMMER) + .setAddition(Items.NETHERITE_INGOT) + .build(); + + SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_helmet") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndItems.AETERNIUM_HELMET) + .setBase(EndBlocks.TERMINITE.helmet) + .setAddition(EndItems.AETERNIUM_FORGED_PLATE) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_chestplate") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndItems.AETERNIUM_CHESTPLATE) + .setBase(EndBlocks.TERMINITE.chestplate) + .setAddition(EndItems.AETERNIUM_FORGED_PLATE) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_leggings") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndItems.AETERNIUM_LEGGINGS) + .setBase(EndBlocks.TERMINITE.leggings) + .setAddition(EndItems.AETERNIUM_FORGED_PLATE) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_boots") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndItems.AETERNIUM_BOOTS) + .setBase(EndBlocks.TERMINITE.boots) + .setAddition(EndItems.AETERNIUM_FORGED_PLATE) + .build(); + + SmithingTableRecipe.create(BetterEnd.MOD_ID, "thallasium_anvil_updrade") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndBlocks.TERMINITE.anvilBlock.asItem()) + .setBase(EndBlocks.THALLASIUM.anvilBlock.asItem()) + .setAddition(EndBlocks.TERMINITE.block) + .build(); + SmithingTableRecipe.create(BetterEnd.MOD_ID, "terminite_anvil_updrade") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndBlocks.AETERNIUM_ANVIL.asItem()) + .setBase(EndBlocks.TERMINITE.anvilBlock.asItem()) + .setAddition(EndItems.AETERNIUM_INGOT) + .build(); + + SmithingTableRecipe.create(BetterEnd.MOD_ID, "armored_elytra") + .checkConfig(Configs.RECIPE_CONFIG) + .setResult(EndItems.ARMORED_ELYTRA) + .setBase(Items.ELYTRA) + .setAddition(EndItems.AETERNIUM_INGOT) + .build(); + } +} diff --git a/src/main/java/org/betterx/betterend/recipe/builders/AlloyingRecipeBuilder.java b/src/main/java/org/betterx/betterend/recipe/builders/AlloyingRecipeBuilder.java new file mode 100644 index 00000000..ba5f31c0 --- /dev/null +++ b/src/main/java/org/betterx/betterend/recipe/builders/AlloyingRecipeBuilder.java @@ -0,0 +1,14 @@ +package org.betterx.betterend.recipe.builders; + +import org.betterx.bclib.recipes.AlloyingRecipe; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.config.Configs; + +public class AlloyingRecipeBuilder extends AlloyingRecipe.Builder { + private AlloyingRecipeBuilder() { + } + + public static AlloyingRecipe.Builder create(String id) { + return AlloyingRecipe.Builder.create(BetterEnd.MOD_ID, id, Configs.RECIPE_CONFIG); + } +} diff --git a/src/main/java/org/betterx/betterend/recipe/builders/InfusionRecipe.java b/src/main/java/org/betterx/betterend/recipe/builders/InfusionRecipe.java new file mode 100644 index 00000000..3bb2bce3 --- /dev/null +++ b/src/main/java/org/betterx/betterend/recipe/builders/InfusionRecipe.java @@ -0,0 +1,298 @@ +package org.betterx.betterend.recipe.builders; + +import org.betterx.bclib.interfaces.UnknownReceipBookCategory; +import org.betterx.bclib.recipes.BCLRecipeManager; +import org.betterx.bclib.util.ItemUtil; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.rituals.InfusionRitual; + +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.core.NonNullList; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.TagParser; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.GsonHelper; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.RecipeSerializer; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.Level; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import com.google.gson.JsonObject; + +import java.util.Arrays; + +public class InfusionRecipe implements Recipe, UnknownReceipBookCategory { + public final static String GROUP = "infusion"; + public final static RecipeType TYPE = BCLRecipeManager.registerType(BetterEnd.MOD_ID, GROUP); + public final static Serializer SERIALIZER = BCLRecipeManager.registerSerializer( + BetterEnd.MOD_ID, + GROUP, + new Serializer() + ); + + private final ResourceLocation id; + private final Ingredient[] catalysts; + private Ingredient input; + private ItemStack output; + private int time = 1; + private String group; + + private InfusionRecipe(ResourceLocation id) { + this(id, null, null); + } + + private InfusionRecipe(ResourceLocation id, Ingredient input, ItemStack output) { + this.id = id; + this.input = input; + this.output = output; + this.catalysts = new Ingredient[8]; + Arrays.fill(catalysts, Ingredient.EMPTY); + } + + public int getInfusionTime() { + return this.time; + } + + @Override + public boolean matches(InfusionRitual inv, Level world) { + boolean valid = this.input.test(inv.getItem(0)); + if (!valid) return false; + for (int i = 0; i < 8; i++) { + valid &= this.catalysts[i].test(inv.getItem(i + 1)); + } + return valid; + } + + @Override + public ItemStack assemble(InfusionRitual ritual) { + return output.copy(); + } + + @Override + public boolean canCraftInDimensions(int width, int height) { + return true; + } + + @Override + public NonNullList getIngredients() { + NonNullList defaultedList = NonNullList.create(); + defaultedList.add(input); + defaultedList.addAll(Arrays.asList(catalysts)); + return defaultedList; + } + + @Override + public ItemStack getResultItem() { + return this.output; + } + + @Override + public ResourceLocation getId() { + return this.id; + } + + @Override + @Environment(EnvType.CLIENT) + public String getGroup() { + return this.group; + } + + @Override + public RecipeSerializer getSerializer() { + return SERIALIZER; + } + + @Override + public RecipeType getType() { + return TYPE; + } + + public static class Builder { + private final static Builder INSTANCE = new Builder(); + private static boolean exist; + + public static Builder create(String id) { + return create(BetterEnd.makeID(id)); + } + + public static Builder create(ResourceLocation id) { + INSTANCE.id = id; + INSTANCE.input = null; + INSTANCE.output = null; + INSTANCE.time = 1; + exist = Configs.RECIPE_CONFIG.getBoolean("infusion", id.getPath(), true); + + Arrays.fill(INSTANCE.catalysts, Ingredient.EMPTY); + + return INSTANCE; + } + + private final Ingredient[] catalysts = new Ingredient[8]; + private ResourceLocation id; + private Ingredient input; + private ItemStack output; + private String group; + private int time = 1; + + private Builder() { + Arrays.fill(catalysts, Ingredient.EMPTY); + } + + public Builder setGroup(String group) { + this.group = group; + return this; + } + + public Builder setInput(ItemLike input) { + this.input = Ingredient.of(input); + return this; + } + + public Builder setOutput(ItemLike output) { + this.output = new ItemStack(output); + this.output.setCount(1); + return this; + } + + public Builder setOutput(ItemStack output) { + this.output = output; + this.output.setCount(1); + return this; + } + + public Builder setTime(int time) { + this.time = time; + return this; + } + + public Builder addCatalyst(int slot, ItemLike... items) { + if (slot > 7) return this; + this.catalysts[slot] = Ingredient.of(items); + return this; + } + + public void build() { + if (exist) { + if (input == null) { + BetterEnd.LOGGER.warning( + "Input for Infusion recipe can't be 'null', recipe {} will be ignored!", + id + ); + return; + } + if (output == null) { + BetterEnd.LOGGER.warning( + "Output for Infusion recipe can't be 'null', recipe {} will be ignored!", + id + ); + return; + } + InfusionRecipe recipe = new InfusionRecipe(id, input, output); + recipe.group = group != null ? group : GROUP; + recipe.time = time; + int empty = 0; + for (int i = 0; i < catalysts.length; i++) { + if (catalysts[i].isEmpty()) empty++; + else recipe.catalysts[i] = catalysts[i]; + } + if (empty == catalysts.length) { + BetterEnd.LOGGER.warning("At least one catalyst must be non empty, recipe {} will be ignored!", id); + return; + } + BCLRecipeManager.addRecipeAndCreateAdvancement(TYPE, recipe); + } + } + } + + public static class Serializer implements RecipeSerializer { + @Override + public InfusionRecipe fromJson(ResourceLocation id, JsonObject json) { + InfusionRecipe recipe = new InfusionRecipe(id); + recipe.input = Ingredient.fromJson(json.get("input")); + JsonObject result = GsonHelper.getAsJsonObject(json, "result"); + recipe.output = ItemUtil.fromJsonRecipe(result); + if (recipe.output == null) { + throw new IllegalStateException("Output item does not exists!"); + } + if (result.has("nbt")) { + try { + String nbtData = GsonHelper.getAsString(result, "nbt"); + CompoundTag nbt = TagParser.parseTag(nbtData); + recipe.output.setTag(nbt); + } catch (CommandSyntaxException ex) { + BetterEnd.LOGGER.warning("Error parse nbt data for output.", ex); + } + } + recipe.group = GsonHelper.getAsString(json, "group", GROUP); + recipe.time = GsonHelper.getAsInt(json, "time", 1); + + JsonObject catalysts = GsonHelper.getAsJsonObject(json, "catalysts"); + ItemStack catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "north", "")); + recipe.catalysts[0] = (catalyst != null && !catalyst.isEmpty()) + ? Ingredient.of(catalyst.getItem()) + : Ingredient.EMPTY; + catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "north_east", "")); + recipe.catalysts[1] = (catalyst != null && !catalyst.isEmpty()) + ? Ingredient.of(catalyst.getItem()) + : Ingredient.EMPTY; + catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "east", "")); + recipe.catalysts[2] = (catalyst != null && !catalyst.isEmpty()) + ? Ingredient.of(catalyst.getItem()) + : Ingredient.EMPTY; + catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "south_east", "")); + recipe.catalysts[3] = (catalyst != null && !catalyst.isEmpty()) + ? Ingredient.of(catalyst.getItem()) + : Ingredient.EMPTY; + catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "south", "")); + recipe.catalysts[4] = (catalyst != null && !catalyst.isEmpty()) + ? Ingredient.of(catalyst.getItem()) + : Ingredient.EMPTY; + catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "south_west", "")); + recipe.catalysts[5] = (catalyst != null && !catalyst.isEmpty()) + ? Ingredient.of(catalyst.getItem()) + : Ingredient.EMPTY; + catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "west", "")); + recipe.catalysts[6] = (catalyst != null && !catalyst.isEmpty()) + ? Ingredient.of(catalyst.getItem()) + : Ingredient.EMPTY; + catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "north_west", "")); + recipe.catalysts[7] = (catalyst != null && !catalyst.isEmpty()) + ? Ingredient.of(catalyst.getItem()) + : Ingredient.EMPTY; + + return recipe; + } + + @Override + public InfusionRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) { + InfusionRecipe recipe = new InfusionRecipe(id); + recipe.input = Ingredient.fromNetwork(buffer); + recipe.output = buffer.readItem(); + recipe.group = buffer.readUtf(); + recipe.time = buffer.readVarInt(); + for (int i = 0; i < 8; i++) { + recipe.catalysts[i] = Ingredient.fromNetwork(buffer); + } + return recipe; + } + + @Override + public void toNetwork(FriendlyByteBuf buffer, InfusionRecipe recipe) { + recipe.input.toNetwork(buffer); + buffer.writeItem(recipe.output); + buffer.writeUtf(recipe.group); + buffer.writeVarInt(recipe.time); + for (int i = 0; i < 8; i++) { + recipe.catalysts[i].toNetwork(buffer); + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndAdvancements.java b/src/main/java/org/betterx/betterend/registry/EndAdvancements.java new file mode 100644 index 00000000..d0497568 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndAdvancements.java @@ -0,0 +1,104 @@ +package org.betterx.betterend.registry; + +import org.betterx.bclib.api.v2.advancement.AdvancementManager; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.advancements.BECriteria; + +import net.minecraft.advancements.FrameType; +import net.minecraft.advancements.RequirementsStrategy; +import net.minecraft.advancements.critereon.ChangeDimensionTrigger; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; + +public class EndAdvancements { + public static void register() { + ResourceLocation root = AdvancementManager.Builder + .create(BetterEnd.makeID("root")) + .startDisplay(EndBlocks.CAVE_MOSS) + .frame(FrameType.TASK) + .hideToast() + .hideFromChat() + .background(new ResourceLocation("textures/gui/advancements/backgrounds/end.png")) + .endDisplay() + .addCriterion( + "entered_end", + ChangeDimensionTrigger + .TriggerInstance + .changedDimensionTo(Level.END) + ) + .requirements(RequirementsStrategy.OR) + .buildAndRegister(); + + ResourceLocation portal = AdvancementManager.Builder + .create(BetterEnd.makeID("portal")) + .parent(root) + .startDisplay(EndBlocks.ETERNAL_PEDESTAL) + .frame(FrameType.GOAL) + .endDisplay() + .addAtStructureCriterion("eternal_portal", EndStructures.ETERNAL_PORTAL) + .requirements(RequirementsStrategy.OR) + .buildAndRegister(); + + ResourceLocation portalOn = AdvancementManager.Builder + .create(BetterEnd.makeID("portal_on")) + .parent(portal) + .startDisplay(EndItems.ETERNAL_CRYSTAL) + .endDisplay() + .addCriterion("turn_on", BECriteria.PORTAL_ON_TRIGGER) + .requirements(RequirementsStrategy.OR) + .buildAndRegister(); + + ResourceLocation portalTravel = AdvancementManager.Builder + .create(BetterEnd.makeID("portal_travel")) + .parent(portalOn) + .startDisplay(Items.GRASS_BLOCK) + .frame(FrameType.CHALLENGE) + .endDisplay() + .addCriterion("travel", BECriteria.PORTAL_TRAVEL_TRIGGER) + .requirements(RequirementsStrategy.OR) + .buildAndRegister(); + + ResourceLocation allTheBiomes = AdvancementManager.Builder + .create(BetterEnd.makeID("all_the_biomes")) + .parent(root) + .startDisplay(EndItems.AETERNIUM_BOOTS) + .frame(FrameType.CHALLENGE) + .endDisplay() + .addVisitBiomesCriterion(EndBiomes.ALL_BE_BIOMES.stream().map(b -> b.getBiomeKey()).toList()) + .requirements(RequirementsStrategy.AND) + .rewardXP(1500) + .buildAndRegister(); + + ResourceLocation allElytras = AdvancementManager.Builder + .create(BetterEnd.makeID("all_elytras")) + .parent(root) + .startDisplay(EndItems.CRYSTALITE_ELYTRA) + .frame(FrameType.GOAL) + .endDisplay() + .addInventoryChangedCriterion("vanilla", Items.ELYTRA) + .addInventoryChangedCriterion("crystalite", EndItems.CRYSTALITE_ELYTRA) + .addInventoryChangedCriterion("armored", EndItems.ARMORED_ELYTRA) + .requirements(RequirementsStrategy.AND) + .buildAndRegister(); + + ResourceLocation infusion = AdvancementManager.Builder + .create(BetterEnd.makeID("infusion")) + .parent(root) + .startDisplay(EndBlocks.INFUSION_PEDESTAL) + .endDisplay() + .addInventoryChangedCriterion("infusion_pedestal", EndBlocks.INFUSION_PEDESTAL) + .requirements(RequirementsStrategy.OR) + .buildAndRegister(); + + ResourceLocation infusionFinished = AdvancementManager.Builder + .create(BetterEnd.makeID("infusion_finished")) + .parent(infusion) + .startDisplay(Items.ENDER_EYE) + .frame(FrameType.GOAL) + .endDisplay() + .addCriterion("finished", BECriteria.INFUSION_FINISHED_TRIGGER) + .requirements(RequirementsStrategy.OR) + .buildAndRegister(); + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndAttributes.java b/src/main/java/org/betterx/betterend/registry/EndAttributes.java new file mode 100644 index 00000000..e9df8d36 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndAttributes.java @@ -0,0 +1,26 @@ +package org.betterx.betterend.registry; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.item.EndAttribute; + +import net.minecraft.core.Registry; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; + +public class EndAttributes { + public final static Attribute BLINDNESS_RESISTANCE = registerAttribute("generic.blindness_resistance", 0.0, true); + + public static Attribute registerAttribute(String name, double value, boolean syncable) { + return Registry.register( + Registry.ATTRIBUTE, + BetterEnd.makeID(name), + new EndAttribute("attribute.name." + name, value).setSyncable(syncable) + ); + } + + public static AttributeSupplier.Builder addLivingEntityAttributes(AttributeSupplier.Builder builder) { + return builder.add(EndAttributes.BLINDNESS_RESISTANCE); + } +} + + diff --git a/src/main/java/org/betterx/betterend/registry/EndBiomes.java b/src/main/java/org/betterx/betterend/registry/EndBiomes.java new file mode 100644 index 00000000..aa8649e2 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndBiomes.java @@ -0,0 +1,185 @@ +package org.betterx.betterend.registry; + +import org.betterx.bclib.api.v2.LifeCycleAPI; +import org.betterx.bclib.api.v2.generator.BiomePicker; +import org.betterx.bclib.api.v2.generator.map.hex.HexBiomeMap; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.betterend.world.biome.air.BiomeIceStarfield; +import org.betterx.betterend.world.biome.cave.*; +import org.betterx.betterend.world.biome.land.*; +import org.betterx.betterend.world.generator.BiomeType; +import org.betterx.betterend.world.generator.GeneratorOptions; + +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.biome.Biome; + +import java.util.LinkedList; +import java.util.List; + +public class EndBiomes { + public static final BiomeAPI.BiomeType END_CAVE = new BiomeAPI.BiomeType("END_CAVE", BiomeAPI.BiomeType.END_IGNORE); + public static final List ALL_BE_BIOMES = new LinkedList<>(); + public static BiomePicker CAVE_BIOMES = null; + private static HexBiomeMap caveBiomeMap; + private static long lastSeed; + + // Better End Land + public static final EndBiome FOGGY_MUSHROOMLAND = registerBiome(new FoggyMushroomlandBiome(), BiomeType.LAND); + public static final EndBiome CHORUS_FOREST = registerBiome(new ChorusForestBiome(), BiomeType.LAND); + public static final EndBiome DUST_WASTELANDS = registerBiome(new DustWastelandsBiome(), BiomeType.LAND); + public static final EndBiome MEGALAKE = registerBiome(new MegalakeBiome(), BiomeType.LAND); + public static final EndBiome MEGALAKE_GROVE = registerSubBiome(new MegalakeGroveBiome(), MEGALAKE); + public static final EndBiome CRYSTAL_MOUNTAINS = registerBiome(new CrystalMountainsBiome(), BiomeType.LAND); + public static final EndBiome PAINTED_MOUNTAINS = registerSubBiome(new PaintedMountainsBiome(), DUST_WASTELANDS); + public static final EndBiome SHADOW_FOREST = registerBiome(new ShadowForestBiome(), BiomeType.LAND); + public static final EndBiome AMBER_LAND = registerBiome(new AmberLandBiome(), BiomeType.LAND); + public static final EndBiome BLOSSOMING_SPIRES = registerBiome(new BlossomingSpiresBiome(), BiomeType.LAND); + public static final EndBiome SULPHUR_SPRINGS = registerBiome(new SulphurSpringsBiome(), BiomeType.LAND); + public static final EndBiome UMBRELLA_JUNGLE = registerBiome(new UmbrellaJungleBiome(), BiomeType.LAND); + public static final EndBiome GLOWING_GRASSLANDS = registerBiome(new GlowingGrasslandsBiome(), BiomeType.LAND); + public static final EndBiome DRAGON_GRAVEYARDS = registerBiome(new DragonGraveyardsBiome(), BiomeType.LAND); + public static final EndBiome DRY_SHRUBLAND = registerBiome(new DryShrublandBiome(), BiomeType.LAND); + public static final EndBiome LANTERN_WOODS = registerBiome(new LanternWoodsBiome(), BiomeType.LAND); + public static final EndBiome NEON_OASIS = registerSubBiome(new NeonOasisBiome(), DUST_WASTELANDS); + public static final EndBiome UMBRA_VALLEY = registerBiome(new UmbraValleyBiome(), BiomeType.LAND); + + // Better End Void + public static final EndBiome ICE_STARFIELD = registerBiome(new BiomeIceStarfield(), BiomeType.VOID); + + // Better End Caves + public static final EndCaveBiome EMPTY_END_CAVE = registerCaveBiome(new EmptyEndCaveBiome()); + public static final EndCaveBiome EMPTY_SMARAGDANT_CAVE = registerCaveBiome(new EmptySmaragdantCaveBiome()); + public static final EndCaveBiome LUSH_SMARAGDANT_CAVE = registerCaveBiome(new LushSmaragdantCaveBiome()); + public static final EndCaveBiome EMPTY_AURORA_CAVE = registerCaveBiome(new EmptyAuroraCaveBiome()); + public static final EndCaveBiome LUSH_AURORA_CAVE = registerCaveBiome(new LushAuroraCaveBiome()); + public static final EndCaveBiome JADE_CAVE = registerCaveBiome(new JadeCaveBiome()); + + public static void register() { + BCLBiomeRegistry.registerBiomeCodec(BetterEnd.makeID("biome"), EndBiome.KEY_CODEC); + BCLBiomeRegistry.registerBiomeCodec(BetterEnd.makeID("cave_biome"), EndCaveBiome.KEY_CODEC); + BCLBiomeRegistry.registerBiomeCodec( + BetterEnd.makeID("empty_aurora_cave_biome"), + EmptyAuroraCaveBiome.KEY_CODEC + ); + BCLBiomeRegistry.registerBiomeCodec(BetterEnd.makeID("empty_end_cave_biome"), EmptyEndCaveBiome.KEY_CODEC); + BCLBiomeRegistry.registerBiomeCodec( + BetterEnd.makeID("empty_smaragdant_cave_biome"), + EmptySmaragdantCaveBiome.KEY_CODEC + ); + BCLBiomeRegistry.registerBiomeCodec(BetterEnd.makeID("jade_cave_biome"), JadeCaveBiome.KEY_CODEC); + BCLBiomeRegistry.registerBiomeCodec(BetterEnd.makeID("lush_aurora_cave_biome"), LushAuroraCaveBiome.KEY_CODEC); + BCLBiomeRegistry.registerBiomeCodec( + BetterEnd.makeID("lush_smaragdant_cave_biome"), + LushSmaragdantCaveBiome.KEY_CODEC + ); + LifeCycleAPI.onLevelLoad(EndBiomes::onWorldLoad); + } + + private static void onWorldLoad(ServerLevel level, long seed, Registry registry) { + if (CAVE_BIOMES == null || CAVE_BIOMES.biomeRegistry != registry) { + CAVE_BIOMES = new BiomePicker(registry); + registry.stream() + .filter(biome -> registry.getResourceKey(biome).isPresent()) + .map(biome -> registry.getOrCreateHolderOrThrow(registry.getResourceKey(biome).get())) + .map(biome -> biome.unwrapKey().orElseThrow().location()) + .filter(id -> BiomeAPI.wasRegisteredAs(id, END_CAVE)) + .map(id -> BiomeAPI.getBiome(id)) + .filter(bcl -> bcl != null) + .forEach(bcl -> CAVE_BIOMES.addBiome(bcl)); + + CAVE_BIOMES.rebuild(); + caveBiomeMap = null; + } + + if (caveBiomeMap == null || lastSeed != seed) { + caveBiomeMap = new HexBiomeMap(seed, GeneratorOptions.getBiomeSizeCaves(), CAVE_BIOMES); + lastSeed = seed; + } + } + + /** + * Put existing {@link EndBiome} as a sub-biome into selected parent. + * + * @param biomeConfig - {@link EndBiome.Config} instance + * @param parent - {@link EndBiome} to be linked with + * @return registered {@link EndBiome} + */ + public static EndBiome registerSubBiome(EndBiome.Config biomeConfig, EndBiome parent) { + final EndBiome biome = EndBiome.create(biomeConfig); + + if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { + BiomeAPI.registerSubBiome(parent, biome); + } + return biome; + } + + /** + * Registers {@link EndBiome} and adds it into worldgen. + * + * @param biomeConfig - {@link EndBiome.Config} instance + * @param type - {@link BiomeType} + * @return registered {@link EndBiome} + */ + public static EndBiome registerBiome(EndBiome.Config biomeConfig, BiomeType type) { + final EndBiome biome = EndBiome.create(biomeConfig); + if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { + if (type == BiomeType.LAND) { + BiomeAPI.registerEndLandBiome(biome); + } else { + BiomeAPI.registerEndVoidBiome(biome); + } + ALL_BE_BIOMES.add(biome); + } + return biome; + } + + /** + * Put integration sub-biome {@link EndBiome} into subbiomes list and registers it. + * + * @param biomeConfig - {@link EndBiome.Config} instance + * @return registered {@link EndBiome} + */ + public static EndBiome registerSubBiomeIntegration(EndBiome.Config biomeConfig) { + EndBiome biome = EndBiome.create(biomeConfig); + if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { + BiomeAPI.registerBiome(biome, BiomeAPI.BiomeType.END); + } + return biome; + } + + /** + * Link integration sub-biome with parent. + * + * @param biome - {@link EndBiome} instance + * @param parent - {@link ResourceLocation} parent id + */ + public static void addSubBiomeIntegration(EndBiome biome, ResourceLocation parent) { + if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { + BCLBiome parentBiome = BiomeAPI.getBiome(parent); + if (parentBiome != null && !parentBiome.containsSubBiome(biome)) { + parentBiome.addSubBiome(biome); + } + } + } + + public static EndCaveBiome registerCaveBiome(EndCaveBiome.Config biomeConfig) { + final EndCaveBiome biome = EndCaveBiome.create(biomeConfig); + if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { + BiomeAPI.registerBiome(biome, END_CAVE); + //ALL_BE_BIOMES.add(biome); + } + return biome; + } + + public static BiomePicker.ActualBiome getCaveBiome(int x, int z) { + return caveBiomeMap.getBiome(x, 5, z); + } + +} diff --git a/src/main/java/org/betterx/betterend/registry/EndBlockEntities.java b/src/main/java/org/betterx/betterend/registry/EndBlockEntities.java new file mode 100644 index 00000000..68ca4b93 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndBlockEntities.java @@ -0,0 +1,55 @@ +package org.betterx.betterend.registry; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.EndStoneSmelter; +import org.betterx.betterend.blocks.basis.PedestalBlock; +import org.betterx.betterend.blocks.entities.*; + +import net.minecraft.core.Registry; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; + +import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder; + +public class EndBlockEntities { + public final static BlockEntityType END_STONE_SMELTER = registerBlockEntity( + EndStoneSmelter.ID, + FabricBlockEntityTypeBuilder.create(EndStoneSmelterBlockEntity::new, EndBlocks.END_STONE_SMELTER) + ); + public final static BlockEntityType PEDESTAL = registerBlockEntity( + "pedestal", + FabricBlockEntityTypeBuilder.create(PedestalBlockEntity::new, getPedestals()) + ); + public final static BlockEntityType ETERNAL_PEDESTAL = registerBlockEntity( + "eternal_pedestal", + FabricBlockEntityTypeBuilder.create(EternalPedestalEntity::new, EndBlocks.ETERNAL_PEDESTAL) + ); + public final static BlockEntityType INFUSION_PEDESTAL = registerBlockEntity( + "infusion_pedestal", + FabricBlockEntityTypeBuilder.create(InfusionPedestalEntity::new, EndBlocks.INFUSION_PEDESTAL) + ); + public final static BlockEntityType HYDROTHERMAL_VENT = registerBlockEntity( + "hydrother_malvent", + FabricBlockEntityTypeBuilder.create(BlockEntityHydrothermalVent::new, EndBlocks.HYDROTHERMAL_VENT) + ); + + public static BlockEntityType registerBlockEntity( + String id, + FabricBlockEntityTypeBuilder builder + ) { + return Registry.register(Registry.BLOCK_ENTITY_TYPE, BetterEnd.makeID(id), builder.build(null)); + + //return Registry.register(Registry.BLOCK_ENTITY_TYPE, BetterEnd.makeID(id), builder.build(null)); + } + + public static void register() { + } + + static Block[] getPedestals() { + return EndBlocks.getModBlocks() + .stream() + .filter(block -> block instanceof PedestalBlock && !((PedestalBlock) block).hasUniqueEntity()) + .toArray(Block[]::new); + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndBlockEntityRenders.java b/src/main/java/org/betterx/betterend/registry/EndBlockEntityRenders.java new file mode 100644 index 00000000..29c2d83b --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndBlockEntityRenders.java @@ -0,0 +1,16 @@ +package org.betterx.betterend.registry; + +import org.betterx.betterend.client.render.PedestalItemRenderer; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.rendering.v1.BlockEntityRendererRegistry; + +@Environment(EnvType.CLIENT) +public class EndBlockEntityRenders { + public static void register() { + BlockEntityRendererRegistry.register(EndBlockEntities.PEDESTAL, PedestalItemRenderer::new); + BlockEntityRendererRegistry.register(EndBlockEntities.ETERNAL_PEDESTAL, PedestalItemRenderer::new); + BlockEntityRendererRegistry.register(EndBlockEntities.INFUSION_PEDESTAL, PedestalItemRenderer::new); + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndBlocks.java b/src/main/java/org/betterx/betterend/registry/EndBlocks.java new file mode 100644 index 00000000..023572de --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndBlocks.java @@ -0,0 +1,668 @@ +package org.betterx.betterend.registry; + +import org.betterx.bclib.blocks.*; +import org.betterx.bclib.registry.BlockRegistry; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.*; +import org.betterx.betterend.blocks.basis.*; +import org.betterx.betterend.complexmaterials.*; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.item.material.EndArmorMaterial; +import org.betterx.betterend.item.material.EndToolMaterial; +import org.betterx.betterend.tab.CreativeTabs; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.material.MaterialColor; + +import net.fabricmc.fabric.api.item.v1.FabricItemSettings; + +import java.util.List; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +public class EndBlocks { + private static final BlockRegistry REGISTRY = new BlockRegistry(CreativeTabs.TAB_BLOCKS, Configs.BLOCK_CONFIG); + + // Terrain // + public static final Block ENDSTONE_DUST = registerBlock("endstone_dust", new EndstoneDustBlock()); + public static final Block END_MYCELIUM = registerBlock( + "end_mycelium", + new EndTerrainBlock(MaterialColor.COLOR_LIGHT_BLUE) + ); + public static final Block END_MOSS = registerBlock("end_moss", new EndTerrainBlock(MaterialColor.COLOR_CYAN)); + public static final Block CHORUS_NYLIUM = registerBlock( + "chorus_nylium", + new EndTerrainBlock(MaterialColor.COLOR_MAGENTA) + ); + public static final Block CAVE_MOSS = registerBlock("cave_moss", new EndTripleTerrain(MaterialColor.COLOR_PURPLE)); + public static final Block CRYSTAL_MOSS = registerBlock( + "crystal_moss", + new EndTerrainBlock(MaterialColor.COLOR_PINK) + ); + public static final Block CRYSTAL_MOSS_COVER = registerBlock( + "crystal_moss_cover", + new CrystalMossCoverBlock(MaterialColor.COLOR_PINK) + ); + public static final Block SHADOW_GRASS = registerBlock("shadow_grass", new ShadowGrassBlock()); + public static final Block PINK_MOSS = registerBlock("pink_moss", new EndTerrainBlock(MaterialColor.COLOR_PINK)); + public static final Block AMBER_MOSS = registerBlock("amber_moss", new EndTerrainBlock(MaterialColor.COLOR_ORANGE)); + public static final Block JUNGLE_MOSS = registerBlock( + "jungle_moss", + new EndTerrainBlock(MaterialColor.COLOR_GREEN) + ); + public static final Block SANGNUM = registerBlock("sangnum", new EndTerrainBlock(MaterialColor.COLOR_RED)); + public static final Block RUTISCUS = registerBlock("rutiscus", new EndTerrainBlock(MaterialColor.COLOR_ORANGE)); + public static final Block PALLIDIUM_FULL = registerBlock("pallidium_full", new PallidiumBlock("full", null)); + public static final Block PALLIDIUM_HEAVY = registerBlock( + "pallidium_heavy", + new PallidiumBlock("heavy", PALLIDIUM_FULL) + ); + public static final Block PALLIDIUM_THIN = registerBlock( + "pallidium_thin", + new PallidiumBlock("thin", PALLIDIUM_HEAVY) + ); + public static final Block PALLIDIUM_TINY = registerBlock( + "pallidium_tiny", + new PallidiumBlock("tiny", PALLIDIUM_THIN) + ); + + // Roads // + public static final Block END_MYCELIUM_PATH = registerBlock("end_mycelium_path", new BasePathBlock(END_MYCELIUM)); + public static final Block END_MOSS_PATH = registerBlock("end_moss_path", new BasePathBlock(END_MOSS)); + public static final Block CHORUS_NYLIUM_PATH = registerBlock( + "chorus_nylium_path", + new BasePathBlock(CHORUS_NYLIUM) + ); + public static final Block CAVE_MOSS_PATH = registerBlock("cave_moss_path", new BasePathBlock(CAVE_MOSS)); + public static final Block CRYSTAL_MOSS_PATH = registerBlock("crystal_moss_path", new BasePathBlock(CRYSTAL_MOSS)); + public static final Block SHADOW_GRASS_PATH = registerBlock("shadow_grass_path", new BasePathBlock(SHADOW_GRASS)); + public static final Block PINK_MOSS_PATH = registerBlock("pink_moss_path", new BasePathBlock(PINK_MOSS)); + public static final Block AMBER_MOSS_PATH = registerBlock("amber_moss_path", new BasePathBlock(AMBER_MOSS)); + public static final Block JUNGLE_MOSS_PATH = registerBlock("jungle_moss_path", new BasePathBlock(JUNGLE_MOSS)); + public static final Block SANGNUM_PATH = registerBlock("sangnum_path", new BasePathBlock(SANGNUM)); + public static final Block RUTISCUS_PATH = registerBlock("rutiscus_path", new BasePathBlock(RUTISCUS)); + + public static final Block MOSSY_OBSIDIAN = registerBlock("mossy_obsidian", new MossyObsidian()); + public static final Block DRAGON_BONE_BLOCK = registerBlock( + "dragon_bone_block", + new BaseRotatedPillarBlock(Blocks.BONE_BLOCK) + ); + public static final Block DRAGON_BONE_STAIRS = registerBlock( + "dragon_bone_stairs", + new BaseStairsBlock(DRAGON_BONE_BLOCK) + ); + public static final Block DRAGON_BONE_SLAB = registerBlock( + "dragon_bone_slab", + new BaseSlabBlock(DRAGON_BONE_BLOCK) + ); + public static final Block MOSSY_DRAGON_BONE = registerBlock("mossy_dragon_bone", new MossyDragonBoneBlock()); + + // Rocks // + public static final StoneMaterial FLAVOLITE = new StoneMaterial("flavolite", MaterialColor.SAND); + public static final StoneMaterial VIOLECITE = new StoneMaterial("violecite", MaterialColor.COLOR_PURPLE); + public static final StoneMaterial SULPHURIC_ROCK = new StoneMaterial("sulphuric_rock", MaterialColor.COLOR_BROWN); + public static final StoneMaterial VIRID_JADESTONE = new StoneMaterial("virid_jadestone", MaterialColor.COLOR_GREEN); + public static final StoneMaterial AZURE_JADESTONE = new StoneMaterial( + "azure_jadestone", + MaterialColor.COLOR_LIGHT_BLUE + ); + public static final StoneMaterial SANDY_JADESTONE = new StoneMaterial( + "sandy_jadestone", + MaterialColor.COLOR_YELLOW + ); + public static final StoneMaterial UMBRALITH = new StoneMaterial("umbralith", MaterialColor.DEEPSLATE); + public static final Block BRIMSTONE = registerBlock("brimstone", new BrimstoneBlock()); + public static final Block SULPHUR_CRYSTAL = registerBlock("sulphur_crystal", new SulphurCrystalBlock()); + public static final Block MISSING_TILE = registerBlock("missing_tile", new MissingTileBlock()); + public static final Block ENDSTONE_FLOWER_POT = registerBlock( + "endstone_flower_pot", + new FlowerPotBlock(Blocks.END_STONE) + ); + + public static final Block FLAVOLITE_RUNED = registerBlock("flavolite_runed", new RunedFlavolite(false)); + public static final Block FLAVOLITE_RUNED_ETERNAL = registerBlock( + "flavolite_runed_eternal", + new RunedFlavolite(true) + ); + + public static final Block ANDESITE_PEDESTAL = registerBlock( + "andesite_pedestal", + new PedestalVanilla(Blocks.ANDESITE) + ); + public static final Block DIORITE_PEDESTAL = registerBlock("diorite_pedestal", new PedestalVanilla(Blocks.DIORITE)); + public static final Block GRANITE_PEDESTAL = registerBlock("granite_pedestal", new PedestalVanilla(Blocks.GRANITE)); + public static final Block QUARTZ_PEDESTAL = registerBlock( + "quartz_pedestal", + new PedestalVanilla(Blocks.QUARTZ_BLOCK) + ); + public static final Block PURPUR_PEDESTAL = registerBlock( + "purpur_pedestal", + new PedestalVanilla(Blocks.PURPUR_BLOCK) + ); + + public static final Block HYDROTHERMAL_VENT = registerBlock("hydrothermal_vent", new HydrothermalVentBlock()); + public static final Block VENT_BUBBLE_COLUMN = registerEndBlockOnly( + "vent_bubble_column", + new VentBubbleColumnBlock() + ); + + public static final Block DENSE_SNOW = registerBlock("dense_snow", new DenseSnowBlock()); + public static final Block EMERALD_ICE = registerBlock("emerald_ice", new EmeraldIceBlock()); + public static final Block DENSE_EMERALD_ICE = registerBlock("dense_emerald_ice", new DenseEmeraldIceBlock()); + public static final Block ANCIENT_EMERALD_ICE = registerBlock("ancient_emerald_ice", new AncientEmeraldIceBlock()); + + public static final Block END_STONE_STALACTITE = registerBlock( + "end_stone_stalactite", + new StalactiteBlock(Blocks.END_STONE) + ); + public static final Block END_STONE_STALACTITE_CAVEMOSS = registerBlock( + "end_stone_stalactite_cavemoss", + new StalactiteBlock(CAVE_MOSS) + ); + + // Wooden Materials And Trees // + public static final Block MOSSY_GLOWSHROOM_SAPLING = registerBlock( + "mossy_glowshroom_sapling", + new MossyGlowshroomSaplingBlock() + ); + public static final Block MOSSY_GLOWSHROOM_CAP = registerBlock( + "mossy_glowshroom_cap", + new MossyGlowshroomCapBlock() + ); + public static final Block MOSSY_GLOWSHROOM_HYMENOPHORE = registerBlock( + "mossy_glowshroom_hymenophore", + new GlowingHymenophoreBlock() + ); + public static final Block MOSSY_GLOWSHROOM_FUR = registerBlock( + "mossy_glowshroom_fur", + new FurBlock( + MOSSY_GLOWSHROOM_SAPLING, + 15, + 16, + true + ) + ); + public static final EndWoodenComplexMaterial MOSSY_GLOWSHROOM = new EndWoodenComplexMaterial( + "mossy_glowshroom", + MaterialColor.COLOR_GRAY, + MaterialColor.WOOD + ).init(); + + public static final Block PYTHADENDRON_SAPLING = registerBlock( + "pythadendron_sapling", + new PythadendronSaplingBlock() + ); + public static final Block PYTHADENDRON_LEAVES = registerBlock( + "pythadendron_leaves", + new PottableLeavesBlock( + PYTHADENDRON_SAPLING, + MaterialColor.COLOR_MAGENTA + ) + ); + public static final EndWoodenComplexMaterial PYTHADENDRON = new EndWoodenComplexMaterial( + "pythadendron", + MaterialColor.COLOR_MAGENTA, + MaterialColor.COLOR_PURPLE + ).init(); + + public static final Block END_LOTUS_SEED = registerBlock("end_lotus_seed", new EndLotusSeedBlock()); + public static final Block END_LOTUS_STEM = registerBlock("end_lotus_stem", new EndLotusStemBlock()); + public static final Block END_LOTUS_LEAF = registerEndBlockOnly("end_lotus_leaf", new EndLotusLeafBlock()); + public static final Block END_LOTUS_FLOWER = registerEndBlockOnly("end_lotus_flower", new EndLotusFlowerBlock()); + public static final EndWoodenComplexMaterial END_LOTUS = new EndWoodenComplexMaterial( + "end_lotus", + MaterialColor.COLOR_LIGHT_BLUE, + MaterialColor.COLOR_CYAN + ).init(); + + public static final Block LACUGROVE_SAPLING = registerBlock("lacugrove_sapling", new LacugroveSaplingBlock()); + public static final Block LACUGROVE_LEAVES = registerBlock( + "lacugrove_leaves", + new PottableLeavesBlock( + LACUGROVE_SAPLING, + MaterialColor.COLOR_CYAN + ) + ); + public static final EndWoodenComplexMaterial LACUGROVE = new EndWoodenComplexMaterial( + "lacugrove", + MaterialColor.COLOR_BROWN, + MaterialColor.COLOR_YELLOW + ).init(); + + public static final Block DRAGON_TREE_SAPLING = registerBlock("dragon_tree_sapling", new DragonTreeSaplingBlock()); + public static final Block DRAGON_TREE_LEAVES = registerBlock( + "dragon_tree_leaves", + new PottableLeavesBlock( + DRAGON_TREE_SAPLING, + MaterialColor.COLOR_MAGENTA + ) + ); + public static final EndWoodenComplexMaterial DRAGON_TREE = new EndWoodenComplexMaterial( + "dragon_tree", + MaterialColor.COLOR_BLACK, + MaterialColor.COLOR_MAGENTA + ).init(); + + public static final Block TENANEA_SAPLING = registerBlock("tenanea_sapling", new TenaneaSaplingBlock()); + public static final Block TENANEA_LEAVES = registerBlock( + "tenanea_leaves", + new PottableLeavesBlock( + TENANEA_SAPLING, + MaterialColor.COLOR_PINK + ) + ); + public static final Block TENANEA_FLOWERS = registerBlock("tenanea_flowers", new TenaneaFlowersBlock()); + public static final Block TENANEA_OUTER_LEAVES = registerBlock( + "tenanea_outer_leaves", + new FurBlock(TENANEA_SAPLING, 32) + ); + public static final EndWoodenComplexMaterial TENANEA = new EndWoodenComplexMaterial( + "tenanea", + MaterialColor.COLOR_BROWN, + MaterialColor.COLOR_PINK + ).init(); + + public static final Block HELIX_TREE_SAPLING = registerBlock("helix_tree_sapling", new HelixTreeSaplingBlock()); + public static final Block HELIX_TREE_LEAVES = registerBlock("helix_tree_leaves", new HelixTreeLeavesBlock()); + public static final EndWoodenComplexMaterial HELIX_TREE = new EndWoodenComplexMaterial( + "helix_tree", + MaterialColor.COLOR_GRAY, + MaterialColor.COLOR_ORANGE + ).init(); + + public static final Block UMBRELLA_TREE_SAPLING = registerBlock( + "umbrella_tree_sapling", + new UmbrellaTreeSaplingBlock() + ); + public static final Block UMBRELLA_TREE_MEMBRANE = registerBlock( + "umbrella_tree_membrane", + new UmbrellaTreeMembraneBlock() + ); + public static final Block UMBRELLA_TREE_CLUSTER = registerBlock( + "umbrella_tree_cluster", + new UmbrellaTreeClusterBlock() + ); + public static final Block UMBRELLA_TREE_CLUSTER_EMPTY = registerBlock( + "umbrella_tree_cluster_empty", + new UmbrellaTreeClusterEmptyBlock() + ); + public static final EndWoodenComplexMaterial UMBRELLA_TREE = new EndWoodenComplexMaterial( + "umbrella_tree", + MaterialColor.COLOR_BLUE, + MaterialColor.COLOR_GREEN + ).init(); + + public static final Block JELLYSHROOM_CAP_PURPLE = registerBlock( + "jellyshroom_cap_purple", + new JellyshroomCapBlock( + 217, + 142, + 255, + 164, + 0, + 255 + ) + ); + public static final EndWoodenComplexMaterial JELLYSHROOM = new EndWoodenComplexMaterial( + "jellyshroom", + MaterialColor.COLOR_PURPLE, + MaterialColor.COLOR_LIGHT_BLUE + ).init(); + + public static final Block LUCERNIA_SAPLING = registerBlock("lucernia_sapling", new LucerniaSaplingBlock()); + public static final Block LUCERNIA_LEAVES = registerBlock( + "lucernia_leaves", + new PottableLeavesBlock( + LUCERNIA_SAPLING, + MaterialColor.COLOR_ORANGE + ) + ); + public static final Block LUCERNIA_OUTER_LEAVES = registerBlock( + "lucernia_outer_leaves", + new FurBlock(LUCERNIA_SAPLING, 32) + ); + public static final EndWoodenComplexMaterial LUCERNIA = new EndWoodenComplexMaterial( + "lucernia", + MaterialColor.COLOR_ORANGE, + MaterialColor.COLOR_ORANGE + ).init(); + + // Small Plants // + public static final Block UMBRELLA_MOSS = registerBlock("umbrella_moss", new UmbrellaMossBlock()); + public static final Block UMBRELLA_MOSS_TALL = registerBlock("umbrella_moss_tall", new UmbrellaMossTallBlock()); + public static final Block CREEPING_MOSS = registerBlock("creeping_moss", new GlowingMossBlock(11)); + public static final Block CHORUS_GRASS = registerBlock("chorus_grass", new ChorusGrassBlock()); + public static final Block CAVE_GRASS = registerBlock("cave_grass", new TerrainPlantBlock(CAVE_MOSS)); + public static final Block CRYSTAL_GRASS = registerBlock("crystal_grass", new TerrainPlantBlock(CRYSTAL_MOSS)); + public static final Block SHADOW_PLANT = registerBlock("shadow_plant", new TerrainPlantBlock(SHADOW_GRASS)); + public static final Block BUSHY_GRASS = registerBlock("bushy_grass", new TerrainPlantBlock(PINK_MOSS)); + public static final Block AMBER_GRASS = registerBlock("amber_grass", new TerrainPlantBlock(AMBER_MOSS)); + public static final Block TWISTED_UMBRELLA_MOSS = registerBlock( + "twisted_umbrella_moss", + new TwistedUmbrellaMossBlock() + ); + public static final Block TWISTED_UMBRELLA_MOSS_TALL = registerBlock( + "twisted_umbrella_moss_tall", + new TwistedUmbrellaMossTallBlock() + ); + public static final Block JUNGLE_GRASS = registerBlock("jungle_grass", new TerrainPlantBlock(JUNGLE_MOSS)); + public static final Block BLOOMING_COOKSONIA = registerBlock("blooming_cooksonia", new TerrainPlantBlock(END_MOSS)); + public static final Block SALTEAGO = registerBlock("salteago", new TerrainPlantBlock(END_MOSS)); + public static final Block VAIOLUSH_FERN = registerBlock("vaiolush_fern", new TerrainPlantBlock(END_MOSS)); + public static final Block FRACTURN = registerBlock("fracturn", new TerrainPlantBlock(END_MOSS)); + public static final Block CLAWFERN = registerBlock( + "clawfern", + new TerrainPlantBlock( + SANGNUM, + MOSSY_OBSIDIAN, + MOSSY_DRAGON_BONE + ) + ); + public static final Block GLOBULAGUS = registerBlock( + "globulagus", + new TerrainPlantBlock( + SANGNUM, + MOSSY_OBSIDIAN, + MOSSY_DRAGON_BONE + ) + ); + public static final Block ORANGO = registerBlock("orango", new TerrainPlantBlock(RUTISCUS)); + public static final Block AERIDIUM = registerBlock("aeridium", new TerrainPlantBlock(RUTISCUS)); + public static final Block LUTEBUS = registerBlock("lutebus", new TerrainPlantBlock(RUTISCUS)); + public static final Block LAMELLARIUM = registerBlock("lamellarium", new TerrainPlantBlock(RUTISCUS)); + public static final Block INFLEXIA = registerBlock( + "inflexia", + new TerrainPlantBlock( + PALLIDIUM_FULL, + PALLIDIUM_HEAVY, + PALLIDIUM_THIN, + PALLIDIUM_TINY + ) + ); + public static final Block FLAMMALIX = registerBlock("flammalix", new FlammalixBlock()); + + public static final Block BLUE_VINE_SEED = registerBlock("blue_vine_seed", new BlueVineSeedBlock()); + public static final Block BLUE_VINE = registerEndBlockOnly("blue_vine", new BlueVineBlock()); + public static final Block BLUE_VINE_LANTERN = registerBlock("blue_vine_lantern", new BlueVineLanternBlock()); + public static final Block BLUE_VINE_FUR = registerBlock( + "blue_vine_fur", + new FurBlock(BLUE_VINE_SEED, 15, 3, false) + ); + + public static final Block LANCELEAF_SEED = registerBlock("lanceleaf_seed", new LanceleafSeedBlock()); + public static final Block LANCELEAF = registerEndBlockOnly("lanceleaf", new LanceleafBlock()); + + public static final Block GLOWING_PILLAR_SEED = registerBlock("glowing_pillar_seed", new GlowingPillarSeedBlock()); + public static final Block GLOWING_PILLAR_ROOTS = registerEndBlockOnly( + "glowing_pillar_roots", + new GlowingPillarRootsBlock() + ); + public static final Block GLOWING_PILLAR_LUMINOPHOR = registerBlock( + "glowing_pillar_luminophor", + new GlowingPillarLuminophorBlock() + ); + public static final Block GLOWING_PILLAR_LEAVES = registerBlock( + "glowing_pillar_leaves", + new FurBlock(GLOWING_PILLAR_SEED, 15, 3, false) + ); + + public static final Block SMALL_JELLYSHROOM = registerBlock("small_jellyshroom", new SmallJellyshroomBlock()); + public static final Block BOLUX_MUSHROOM = registerBlock("bolux_mushroom", new BoluxMushroomBlock()); + + public static final Block LUMECORN_SEED = registerBlock("lumecorn_seed", new LumecornSeedBlock()); + public static final Block LUMECORN = registerEndBlockOnly("lumecorn", new LumecornBlock()); + + public static final Block SMALL_AMARANITA_MUSHROOM = registerBlock( + "small_amaranita_mushroom", + new SmallAmaranitaBlock() + ); + public static final Block LARGE_AMARANITA_MUSHROOM = registerEndBlockOnly( + "large_amaranita_mushroom", + new LargeAmaranitaBlock() + ); + public static final Block AMARANITA_STEM = registerBlock("amaranita_stem", new AmaranitaStemBlock()); + public static final Block AMARANITA_HYPHAE = registerBlock("amaranita_hyphae", new AmaranitaStemBlock()); + public static final Block AMARANITA_HYMENOPHORE = registerBlock( + "amaranita_hymenophore", + new AmaranitaHymenophoreBlock() + ); + public static final Block AMARANITA_LANTERN = registerBlock("amaranita_lantern", new GlowingHymenophoreBlock()); + public static final Block AMARANITA_FUR = registerBlock( + "amaranita_fur", + new FurBlock(SMALL_AMARANITA_MUSHROOM, 15, 4, true) + ); + public static final Block AMARANITA_CAP = registerBlock("amaranita_cap", new AmaranitaCapBlock()); + + public static final Block NEON_CACTUS = registerBlock("neon_cactus", new NeonCactusPlantBlock()); + public static final Block NEON_CACTUS_BLOCK = registerBlock("neon_cactus_block", new NeonCactusBlock()); + public static final Block NEON_CACTUS_BLOCK_STAIRS = registerBlock( + "neon_cactus_stairs", + new BaseStairsBlock(NEON_CACTUS_BLOCK) + ); + public static final Block NEON_CACTUS_BLOCK_SLAB = registerBlock( + "neon_cactus_slab", + new BaseSlabBlock(NEON_CACTUS_BLOCK) + ); + + // Crops + public static final Block SHADOW_BERRY = registerBlock("shadow_berry", new ShadowBerryBlock()); + public static final Block BLOSSOM_BERRY = registerBlock( + "blossom_berry_seed", + new PottableCropBlock(EndItems.BLOSSOM_BERRY, PINK_MOSS) + ); + public static final Block AMBER_ROOT = registerBlock( + "amber_root_seed", + new PottableCropBlock(EndItems.AMBER_ROOT_RAW, AMBER_MOSS) + ); + public static final Block CHORUS_MUSHROOM = registerBlock( + "chorus_mushroom_seed", + new PottableCropBlock( + EndItems.CHORUS_MUSHROOM_RAW, + CHORUS_NYLIUM + ) + ); + //public static final Block PEARLBERRY = registerBlock("pearlberry_seed", new PottableCropBlock(EndItems.BLOSSOM_BERRY, END_MOSS, END_MYCELIUM)); + public static final Block CAVE_PUMPKIN_SEED = registerBlock("cave_pumpkin_seed", new CavePumpkinVineBlock()); + public static final Block CAVE_PUMPKIN = registerBlock("cave_pumpkin", new CavePumpkinBlock()); + + // Water plants + public static final Block BUBBLE_CORAL = registerBlock("bubble_coral", new BubbleCoralBlock()); + public static final Block MENGER_SPONGE = registerBlock("menger_sponge", new MengerSpongeBlock()); + public static final Block MENGER_SPONGE_WET = registerBlock("menger_sponge_wet", new MengerSpongeWetBlock()); + public static final Block CHARNIA_RED = registerBlock("charnia_red", new CharniaBlock()); + public static final Block CHARNIA_PURPLE = registerBlock("charnia_purple", new CharniaBlock()); + public static final Block CHARNIA_ORANGE = registerBlock("charnia_orange", new CharniaBlock()); + public static final Block CHARNIA_LIGHT_BLUE = registerBlock("charnia_light_blue", new CharniaBlock()); + public static final Block CHARNIA_CYAN = registerBlock("charnia_cyan", new CharniaBlock()); + public static final Block CHARNIA_GREEN = registerBlock("charnia_green", new CharniaBlock()); + + public static final Block END_LILY = registerEndBlockOnly("end_lily", new EndLilyBlock()); + public static final Block END_LILY_SEED = registerBlock("end_lily_seed", new EndLilySeedBlock()); + + public static final Block HYDRALUX_SAPLING = registerBlock("hydralux_sapling", new HydraluxSaplingBlock()); + public static final Block HYDRALUX = registerEndBlockOnly("hydralux", new HydraluxBlock()); + public static final Block HYDRALUX_PETAL_BLOCK = registerBlock("hydralux_petal_block", new HydraluxPetalBlock()); + public static final ColoredMaterial HYDRALUX_PETAL_BLOCK_COLORED = new ColoredMaterial( + HydraluxPetalColoredBlock::new, + HYDRALUX_PETAL_BLOCK, + true + ); + + public static final Block POND_ANEMONE = registerBlock("pond_anemone", new PondAnemoneBlock()); + + public static final Block FLAMAEA = registerBlock("flamaea", new FlamaeaBlock()); + + public static final Block CAVE_BUSH = registerBlock( + "cave_bush", + new SimpleLeavesBlock(MaterialColor.COLOR_MAGENTA) + ); + + public static final Block MURKWEED = registerBlock("murkweed", new MurkweedBlock()); + public static final Block NEEDLEGRASS = registerBlock("needlegrass", new NeedlegrassBlock()); + + // Wall Plants // + public static final Block PURPLE_POLYPORE = registerBlock("purple_polypore", new EndWallMushroom(13)); + public static final Block AURANT_POLYPORE = registerBlock("aurant_polypore", new EndWallMushroom(13)); + public static final Block TAIL_MOSS = registerBlock("tail_moss", new EndWallPlantBlock()); + public static final Block CYAN_MOSS = registerBlock("cyan_moss", new EndWallPlantBlock()); + public static final Block TWISTED_MOSS = registerBlock("twisted_moss", new EndWallPlantBlock()); + public static final Block TUBE_WORM = registerBlock("tube_worm", new EndUnderwaterWallPlantBlock()); + public static final Block BULB_MOSS = registerBlock("bulb_moss", new EndWallPlantBlock(12)); + public static final Block JUNGLE_FERN = registerBlock("jungle_fern", new EndWallPlantBlock()); + public static final Block RUSCUS = registerBlock("ruscus", new EndWallPlantBlock()); + + // Vines // + public static final Block DENSE_VINE = registerBlock("dense_vine", new BaseVineBlock(15, true)); + public static final Block TWISTED_VINE = registerBlock("twisted_vine", new BaseVineBlock()); + public static final Block BULB_VINE_SEED = registerBlock("bulb_vine_seed", new BulbVineSeedBlock()); + public static final Block BULB_VINE = registerBlock("bulb_vine", new BulbVineBlock()); + public static final Block JUNGLE_VINE = registerBlock("jungle_vine", new BaseVineBlock()); + public static final Block RUBINEA = registerBlock("rubinea", new BaseVineBlock()); + public static final Block MAGNULA = registerBlock("magnula", new BaseVineBlock()); + public static final Block FILALUX = registerBlock("filalux", new FilaluxBlock()); + public static final Block FILALUX_WINGS = registerBlock("filalux_wings", new FilaluxWingsBlock()); + public static final Block FILALUX_LANTERN = registerBlock("filalux_lantern", new FilaluxLanternBlock()); + + // Mob-Related + public static final Block SILK_MOTH_NEST = registerBlock("silk_moth_nest", new SilkMothNestBlock()); + public static final Block SILK_MOTH_HIVE = registerBlock("silk_moth_hive", new SilkMothHiveBlock()); + + // Ores // + public static final Block ENDER_ORE = registerBlock( + "ender_ore", + new BaseOreBlock(() -> EndItems.ENDER_SHARD, 1, 3, 5) + ); + public static final Block AMBER_ORE = registerBlock( + "amber_ore", + new BaseOreBlock(() -> EndItems.RAW_AMBER, 1, 2, 4) + ); + + // Materials // + public static final MetalMaterial THALLASIUM = MetalMaterial.makeNormal( + "thallasium", + MaterialColor.COLOR_BLUE, + EndToolMaterial.THALLASIUM, + EndArmorMaterial.THALLASIUM, + EndToolMaterial.THALLASIUM.getLevel() + ); + + public static final MetalMaterial TERMINITE = MetalMaterial.makeOreless( + "terminite", + MaterialColor.WARPED_WART_BLOCK, + 7F, + 9F, + EndToolMaterial.TERMINITE, + EndArmorMaterial.TERMINITE, + EndToolMaterial.TERMINITE.getLevel() + ); + public static final Block AETERNIUM_BLOCK = registerBlock("aeternium_block", new AeterniumBlock()); + public static final Block CHARCOAL_BLOCK = registerBlock("charcoal_block", new CharcoalBlock()); + + public static final Block ENDER_BLOCK = registerBlock("ender_block", new EnderBlock()); + public static final Block AURORA_CRYSTAL = registerBlock("aurora_crystal", new AuroraCrystalBlock()); + public static final Block AMBER_BLOCK = registerBlock("amber_block", new AmberBlock()); + public static final Block SMARAGDANT_CRYSTAL_SHARD = registerBlock( + "smaragdant_crystal_shard", + new SmaragdantCrystalShardBlock() + ); + public static final Block SMARAGDANT_CRYSTAL = registerBlock("smaragdant_crystal", new SmaragdantCrystalBlock()); + public static final CrystalSubblocksMaterial SMARAGDANT_SUBBLOCKS = new CrystalSubblocksMaterial( + "smaragdant_crystal", + SMARAGDANT_CRYSTAL + ); + + public static final Block RESPAWN_OBELISK = registerBlock("respawn_obelisk", new RespawnObeliskBlock()); + + // Lanterns + public static final Block ANDESITE_LANTERN = registerBlock( + "andesite_lantern", + new StoneLanternBlock(Blocks.ANDESITE) + ); + public static final Block DIORITE_LANTERN = registerBlock("diorite_lantern", new StoneLanternBlock(Blocks.DIORITE)); + public static final Block GRANITE_LANTERN = registerBlock("granite_lantern", new StoneLanternBlock(Blocks.GRANITE)); + public static final Block QUARTZ_LANTERN = registerBlock( + "quartz_lantern", + new StoneLanternBlock(Blocks.QUARTZ_BLOCK) + ); + public static final Block PURPUR_LANTERN = registerBlock( + "purpur_lantern", + new StoneLanternBlock(Blocks.PURPUR_BLOCK) + ); + public static final Block END_STONE_LANTERN = registerBlock( + "end_stone_lantern", + new StoneLanternBlock(Blocks.END_STONE) + ); + public static final Block BLACKSTONE_LANTERN = registerBlock( + "blackstone_lantern", + new StoneLanternBlock(Blocks.BLACKSTONE) + ); + + public static final Block IRON_BULB_LANTERN = registerBlock("iron_bulb_lantern", new BulbVineLanternBlock()); + public static final ColoredMaterial IRON_BULB_LANTERN_COLORED = new ColoredMaterial( + BulbVineLanternColoredBlock::new, + IRON_BULB_LANTERN, + false + ); + + public static final Block IRON_CHANDELIER = EndBlocks.registerBlock( + "iron_chandelier", + new ChandelierBlock(Blocks.GOLD_BLOCK) + ); + public static final Block GOLD_CHANDELIER = EndBlocks.registerBlock( + "gold_chandelier", + new ChandelierBlock(Blocks.GOLD_BLOCK) + ); + + // Blocks With Entity // + public static final Block END_STONE_FURNACE = registerBlock( + "end_stone_furnace", + new BaseFurnaceBlock(Blocks.END_STONE) + ); + public static final Block END_STONE_SMELTER = registerBlock("end_stone_smelter", new EndStoneSmelter()); + public static final Block ETERNAL_PEDESTAL = registerBlock("eternal_pedestal", new EternalPedestal()); + public static final Block INFUSION_PEDESTAL = registerBlock("infusion_pedestal", new InfusionPedestal()); + public static final Block AETERNIUM_ANVIL = registerBlock("aeternium_anvil", new AeterniumAnvil()); + + // Technical + public static final Block END_PORTAL_BLOCK = registerEndBlockOnly("end_portal_block", new EndPortalBlock()); + + public static List getModBlocks() { + return BlockRegistry.getModBlocks(BetterEnd.MOD_ID); + } + + public static List getModBlockItems() { + return BlockRegistry.getModBlockItems(BetterEnd.MOD_ID); + } + + public static Block registerBlock(ResourceLocation id, Block block) { + if (!Configs.BLOCK_CONFIG.getBooleanRoot(id.getPath(), true)) { + return block; + } + getBlockRegistry().register(id, block); + return block; + } + + public static Block registerBlock(String name, Block block) { + return registerBlock(BetterEnd.makeID(name), block); + } + + public static Block registerEndBlockOnly(String name, Block block) { + return getBlockRegistry().registerBlockOnly(BetterEnd.makeID(name), block); + } + + public static FabricItemSettings makeBlockItemSettings() { + return getBlockRegistry().makeItemSettings(); + } + + @NotNull + public static BlockRegistry getBlockRegistry() { + return REGISTRY; + } + + @ApiStatus.Internal + public static void ensureStaticallyLoaded() { + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndEnchantments.java b/src/main/java/org/betterx/betterend/registry/EndEnchantments.java new file mode 100644 index 00000000..a47ac1f6 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndEnchantments.java @@ -0,0 +1,22 @@ +package org.betterx.betterend.registry; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.effects.enchantment.EndVeilEnchantment; + +import net.minecraft.core.Registry; +import net.minecraft.world.item.enchantment.Enchantment; + +public class EndEnchantments { + public final static Enchantment END_VEIL = registerEnchantment("end_veil", new EndVeilEnchantment()); + + public static Enchantment registerEnchantment(String name, Enchantment enchantment) { + if (!Configs.ENCHANTMENT_CONFIG.getBooleanRoot(name, true)) { + return enchantment; + } + return Registry.register(Registry.ENCHANTMENT, BetterEnd.makeID(name), enchantment); + } + + public static void register() { + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndEntities.java b/src/main/java/org/betterx/betterend/registry/EndEntities.java new file mode 100644 index 00000000..e101d79a --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndEntities.java @@ -0,0 +1,155 @@ +package org.betterx.betterend.registry; + +import org.betterx.bclib.api.v2.spawning.SpawnRuleBuilder; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.entity.*; +import org.betterx.ui.ColorUtil; + +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.EntityType.EntityFactory; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier.Builder; +import net.minecraft.world.level.levelgen.Heightmap.Types; + +import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; +import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder; + +public class EndEntities { + public static final EntityType DRAGONFLY = register( + "dragonfly", + MobCategory.AMBIENT, + 0.6F, + 0.5F, + DragonflyEntity::new, + DragonflyEntity.createMobAttributes(), + true, + ColorUtil.color(32, 42, 176), + ColorUtil.color(115, 225, 249) + ); + public static final EntityType END_SLIME = register( + "end_slime", + MobCategory.MONSTER, + 2F, + 2F, + EndSlimeEntity::new, + EndSlimeEntity.createMobAttributes(), + false, + ColorUtil.color(28, 28, 28), + ColorUtil.color(99, 11, 99) + ); + public static final EntityType END_FISH = register( + "end_fish", + MobCategory.WATER_AMBIENT, + 0.5F, + 0.5F, + EndFishEntity::new, + EndFishEntity.createMobAttributes(), + true, + ColorUtil.color(3, 50, 76), + ColorUtil.color(120, 206, 255) + ); + public static final EntityType SHADOW_WALKER = register( + "shadow_walker", + MobCategory.MONSTER, + 0.6F, + 1.95F, + ShadowWalkerEntity::new, + ShadowWalkerEntity.createMobAttributes(), + true, + ColorUtil.color(30, 30, 30), + ColorUtil.color(5, 5, 5) + ); + public static final EntityType CUBOZOA = register( + "cubozoa", + MobCategory.WATER_AMBIENT, + 0.6F, + 1F, + CubozoaEntity::new, + CubozoaEntity.createMobAttributes(), + true, + ColorUtil.color(151, 77, 181), + ColorUtil.color(93, 176, 238) + ); + public static final EntityType SILK_MOTH = register( + "silk_moth", + MobCategory.AMBIENT, + 0.6F, + 0.6F, + SilkMothEntity::new, + SilkMothEntity.createMobAttributes(), + true, + ColorUtil.color(198, 138, 204), + ColorUtil.color(242, 220, 236) + ); + + public static void register() { + // Air // + SpawnRuleBuilder.start(DRAGONFLY).aboveGround(2).maxNearby(8).buildNoRestrictions(Types.MOTION_BLOCKING); + SpawnRuleBuilder.start(SILK_MOTH).aboveGround(2).maxNearby(4).buildNoRestrictions(Types.MOTION_BLOCKING); + + // Land // + SpawnRuleBuilder + .start(END_SLIME) + .notPeaceful() + .maxNearby(4, 64) + .onlyOnValidBlocks() + .customRule(EndSlimeEntity::canSpawn) + .buildNoRestrictions(Types.MOTION_BLOCKING); + + SpawnRuleBuilder.start(SHADOW_WALKER) + .vanillaHostile() + .onlyOnValidBlocks() + .maxNearby(8, 64) + .buildNoRestrictions(Types.MOTION_BLOCKING); + + // Water // + SpawnRuleBuilder.start(END_FISH).maxNearby(8, 64).buildInWater(Types.MOTION_BLOCKING); + SpawnRuleBuilder.start(CUBOZOA).maxNearby(8, 64).buildInWater(Types.MOTION_BLOCKING); + } + + protected static EntityType register( + String name, + MobCategory group, + float width, + float height, + EntityFactory entity + ) { + ResourceLocation id = BetterEnd.makeID(name); + EntityType type = FabricEntityTypeBuilder + .create(group, entity) + .dimensions(EntityDimensions.fixed(width, height)) + .build(); + if (Configs.ENTITY_CONFIG.getBooleanRoot(id.getPath(), true)) { + return Registry.register(Registry.ENTITY_TYPE, id, type); + } + return type; + } + + private static EntityType register( + String name, + MobCategory group, + float width, + float height, + EntityFactory entity, + Builder attributes, + boolean fixedSize, + int eggColor, + int dotsColor + ) { + ResourceLocation id = BetterEnd.makeID(name); + EntityType type = FabricEntityTypeBuilder + .create(group, entity) + .dimensions(fixedSize + ? EntityDimensions.fixed(width, height) + : EntityDimensions.scalable(width, height)) + .build(); + if (Configs.ENTITY_CONFIG.getBooleanRoot(id.getPath(), true)) { + FabricDefaultAttributeRegistry.register(type, attributes); + EndItems.registerEndEgg("spawn_egg_" + name, type, eggColor, dotsColor); + return Registry.register(Registry.ENTITY_TYPE, BetterEnd.makeID(name), type); + } + return type; + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndEntitiesRenders.java b/src/main/java/org/betterx/betterend/registry/EndEntitiesRenders.java new file mode 100644 index 00000000..e168eac2 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndEntitiesRenders.java @@ -0,0 +1,73 @@ +package org.betterx.betterend.registry; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.entity.model.*; +import org.betterx.betterend.entity.render.*; +import org.betterx.betterend.item.model.*; + +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.renderer.entity.EntityRendererProvider.Context; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.world.entity.EntityType; + +import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry; +import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; + +import java.util.function.Function; + +public class EndEntitiesRenders { + public static final ModelLayerLocation DRAGONFLY_MODEL = registerMain("dragonfly"); + public static final ModelLayerLocation END_SLIME_SHELL_MODEL = registerMain("endslime_shell"); + public static final ModelLayerLocation END_SLIME_MODEL = registerMain("endslime"); + public static final ModelLayerLocation END_FISH_MODEL = registerMain("endfish"); + public static final ModelLayerLocation CUBOZOA_MODEL = registerMain("cubozoa"); + public static final ModelLayerLocation SILK_MOTH_MODEL = registerMain("silkmoth"); + public static final ModelLayerLocation TEST_MODEL = registerMain("test"); + + public static final ModelLayerLocation ARMORED_ELYTRA = registerMain("armored_elytra"); + public static final ModelLayerLocation CRYSTALITE_CHESTPLATE = registerMain("crystalite_chestplate"); + public static final ModelLayerLocation CRYSTALITE_CHESTPLATE_THIN = registerMain("crystalite_chestplate_thin"); + public static final ModelLayerLocation CRYSTALITE_HELMET = registerMain("crystalite_helmet"); + public static final ModelLayerLocation CRYSTALITE_LEGGINGS = registerMain("crystalite_leggings"); + public static final ModelLayerLocation CRYSTALITE_BOOTS = registerMain("crystalite_boots"); + + public static void register() { + register(EndEntities.DRAGONFLY, RendererEntityDragonfly::new); + register(EndEntities.END_SLIME, RendererEntityEndSlime::new); + register(EndEntities.END_FISH, RendererEntityEndFish::new); + register(EndEntities.SHADOW_WALKER, RendererEntityShadowWalker::new); + register(EndEntities.CUBOZOA, RendererEntityCubozoa::new); + register(EndEntities.SILK_MOTH, SilkMothEntityRenderer::new); + + EntityModelLayerRegistry.registerModelLayer(DRAGONFLY_MODEL, DragonflyEntityModel::getTexturedModelData); + EntityModelLayerRegistry.registerModelLayer( + END_SLIME_SHELL_MODEL, + EndSlimeEntityModel::getShellOnlyTexturedModelData + ); + EntityModelLayerRegistry.registerModelLayer(END_SLIME_MODEL, EndSlimeEntityModel::getCompleteTexturedModelData); + EntityModelLayerRegistry.registerModelLayer(END_FISH_MODEL, EndFishEntityModel::getTexturedModelData); + EntityModelLayerRegistry.registerModelLayer(CUBOZOA_MODEL, CubozoaEntityModel::getTexturedModelData); + EntityModelLayerRegistry.registerModelLayer(SILK_MOTH_MODEL, SilkMothEntityModel::getTexturedModelData); + + EntityModelLayerRegistry.registerModelLayer(ARMORED_ELYTRA, ArmoredElytraModel::getTexturedModelData); + EntityModelLayerRegistry.registerModelLayer( + CRYSTALITE_CHESTPLATE, + CrystaliteChestplateModel::getRegularTexturedModelData + ); + EntityModelLayerRegistry.registerModelLayer( + CRYSTALITE_CHESTPLATE_THIN, + CrystaliteChestplateModel::getThinTexturedModelData + ); + EntityModelLayerRegistry.registerModelLayer(CRYSTALITE_HELMET, CrystaliteHelmetModel::getTexturedModelData); + EntityModelLayerRegistry.registerModelLayer(CRYSTALITE_LEGGINGS, CrystaliteLeggingsModel::getTexturedModelData); + EntityModelLayerRegistry.registerModelLayer(CRYSTALITE_BOOTS, CrystaliteBootsModel::getTexturedModelData); + } + + private static void register(EntityType type, Function renderer) { + EntityRendererRegistry.register(type, (context) -> renderer.apply(context)); + } + + private static ModelLayerLocation registerMain(String id) { + return new ModelLayerLocation(BetterEnd.makeID(id), "main"); + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndFeatures.java b/src/main/java/org/betterx/betterend/registry/EndFeatures.java new file mode 100644 index 00000000..600fb65e --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndFeatures.java @@ -0,0 +1,1321 @@ +package org.betterx.betterend.registry; + +import org.betterx.bclib.BCLib; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.api.v3.levelgen.features.BCLConfigureFeature; +import org.betterx.bclib.api.v3.levelgen.features.BCLFeature; +import org.betterx.bclib.api.v3.levelgen.features.BCLFeatureBuilder; +import org.betterx.bclib.util.JsonFactory; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.complexmaterials.StoneMaterial; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.betterend.world.biome.cave.EndCaveBiome; +import org.betterx.betterend.world.features.*; +import org.betterx.betterend.world.features.bushes.*; +import org.betterx.betterend.world.features.terrain.*; +import org.betterx.betterend.world.features.terrain.caves.CaveChunkPopulatorFeature; +import org.betterx.betterend.world.features.terrain.caves.RoundCaveFeature; +import org.betterx.betterend.world.features.terrain.caves.TunelCaveFeature; +import org.betterx.betterend.world.features.trees.*; + +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.data.BuiltinRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.GenerationStep.Decoration; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.OreFeature; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration; +import net.minecraft.world.level.levelgen.feature.configurations.SimpleBlockConfiguration; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +import com.google.common.collect.Lists; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +import java.io.InputStream; +import java.util.List; + +public class EndFeatures { + public static final StalactiteFeature STALACTITE_FEATURE = inlineBuild( + "stalactite_feature", + new StalactiteFeature() + ); + public static final BuildingListFeature BUILDING_LIST_FEATURE = inlineBuild( + "building_list_feature", + new BuildingListFeature() + ); + + public static final VineFeature VINE_FEATURE = inlineBuild( + "vine_feature", + new VineFeature() + ); + + public static final WallPlantFeature WALL_PLANT_FEATURE = inlineBuild( + "wall_plant_feature", + new WallPlantFeature() + ); + + public static final WallPlantOnLogFeature WALL_PLANT_ON_LOG_FEATURE = inlineBuild( + "wall_plant_on_log_feature", + new WallPlantOnLogFeature() + ); + + public static final GlowPillarFeature GLOW_PILLAR_FEATURE = inlineBuild( + "glow_pillar_feature", + new GlowPillarFeature() + ); + + public static final HydraluxFeature HYDRALUX_FEATURE = inlineBuild( + "hydralux_feature", + new HydraluxFeature() + ); + + public static final LanceleafFeature LANCELEAF_FEATURE = inlineBuild( + "lanceleaf_feature", + new LanceleafFeature() + ); + + public static final MengerSpongeFeature MENGER_SPONGE_FEATURE = inlineBuild( + "menger_sponge_feature", + new MengerSpongeFeature() + ); + + public static final CaveChunkPopulatorFeature CAVE_CHUNK_POPULATOR = inlineBuild( + "cave_chunk_populator", + new CaveChunkPopulatorFeature() + ); + + public static final SinglePlantFeature SINGLE_PLANT_FEATURE = inlineBuild( + "single_plant_feature", + new SinglePlantFeature() + ); + + public static final SingleInvertedScatterFeature SINGLE_INVERTED_SCATTER_FEATURE = inlineBuild( + "single_inverted_scatter_feature", + new SingleInvertedScatterFeature() + ); + + public static final DoublePlantFeature DOUBLE_PLANT_FEATURE = inlineBuild( + "double_plant_feature", + new DoublePlantFeature() + ); + + public static final UnderwaterPlantFeature UNDERWATER_PLANT_FEATURE = inlineBuild( + "underwater_plant_feature", + new UnderwaterPlantFeature() + ); + + public static final ArchFeature ARCH_FEATURE = inlineBuild( + "arch_feature", + new ArchFeature() + ); + + public static final ThinArchFeature THIN_ARCH_FEATURE = inlineBuild( + "thin_arch_feature", + new ThinArchFeature() + ); + + public static final CharniaFeature CHARNIA_FEATURE = inlineBuild( + "charnia_feature", + new CharniaFeature() + ); + + public static final BlueVineFeature BLUE_VINE_FEATURE = inlineBuild( + "blue_vine_feature", + new BlueVineFeature() + ); + + public static final FilaluxFeature FILALUX_FEATURE = inlineBuild( + "filalux_feature", + new FilaluxFeature() + ); + + public static final EndLilyFeature END_LILY_FEATURE = inlineBuild( + "end_lily_feature", + new EndLilyFeature() + ); + + public static final EndLotusFeature END_LOTUS_FEATURE = inlineBuild( + "end_lotus_feature", + new EndLotusFeature() + ); + + public static final BushFeature BUSH_FEATURE = inlineBuild( + "bush_feature", + new BushFeature() + ); + + public static final SingleBlockFeature SINGLE_BLOCK_FEATURE = inlineBuild( + "single_block_feature", + new SingleBlockFeature() + ); + + public static final BushWithOuterFeature BUSH_WITH_OUTER_FEATURE = inlineBuild( + "bush_with_outer_feature", + new BushWithOuterFeature() + ); + public static final BCLFeature MOSSY_GLOWSHROOM = registerVegetation( + "mossy_glowshroom", + inlineBuild("mossy_glowshroom", new MossyGlowshroomFeature()), + 2 + ); + public static final BCLFeature PYTHADENDRON_TREE = registerVegetation( + "pythadendron_tree", + inlineBuild("pythadendron_tree", new PythadendronTreeFeature()), + 1 + ); + public static final BCLFeature LACUGROVE = registerVegetation( + "lacugrove", + inlineBuild("lacugrove", new LacugroveFeature()), + 4 + ); + public static final BCLFeature DRAGON_TREE = registerVegetation( + "dragon_tree", + inlineBuild("dragon_tree", new DragonTreeFeature()), + 2 + ); + public static final BCLFeature TENANEA = registerVegetation( + "tenanea", + inlineBuild("tenanea", new TenaneaFeature()), + 3 + ); + public static final BCLFeature HELIX_TREE = registerVegetation( + "helix_tree", + inlineBuild("helix_tree", new HelixTreeFeature()), + 1 + ); + public static final BCLFeature UMBRELLA_TREE = registerVegetation( + "umbrella_tree", + inlineBuild("umbrella_tree", new UmbrellaTreeFeature()), + 2 + ); + public static final BCLFeature JELLYSHROOM = registerVegetation( + "jellyshroom", + inlineBuild("jellyshroom", new JellyshroomFeature()), + 2 + ); + public static final BCLFeature GIGANTIC_AMARANITA = registerVegetation( + "gigantic_amaranita", + inlineBuild("gigantic_amaranita", new GiganticAmaranitaFeature()), + 1 + ); + public static final BCLFeature LUCERNIA = registerVegetation( + "lucernia", + inlineBuild("lucernia", new LucerniaFeature()), + 3 + ); + + // Bushes // + public static final BCLFeature PYTHADENDRON_BUSH = registerVegetation( + "pythadendron_bush", + BUSH_FEATURE, + new BushFeatureConfig( + EndBlocks.PYTHADENDRON_LEAVES, + EndBlocks.PYTHADENDRON.getBark() + ), + 3 + ); + public static final BCLFeature DRAGON_TREE_BUSH = registerVegetation( + "dragon_tree_bush", + BUSH_FEATURE, + new BushFeatureConfig( + EndBlocks.DRAGON_TREE_LEAVES, + EndBlocks.DRAGON_TREE.getBark() + ), + 5 + ); + public static final BCLFeature TENANEA_BUSH = registerVegetation( + "tenanea_bush", + inlineBuild("tenanea_bush", new TenaneaBushFeature()), + 12 + ); + public static final BCLFeature LUMECORN = registerVegetation( + "lumecorn", + inlineBuild("lumecorn", new Lumecorn()), + 5 + ); + public static final BCLFeature LARGE_AMARANITA = registerVegetation( + "large_amaranita", + inlineBuild("large_amaranita", new LargeAmaranitaFeature()), + 5 + ); + public static final BCLFeature LUCERNIA_BUSH = registerVegetation( + "lucernia_bush", + BUSH_WITH_OUTER_FEATURE, + new BushWithOuterFeatureConfig( + EndBlocks.LUCERNIA_LEAVES, + EndBlocks.LUCERNIA_OUTER_LEAVES, + EndBlocks.LUCERNIA.getBark() + ), + 10 + ); + public static final BCLFeature LUCERNIA_BUSH_RARE = registerVegetation( + "lucernia_bush_rare", + BUSH_WITH_OUTER_FEATURE, + new BushWithOuterFeatureConfig( + EndBlocks.LUCERNIA_LEAVES, + EndBlocks.LUCERNIA_OUTER_LEAVES, + EndBlocks.LUCERNIA.getBark() + ), + 1 + ); + public static final BCLFeature NEON_CACTUS = registerVegetation( + "neon_cactus", + inlineBuild("neon_cactus", new NeonCactusFeature()), + 2 + ); + + // Plants // + public static final BCLFeature UMBRELLA_MOSS = registerVegetation( + "umbrella_moss", + new DoublePlantFeatureConfig( + EndBlocks.UMBRELLA_MOSS, + EndBlocks.UMBRELLA_MOSS_TALL, + 5 + ), + 3 + ); + public static final BCLFeature CREEPING_MOSS = registerVegetation( + "creeping_moss", + new SinglePlantFeatureConfig( + EndBlocks.CREEPING_MOSS, + 5 + ), + 3 + ); + public static final BCLFeature BLUE_VINE = registerVegetation( + "blue_vine", + BLUE_VINE_FEATURE, + ScatterFeatureConfig.blueVine(), + 1 + ); + public static final BCLFeature CHORUS_GRASS = registerVegetation( + "chorus_grass", + new SinglePlantFeatureConfig(EndBlocks.CHORUS_GRASS, 4), + 3 + ); + public static final BCLFeature CRYSTAL_GRASS = registerVegetation( + "crystal_grass", + new SinglePlantFeatureConfig( + EndBlocks.CRYSTAL_GRASS, + 8, + false + ), + 5 + ); + public static final BCLFeature SHADOW_PLANT = registerVegetation( + "shadow_plant", + new SinglePlantFeatureConfig(EndBlocks.SHADOW_PLANT, 6), + 5 + ); + public static final BCLFeature MURKWEED = registerVegetation( + "murkweed", + new SinglePlantFeatureConfig(EndBlocks.MURKWEED, 3), + 2 + ); + public static final BCLFeature NEEDLEGRASS = registerVegetation( + "needlegrass", + new SinglePlantFeatureConfig(EndBlocks.NEEDLEGRASS, 3), + 1 + ); + public static final BCLFeature SHADOW_BERRY = registerVegetation( + "shadow_berry", + new SinglePlantFeatureConfig(EndBlocks.SHADOW_BERRY, 2), + 1 + ); + public static final BCLFeature BUSHY_GRASS = registerVegetation( + "bushy_grass", + new SinglePlantFeatureConfig( + EndBlocks.BUSHY_GRASS, + 8, + false + ), + 10 + ); + public static final BCLFeature BUSHY_GRASS_WG = registerVegetation( + "bushy_grass_wg", + new SinglePlantFeatureConfig(EndBlocks.BUSHY_GRASS, 5), + 8 + ); + public static final BCLFeature AMBER_GRASS = registerVegetation( + "amber_grass", + new SinglePlantFeatureConfig(EndBlocks.AMBER_GRASS, 6), + 7 + ); + public static final BCLFeature LANCELEAF = registerVegetation( + "lanceleaf", + LANCELEAF_FEATURE, + ScatterFeatureConfig.lanceleaf(), + 2 + ); + public static final BCLFeature GLOW_PILLAR = registerVegetation( + "glow_pillar", + GLOW_PILLAR_FEATURE, + ScatterFeatureConfig.glowPillar(), + 1 + ); + public static final BCLFeature TWISTED_UMBRELLA_MOSS = registerVegetation( + "twisted_umbrella_moss", + new DoublePlantFeatureConfig( + EndBlocks.TWISTED_UMBRELLA_MOSS, + EndBlocks.TWISTED_UMBRELLA_MOSS_TALL, + 6 + ), + 3 + ); + public static final BCLFeature JUNGLE_GRASS = registerVegetation( + "jungle_grass", + new SinglePlantFeatureConfig( + EndBlocks.JUNGLE_GRASS, + 7, + 3 + ), + 6 + ); + public static final BCLFeature SMALL_JELLYSHROOM_FLOOR = registerVegetation( + "small_jellyshroom_floor", + new SinglePlantFeatureConfig( + EndBlocks.SMALL_JELLYSHROOM, + 5, + 5 + ), + 2 + ); + public static final BCLFeature BLOSSOM_BERRY = registerVegetation( + "blossom_berry", + new SinglePlantFeatureConfig( + EndBlocks.BLOSSOM_BERRY, + 4, + 4 + ), + 3 + ); + public static final BCLFeature BLOOMING_COOKSONIA = registerVegetation( + "blooming_cooksonia", + new SinglePlantFeatureConfig( + EndBlocks.BLOOMING_COOKSONIA, + 5 + ), + 5 + ); + public static final BCLFeature SALTEAGO = registerVegetation( + "salteago", + new SinglePlantFeatureConfig(EndBlocks.SALTEAGO, 5), + 5 + ); + public static final BCLFeature VAIOLUSH_FERN = registerVegetation( + "vaiolush_fern", + new SinglePlantFeatureConfig( + EndBlocks.VAIOLUSH_FERN, + 5 + ), + 5 + ); + public static final BCLFeature FRACTURN = registerVegetation( + "fracturn", + new SinglePlantFeatureConfig(EndBlocks.FRACTURN, 5), + 5 + ); + public static final BCLFeature UMBRELLA_MOSS_RARE = registerVegetation( + "umbrella_moss_rare", + new SinglePlantFeatureConfig( + EndBlocks.UMBRELLA_MOSS, + 3 + ), + 2 + ); + public static final BCLFeature CREEPING_MOSS_RARE = registerVegetation( + "creeping_moss_rare", + new SinglePlantFeatureConfig( + EndBlocks.CREEPING_MOSS, + 3 + ), + 2 + ); + public static final BCLFeature TWISTED_UMBRELLA_MOSS_RARE = registerVegetation( + "twisted_umbrella_moss_rare", + new SinglePlantFeatureConfig( + EndBlocks.TWISTED_UMBRELLA_MOSS, + 3 + ), + 2 + ); + public static final BCLFeature ORANGO = registerVegetation( + "orango", + new SinglePlantFeatureConfig(EndBlocks.ORANGO, 5), + 6 + ); + public static final BCLFeature AERIDIUM = registerVegetation( + "aeridium", + new SinglePlantFeatureConfig(EndBlocks.AERIDIUM, 5, 4), + 5 + ); + public static final BCLFeature LUTEBUS = registerVegetation( + "lutebus", + new SinglePlantFeatureConfig(EndBlocks.LUTEBUS, 5, 2), + 5 + ); + public static final BCLFeature LAMELLARIUM = registerVegetation( + "lamellarium", + new SinglePlantFeatureConfig(EndBlocks.LAMELLARIUM, 5), + 6 + ); + public static final BCLFeature SMALL_AMARANITA = registerVegetation( + "small_amaranita", + new SinglePlantFeatureConfig( + EndBlocks.SMALL_AMARANITA_MUSHROOM, + 5, + 5 + ), + 4 + ); + public static final BCLFeature GLOBULAGUS = registerVegetation( + "globulagus", + new SinglePlantFeatureConfig(EndBlocks.GLOBULAGUS, 5, 3), + 6 + ); + public static final BCLFeature CLAWFERN = registerVegetation( + "clawfern", + new SinglePlantFeatureConfig(EndBlocks.CLAWFERN, 5, 4), + 5 + ); + public static final BCLFeature BOLUX_MUSHROOM = registerVegetation( + "bolux_mushroom", + new SinglePlantFeatureConfig( + EndBlocks.BOLUX_MUSHROOM, + 5, + 5 + ), + 2 + ); + public static final BCLFeature CHORUS_MUSHROOM = registerVegetation( + "chorus_mushroom", + new SinglePlantFeatureConfig( + EndBlocks.CHORUS_MUSHROOM, + 3, + 5 + ), + 1 + ); + public static final BCLFeature AMBER_ROOT = registerVegetation( + "amber_root", + new SinglePlantFeatureConfig(EndBlocks.AMBER_ROOT, 5, 5), + 1 + ); + //public static final BCLFeature PEARLBERRY = redisterVegetation("pearlberry", new SinglePlantFeatureConfig(EndBlocks.PEARLBERRY, 5, 5), 1); + public static final BCLFeature INFLEXIA = registerVegetation( + "inflexia", + new SinglePlantFeatureConfig( + EndBlocks.INFLEXIA, + 7, + false, + 3 + ), + 16 + ); + public static final BCLFeature FLAMMALIX = registerVegetation( + "flammalix", + new SinglePlantFeatureConfig( + EndBlocks.FLAMMALIX, + 3, + false, + 7 + ), + 5 + ); + + // Vines // + public static final BCLFeature DENSE_VINE = registerVegetation( + "dense_vine", + VINE_FEATURE, new VineFeatureConfig(EndBlocks.DENSE_VINE, 24), + 3 + ); + public static final BCLFeature TWISTED_VINE = registerVegetation( + "twisted_vine", + VINE_FEATURE, new VineFeatureConfig(EndBlocks.TWISTED_VINE, 24), + 1 + ); + public static final BCLFeature BULB_VINE = registerVegetation( + "bulb_vine", + VINE_FEATURE, new VineFeatureConfig(EndBlocks.BULB_VINE, 24), + 5 + ); + public static final BCLFeature JUNGLE_VINE = registerVegetation( + "jungle_vine", + VINE_FEATURE, new VineFeatureConfig(EndBlocks.JUNGLE_VINE, 24), + 5 + ); + + // Ceil plants + public static final BCLFeature SMALL_JELLYSHROOM_CEIL = registerVegetation( + "small_jellyshroom_ceil", + SINGLE_INVERTED_SCATTER_FEATURE, new SinglePlantFeatureConfig( + EndBlocks.SMALL_JELLYSHROOM, + 8 + ), + 8 + ); + + // Wall Plants // + public static final BCLFeature PURPLE_POLYPORE = registerVegetation( + "purple_polypore", + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( + EndBlocks.PURPLE_POLYPORE, + 3 + ), + 5 + ); + public static final BCLFeature AURANT_POLYPORE = registerVegetation( + "aurant_polypore", + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( + EndBlocks.AURANT_POLYPORE, + 3 + ), + 5 + ); + public static final BCLFeature TAIL_MOSS = registerVegetation( + "tail_moss", + WALL_PLANT_FEATURE, new WallPlantFeatureConfig(EndBlocks.TAIL_MOSS, 3), + 15 + ); + public static final BCLFeature CYAN_MOSS = registerVegetation( + "cyan_moss", + WALL_PLANT_FEATURE, new WallPlantFeatureConfig(EndBlocks.CYAN_MOSS, 3), + 15 + ); + public static final BCLFeature TAIL_MOSS_WOOD = registerVegetation( + "tail_moss_wood", + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( + EndBlocks.TAIL_MOSS, + 4 + ), + 25 + ); + public static final BCLFeature CYAN_MOSS_WOOD = registerVegetation( + "cyan_moss_wood", + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( + EndBlocks.CYAN_MOSS, + 4 + ), + 25 + ); + public static final BCLFeature TWISTED_MOSS = registerVegetation( + "twisted_moss", + WALL_PLANT_FEATURE, new WallPlantFeatureConfig(EndBlocks.TWISTED_MOSS, 6), + 15 + ); + public static final BCLFeature TWISTED_MOSS_WOOD = registerVegetation( + "twisted_moss_wood", + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( + EndBlocks.TWISTED_MOSS, + 6 + ), + 25 + ); + public static final BCLFeature BULB_MOSS = registerVegetation( + "bulb_moss", + WALL_PLANT_FEATURE, new WallPlantFeatureConfig(EndBlocks.BULB_MOSS, 6), + 1 + ); + public static final BCLFeature BULB_MOSS_WOOD = registerVegetation( + "bulb_moss_wood", + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( + EndBlocks.BULB_MOSS, + 6 + ), + 15 + ); + public static final BCLFeature SMALL_JELLYSHROOM_WALL = registerVegetation( + "small_jellyshroom_wall", + WALL_PLANT_FEATURE, new WallPlantFeatureConfig( + EndBlocks.SMALL_JELLYSHROOM, + 4 + ), + 4 + ); + public static final BCLFeature SMALL_JELLYSHROOM_WOOD = registerVegetation( + "small_jellyshroom_wood", + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( + EndBlocks.SMALL_JELLYSHROOM, + 4 + ), + 8 + ); + public static final BCLFeature JUNGLE_FERN_WOOD = registerVegetation( + "jungle_fern_wood", + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( + EndBlocks.JUNGLE_FERN, + 3 + ), + 12 + ); + public static final BCLFeature RUSCUS = registerVegetation( + "ruscus", + WALL_PLANT_FEATURE, + new WallPlantFeatureConfig(EndBlocks.RUSCUS, 6), + 10 + ); + public static final BCLFeature RUSCUS_WOOD = registerVegetation( + "ruscus_wood", + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig(EndBlocks.RUSCUS, 6), + 10 + ); + + // Sky plants + public static final BCLFeature FILALUX = registerVegetation( + "filalux", + FILALUX_FEATURE, + ScatterFeatureConfig.filalux(), + 1 + ); + + // Water // + public static final BCLFeature BUBBLE_CORAL = registerVegetation( + "bubble_coral", + UNDERWATER_PLANT_FEATURE, new SinglePlantFeatureConfig( + EndBlocks.BUBBLE_CORAL, + 6 + ), + 10 + ); + public static final BCLFeature BUBBLE_CORAL_RARE = registerVegetation( + "bubble_coral_rare", + UNDERWATER_PLANT_FEATURE, new SinglePlantFeatureConfig( + EndBlocks.BUBBLE_CORAL, + 3 + ), + 4 + ); + public static final BCLFeature END_LILY = registerVegetation( + "end_lily", + END_LILY_FEATURE, + new ScatterFeatureConfig(6), + 10 + ); + public static final BCLFeature END_LILY_RARE = registerVegetation( + "end_lily_rare", + END_LILY_FEATURE, + new ScatterFeatureConfig(3), + 4 + ); + public static final BCLFeature END_LOTUS = registerVegetation( + "end_lotus", + END_LOTUS_FEATURE, + new ScatterFeatureConfig(7), + 5 + ); + public static final BCLFeature END_LOTUS_LEAF = registerVegetation( + "end_lotus_leaf", + END_LOTUS_FEATURE, new ScatterFeatureConfig(20), + 25 + ); + public static final BCLFeature HYDRALUX = registerVegetation( + "hydralux", + HYDRALUX_FEATURE, + new ScatterFeatureConfig(5), + 5 + ); + public static final BCLFeature POND_ANEMONE = registerVegetation( + "pond_anemone", + UNDERWATER_PLANT_FEATURE, new SinglePlantFeatureConfig( + EndBlocks.POND_ANEMONE, + 6 + ), + 10 + ); + + public static final BCLFeature CHARNIA_RED = registerVegetation( + "charnia_red", + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_RED), + 10 + ); + public static final BCLFeature CHARNIA_PURPLE = registerVegetation( + "charnia_purple", + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_PURPLE), + 10 + ); + public static final BCLFeature CHARNIA_CYAN = registerVegetation( + "charnia_cyan", + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_CYAN), + 10 + ); + public static final BCLFeature CHARNIA_LIGHT_BLUE = registerVegetation( + "charnia_light_blue", + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_LIGHT_BLUE), + 10 + ); + public static final BCLFeature CHARNIA_ORANGE = registerVegetation( + "charnia_orange", + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_ORANGE), + 10 + ); + public static final BCLFeature CHARNIA_GREEN = registerVegetation( + "charnia_green", + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_GREEN), + 10 + ); + public static final BCLFeature MENGER_SPONGE = registerVegetation( + "menger_sponge", + MENGER_SPONGE_FEATURE, + new ScatterFeatureConfig(5), + 1 + ); + public static final BCLFeature CHARNIA_RED_RARE = registerVegetation( + "charnia_red_rare", + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_RED), + 2 + ); + public static final BCLFeature BIOME_ISLAND = BCLFeatureBuilder + .start( + BetterEnd.makeID("overworld_island"), + inlineBuild("overworld_island", new BiomeIslandFeature()) + ) + .buildAndRegister() + .place() + .decoration(Decoration.RAW_GENERATION) + .buildAndRegister(); + public static final BCLFeature FLAMAEA = registerVegetation( + "flamaea", + new SinglePlantFeatureConfig(EndBlocks.FLAMAEA, 12, false, 5), + 20 + ); + + public static final EndLakeFeature END_LAKE_FEATURE = inlineBuild("end_lake", new EndLakeFeature()); + // Terrain // + public static final BCLFeature END_LAKE = registerLake( + "end_lake", + END_LAKE_FEATURE, + 4 + ); + public static final BCLFeature END_LAKE_NORMAL = registerLake( + "end_lake_normal", + END_LAKE_FEATURE, + 20 + ); + public static final BCLFeature END_LAKE_RARE = registerLake( + "end_lake_rare", + END_LAKE_FEATURE, + 40 + ); + public static final BCLFeature DESERT_LAKE = registerLake( + "desert_lake", + inlineBuild("desert_lake", new DesertLakeFeature()), + 8 + ); + public static final BCLFeature ROUND_CAVE = registerRawGen( + "round_cave", + inlineBuild("round_cave", new RoundCaveFeature()), + 2 + ); + public static final BCLFeature SPIRE = registerRawGen( + "spire", + inlineBuild("spire", new SpireFeature()), + 4 + ); + public static final BCLFeature FLOATING_SPIRE = registerRawGen( + "floating_spire", + inlineBuild("floating_spire", new FloatingSpireFeature()), + 8 + ); + public static final BCLFeature GEYSER = registerRawGen( + "geyser", + inlineBuild("geyser", new GeyserFeature()), + 8 + ); + public static final BCLFeature SULPHURIC_LAKE = registerLake( + "sulphuric_lake", + inlineBuild("sulphuric_lake", new SulphuricLakeFeature()), + 8 + ); + public static final BCLFeature SULPHURIC_CAVE = BCLFeatureBuilder + .start( + BetterEnd.makeID("sulphuric_cave"), + inlineBuild("sulphuric_cave", new SulphuricCaveFeature()) + ) + .buildAndRegister() + .place() + .decoration(Decoration.RAW_GENERATION) + .count(2) + .squarePlacement() + .onlyInBiome() + .buildAndRegister(); + + public static final IceStarFeature ICE_STAR_FEATURE = inlineBuild("ice_star", new IceStarFeature()); + public static final BCLFeature ICE_STAR = registerRawGen( + "ice_star", + ICE_STAR_FEATURE, + new IceStarFeatureConfig(5, 15, 10, 25), + 15 + ); + public static final BCLFeature ICE_STAR_SMALL = registerRawGen( + "ice_star_small", + ICE_STAR_FEATURE, + new IceStarFeatureConfig(3, 5, 7, 12), + 8 + ); + public static final BCLFeature SURFACE_VENT = registerChanced( + "surface_vent", + inlineBuild("surface_vent", new SurfaceVentFeature()), + 4 + ); + public static final BCLFeature SULPHUR_HILL = registerChanced( + "sulphur_hill", + inlineBuild("sulphur_hill", new SulphurHillFeature()), + 8 + ); + public static final BCLFeature OBSIDIAN_PILLAR_BASEMENT = registerChanced( + "obsidian_pillar_basement", + inlineBuild("obsidian_pillar_basement", new ObsidianPillarBasementFeature()), + 8 + ); + public static final BCLFeature OBSIDIAN_BOULDER = registerChanced( + "obsidian_boulder", + inlineBuild("obsidian_boulder", new ObsidianBoulderFeature()), + 10 + ); + public static final BCLFeature FALLEN_PILLAR = registerChanced( + "fallen_pillar", + inlineBuild("fallen_pillar", new FallenPillarFeature()), + 20 + ); + public static final BCLFeature TUNEL_CAVE = BCLFeatureBuilder + .start( + BetterEnd.makeID("tunel_cave"), + inlineBuild("tunel_cave", new TunelCaveFeature()) + ).buildAndRegister() + .place() + .decoration(Decoration.RAW_GENERATION) + .count(1) + .onlyInBiome() + .buildAndRegister(); + public static final BCLFeature UMBRALITH_ARCH = registerChanced( + "umbralith_arch", + ARCH_FEATURE, new ArchFeatureConfig( + EndBlocks.UMBRALITH.stone, + ArchFeatureConfig.SurfaceFunction.UMBRA_VALLEY + ), + 10 + ); + public static final BCLFeature THIN_UMBRALITH_ARCH = registerChanced( + "thin_umbralith_arch", + THIN_ARCH_FEATURE, + new ThinArchFeatureConfig(EndBlocks.UMBRALITH.stone), + 15 + ); + + // Ores // + public static final BCLFeature THALLASIUM_ORE = registerOre( + "thallasium_ore", + EndBlocks.THALLASIUM.ore, + 24, + 8 + ); + public static final BCLFeature ENDER_ORE = registerOre( + "ender_ore", + EndBlocks.ENDER_ORE, + 12, + 4 + ); + public static final BCLFeature AMBER_ORE = registerOre( + "amber_ore", + EndBlocks.AMBER_ORE, + 60, + 6 + ); + public static final BCLFeature DRAGON_BONE_BLOCK_ORE = registerOre( + "dragon_bone_ore", + EndBlocks.DRAGON_BONE_BLOCK, + 24, + 8 + ); + public static final BCLFeature VIOLECITE_LAYER = registerLayer( + "violecite_layer", + EndBlocks.VIOLECITE, + 15, + 16, + 128, + 8 + ); + + public static final BCLFeature FLAVOLITE_LAYER = registerLayer( + "flavolite_layer", + EndBlocks.FLAVOLITE, + 12, + 16, + 128, + 6 + ); + + // Buildings + public static final BCLFeature CRASHED_SHIP = registerChanced( + "crashed_ship", + inlineBuild("crashed_ship", new CrashedShipFeature()), + new NBTFeatureConfig(EndBiome.Config.DEFAULT_MATERIAL.getTopMaterial()), + 500 + ); + + // Mobs + public static final BCLFeature SILK_MOTH_NEST = registerChanced( + "silk_moth_nest", + inlineBuild("silk_moth_nest", new SilkMothNestFeature()), + 2 + ); + + // Caves + public static final BCLConfigureFeature SMARAGDANT_CRYSTAL = BCLFeatureBuilder + .start( + BetterEnd.makeID("smaragdant_crystal"), + inlineBuild("smaragdant_crystal", new SmaragdantCrystalFeature()) + ) + .buildAndRegister(); + public static final BCLConfigureFeature SMARAGDANT_CRYSTAL_SHARD = BCLFeatureBuilder + .start(BetterEnd.makeID("smaragdant_crystal_shard"), SINGLE_BLOCK_FEATURE) + .configuration(new SimpleBlockConfiguration(SimpleStateProvider.simple(EndBlocks.SMARAGDANT_CRYSTAL_SHARD))) + .buildAndRegister(); + + public static final BCLConfigureFeature BIG_AURORA_CRYSTAL = BCLFeatureBuilder + .start( + BetterEnd.makeID("big_aurora_crystal"), + inlineBuild("big_aurora_crystal", new BigAuroraCrystalFeature()) + ) + .buildAndRegister(); + public static final BCLConfigureFeature CAVE_BUSH = BCLFeatureBuilder + .start(BetterEnd.makeID("cave_bush"), BUSH_FEATURE) + .configuration(new BushFeatureConfig(EndBlocks.CAVE_BUSH, EndBlocks.CAVE_BUSH)) + .buildAndRegister(); + public static final BCLConfigureFeature CAVE_GRASS = BCLFeatureBuilder + .start(BetterEnd.makeID("cave_grass"), SINGLE_BLOCK_FEATURE) + .configuration(new SimpleBlockConfiguration(SimpleStateProvider.simple(EndBlocks.CAVE_GRASS))) + .buildAndRegister(); + public static final BCLConfigureFeature RUBINEA = BCLFeatureBuilder + .start(BetterEnd.makeID("rubinea"), VINE_FEATURE) + .configuration(new VineFeatureConfig(EndBlocks.RUBINEA, 8)) + .buildAndRegister(); + + public static final BCLConfigureFeature MAGNULA = BCLFeatureBuilder + .start(BetterEnd.makeID("magnula"), VINE_FEATURE) + .configuration(new VineFeatureConfig(EndBlocks.MAGNULA, 8)) + .buildAndRegister(); + + public static final BCLConfigureFeature END_STONE_STALACTITE = BCLFeatureBuilder + .start(BetterEnd.makeID("end_stone_stalactite"), STALACTITE_FEATURE) + .configuration(new StalactiteFeatureConfig(true, EndBlocks.END_STONE_STALACTITE, Blocks.END_STONE)) + .buildAndRegister(); + + + public static final BCLConfigureFeature END_STONE_STALAGMITE = BCLFeatureBuilder + .start(BetterEnd.makeID("end_stone_stalagmite"), STALACTITE_FEATURE) + .configuration(new StalactiteFeatureConfig(false, EndBlocks.END_STONE_STALACTITE, Blocks.END_STONE)) + .buildAndRegister(); + public static final BCLConfigureFeature END_STONE_STALACTITE_CAVEMOSS = BCLFeatureBuilder + .start(BetterEnd.makeID("end_stone_stalactite_cavemoss"), STALACTITE_FEATURE) + .configuration(new StalactiteFeatureConfig( + true, + EndBlocks.END_STONE_STALACTITE_CAVEMOSS, + Blocks.END_STONE, + EndBlocks.CAVE_MOSS + )) + .buildAndRegister(); + public static final BCLConfigureFeature END_STONE_STALAGMITE_CAVEMOSS = BCLFeatureBuilder + .start(BetterEnd.makeID("end_stone_stalagmite_cavemoss"), STALACTITE_FEATURE) + .configuration(new StalactiteFeatureConfig( + false, + EndBlocks.END_STONE_STALACTITE_CAVEMOSS, + EndBlocks.CAVE_MOSS + )) + .buildAndRegister(); + public static final BCLConfigureFeature CAVE_PUMPKIN = BCLFeatureBuilder + .start( + BetterEnd.makeID("cave_pumpkin"), + inlineBuild("cave_pumpkin", new CavePumpkinFeature()) + ) + .buildAndRegister(); + + + public static , FC extends FeatureConfiguration> F inlineBuild(String name, F feature) { + ResourceLocation l = BetterEnd.makeID(name); + if (Registry.FEATURE.containsKey(l)) { + return (F) Registry.FEATURE.get(l); + } + return BCLFeature.register(l, feature); + } + + private static BCLFeature registerVegetation( + String name, + DoublePlantFeatureConfig config, + int density + ) { + return registerVegetation(name, DOUBLE_PLANT_FEATURE, config, density); + } + + private static BCLFeature registerVegetation( + String name, + SinglePlantFeatureConfig config, + int density + ) { + return registerVegetation(name, SINGLE_PLANT_FEATURE, config, density); + } + + private static > BCLFeature registerVegetation( + String name, + F feature, + int density + ) { + return registerVegetation(name, feature, NoneFeatureConfiguration.NONE, density); + } + + private static , FC extends FeatureConfiguration> BCLFeature registerVegetation( + String name, + F feature, + FC config, + int density + ) { + ResourceLocation id = BetterEnd.makeID(name); + return BCLFeatureBuilder.start(id, feature) + .configuration(config) + .buildAndRegister() + .place() + .onEveryLayerMax(density) + .onlyInBiome() + .buildAndRegister(); + } + + private static > BCLFeature registerRawGen( + String name, + F feature, + int chance + ) { + return registerRawGen(name, feature, FeatureConfiguration.NONE, chance); + } + + private static , FC extends FeatureConfiguration> BCLFeature registerRawGen( + String name, + F feature, + FC config, + int chance + ) { + return BCLFeatureBuilder + .start(BetterEnd.makeID(name), feature) + .configuration(config) + .buildAndRegister() + .place() + .decoration(Decoration.RAW_GENERATION) + .onceEvery(chance) + .squarePlacement() + .onlyInBiome() + .buildAndRegister(); + } + + private static > BCLFeature registerLake( + String name, + F feature, + int chance + ) { + return BCLFeatureBuilder + .start(BetterEnd.makeID(name), feature) + .buildAndRegister() + .place() + .decoration(Decoration.LAKES) + .onceEvery(chance) + .squarePlacement() + .onlyInBiome() + .buildAndRegister(); + } + + private static > BCLFeature registerChanced( + String name, + F feature, + int chance + ) { + return registerChanced(name, feature, FeatureConfiguration.NONE, chance); + } + + private static , FC extends FeatureConfiguration> BCLFeature registerChanced( + String name, + F feature, + FC config, + int chance + ) { + return + BCLFeatureBuilder + .start(BetterEnd.makeID(name), feature) + .configuration(config) + .buildAndRegister() + .place() + .decoration(Decoration.SURFACE_STRUCTURES) + .onceEvery(chance) + .squarePlacement() + .onlyInBiome() + .buildAndRegister(); + } + + private static BCLFeature registerOre( + String name, + Block blockOre, + int veins, + int veinSize + ) { + return BCLFeatureBuilder + .startOre(BetterEnd.makeID(name)) + .add(Blocks.END_STONE, blockOre) + .veinSize(veinSize) + .discardChanceOnAirExposure(0) + .buildAndRegister() + .place() + .decoration(Decoration.UNDERGROUND_ORES) + .count(veins) + .randomHeight8FromFloorCeil() + .squarePlacement() + .onlyInBiome() + .buildAndRegister(); + } + + private static BCLFeature registerLayer( + String name, + Block block, + float radius, + int minY, + int maxY, + int count + ) { + OreLayerFeature layer = inlineBuild("ore_layer", new OreLayerFeature()); + return BCLFeatureBuilder + .start(BetterEnd.makeID(name), layer) + .configuration(new OreLayerFeatureConfig(block.defaultBlockState(), radius, minY, maxY)) + .buildAndRegister() + .place() + .decoration(GenerationStep.Decoration.UNDERGROUND_ORES) + .count(count) + .buildAndRegister(); + } + + private static BCLFeature registerLayer( + String name, + StoneMaterial material, + float radius, + int minY, + int maxY, + int count + ) { + return registerLayer(name, material.stone, radius, minY, maxY, count); + } + + public static void addBiomeFeatures(ResourceLocation id, Holder biome) { + if (!BetterEnd.MOD_ID.equals(id.getNamespace())) { + BiomeAPI.addBiomeFeature(biome, FLAVOLITE_LAYER); + BiomeAPI.addBiomeFeature(biome, THALLASIUM_ORE); + BiomeAPI.addBiomeFeature(biome, ENDER_ORE); + BiomeAPI.addBiomeFeature(biome, CRASHED_SHIP); + + BCLBiome bclbiome = BiomeAPI.getBiome(id); + BCLFeature feature = getBiomeStructures(bclbiome); + if (feature != null) { + BiomeAPI.addBiomeFeature(biome, feature); + } + + + boolean hasCaves = !(bclbiome instanceof EndCaveBiome); + if (!(bclbiome instanceof EndCaveBiome) && bclbiome instanceof EndBiome endBiome) { + hasCaves = endBiome.hasCaves(); + } + + if (hasCaves && !BiomeAPI.wasRegisteredAsEndVoidBiome(id) /*!BiomeAPI.END_VOID_BIOME_PICKER.containsImmutable(id)*/) { + if (Configs.BIOME_CONFIG.getBoolean(id, "hasCaves", true)) { + BiomeAPI.addBiomeFeature(biome, ROUND_CAVE); + BiomeAPI.addBiomeFeature(biome, TUNEL_CAVE); + } + } + } + } + + private static BCLFeature getBiomeStructures(BCLBiome biome) { + return getBiomeStructures(biome.getID()); + } + + private static BCLFeature getBiomeStructures(ResourceLocation loc) { + String ns = loc.getNamespace(); + String nm = loc.getPath(); + return getBiomeStructures(ns, nm); + } + + private static BCLFeature getBiomeStructures(String ns, String nm) { + ResourceLocation id = new ResourceLocation(ns, nm + "_structures"); + + if (BuiltinRegistries.PLACED_FEATURE.containsKey(id)) { + BCLib.LOGGER.info("Feature for " + id + " was already build"); + } + + String path = "/data/" + ns + "/structures/biome/" + nm + "/"; + InputStream inputstream = EndFeatures.class.getResourceAsStream(path + "structures.json"); + if (inputstream != null) { + JsonObject obj = JsonFactory.getJsonObject(inputstream); + JsonArray structures = obj.getAsJsonArray("structures"); + if (structures != null) { + List list = Lists.newArrayList(); + structures.forEach((entry) -> { + JsonObject e = entry.getAsJsonObject(); + String structure = path + e.get("nbt").getAsString() + ".nbt"; + NBTFeature.TerrainMerge terrainMerge = NBTFeature.TerrainMerge.getFromString(e + .get("terrainMerge") + .getAsString()); + int offsetY = e.get("offsetY").getAsInt(); + list.add(new BuildingListFeature.StructureInfo(structure, offsetY, terrainMerge)); + }); + if (!list.isEmpty()) { + return BCLFeatureBuilder.start( + new ResourceLocation(ns, nm + "_structures"), + BUILDING_LIST_FEATURE + ) + .configuration(new BuildingListFeatureConfig( + list, + Blocks.END_STONE.defaultBlockState() + )) + .buildAndRegister() + .place() + .decoration(Decoration.SURFACE_STRUCTURES) + .onceEvery(10) + .squarePlacement() + .onlyInBiome() + .buildAndRegister(); + } + } + } + return null; + } + + public static BCLBiomeBuilder addDefaultFeatures( + ResourceLocation biomeID, + BCLBiomeBuilder builder, + boolean hasCaves + ) { + builder.feature(FLAVOLITE_LAYER); + builder.feature(THALLASIUM_ORE); + builder.feature(ENDER_ORE); + builder.feature(CRASHED_SHIP); + + BCLFeature feature = getBiomeStructures(biomeID); + if (feature != null) { + builder.feature(feature); + } + + if (hasCaves) { + builder.feature(ROUND_CAVE); + builder.feature(TUNEL_CAVE); + } + + return builder; + } + + public static void register() { + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndItems.java b/src/main/java/org/betterx/betterend/registry/EndItems.java new file mode 100644 index 00000000..43dac813 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndItems.java @@ -0,0 +1,362 @@ +package org.betterx.betterend.registry; + +import org.betterx.bclib.items.BaseArmorItem; +import org.betterx.bclib.items.ModelProviderItem; +import org.betterx.bclib.items.tool.BaseAxeItem; +import org.betterx.bclib.items.tool.BaseHoeItem; +import org.betterx.bclib.items.tool.BaseShovelItem; +import org.betterx.bclib.items.tool.BaseSwordItem; +import org.betterx.bclib.registry.BaseRegistry; +import org.betterx.bclib.registry.ItemRegistry; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.config.Configs; +import org.betterx.betterend.item.*; +import org.betterx.betterend.item.material.EndArmorMaterial; +import org.betterx.betterend.item.material.EndToolMaterial; +import org.betterx.betterend.item.tool.EndHammerItem; +import org.betterx.betterend.item.tool.EndPickaxe; +import org.betterx.betterend.tab.CreativeTabs; + +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.food.Foods; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.TieredItem; +import net.minecraft.world.item.Tiers; + +import net.fabricmc.fabric.api.item.v1.FabricItemSettings; + +import java.util.List; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +public class EndItems { + private static final ItemRegistry REGISTRY = new ItemRegistry(CreativeTabs.TAB_ITEMS, Configs.ITEM_CONFIG); + + // Materials // + public final static Item ENDER_DUST = registerEndItem("ender_dust"); + public final static Item ENDER_SHARD = registerEndItem("ender_shard"); + public final static Item AETERNIUM_INGOT = registerEndItem( + "aeternium_ingot", + new ModelProviderItem(makeEndItemSettings().fireResistant()) + ); + public final static Item AETERNIUM_FORGED_PLATE = registerEndItem( + "aeternium_forged_plate", + new ModelProviderItem(makeEndItemSettings().fireResistant()) + ); + public final static Item END_LILY_LEAF = registerEndItem("end_lily_leaf"); + public final static Item END_LILY_LEAF_DRIED = registerEndItem("end_lily_leaf_dried"); + public final static Item CRYSTAL_SHARDS = registerEndItem("crystal_shards"); + public final static Item RAW_AMBER = registerEndItem("raw_amber"); + public final static Item AMBER_GEM = registerEndItem("amber_gem"); + public final static Item GLOWING_BULB = registerEndItem("glowing_bulb"); + public final static Item CRYSTALLINE_SULPHUR = registerEndItem("crystalline_sulphur"); + public final static Item HYDRALUX_PETAL = registerEndItem("hydralux_petal"); + public final static Item GELATINE = registerEndItem("gelatine"); + public static final Item ETERNAL_CRYSTAL = registerEndItem("eternal_crystal", new EternalCrystalItem()); + public final static Item ENCHANTED_PETAL = registerEndItem("enchanted_petal", new EnchantedItem(HYDRALUX_PETAL)); + public final static Item LEATHER_STRIPE = registerEndItem("leather_stripe"); + public final static Item LEATHER_WRAPPED_STICK = registerEndItem("leather_wrapped_stick"); + public final static Item SILK_FIBER = registerEndItem("silk_fiber"); + public final static Item LUMECORN_ROD = registerEndItem("lumecorn_rod"); + public final static Item SILK_MOTH_MATRIX = registerEndItem("silk_moth_matrix"); + public final static Item ENCHANTED_MEMBRANE = registerEndItem( + "enchanted_membrane", + new EnchantedItem(Items.PHANTOM_MEMBRANE) + ); + + // Music Discs + public final static Item MUSIC_DISC_STRANGE_AND_ALIEN = registerEndDisc( + "music_disc_strange_and_alien", + 0, + EndSounds.RECORD_STRANGE_AND_ALIEN, + (4 * 60) + 26 + ); + public final static Item MUSIC_DISC_GRASPING_AT_STARS = registerEndDisc( + "music_disc_grasping_at_stars", + 0, + EndSounds.RECORD_GRASPING_AT_STARS, + (8 * 60) + 48 + ); + public final static Item MUSIC_DISC_ENDSEEKER = registerEndDisc( + "music_disc_endseeker", + 0, + EndSounds.RECORD_ENDSEEKER, + (7 * 60) + 41 + ); + public final static Item MUSIC_DISC_EO_DRACONA = registerEndDisc( + "music_disc_eo_dracona", + 0, + EndSounds.RECORD_EO_DRACONA, + (5 * 60) + 53 + ); + + // Armor // + public static final Item AETERNIUM_HELMET = registerEndItem( + "aeternium_helmet", + new BaseArmorItem( + EndArmorMaterial.AETERNIUM, + EquipmentSlot.HEAD, + makeEndItemSettings().fireResistant() + ) + ); + public static final Item AETERNIUM_CHESTPLATE = registerEndItem( + "aeternium_chestplate", + new BaseArmorItem( + EndArmorMaterial.AETERNIUM, + EquipmentSlot.CHEST, + makeEndItemSettings().fireResistant() + ) + ); + public static final Item AETERNIUM_LEGGINGS = registerEndItem( + "aeternium_leggings", + new BaseArmorItem( + EndArmorMaterial.AETERNIUM, + EquipmentSlot.LEGS, + makeEndItemSettings().fireResistant() + ) + ); + public static final Item AETERNIUM_BOOTS = registerEndItem( + "aeternium_boots", + new BaseArmorItem( + EndArmorMaterial.AETERNIUM, + EquipmentSlot.FEET, + makeEndItemSettings().fireResistant() + ) + ); + public static final Item CRYSTALITE_HELMET = registerEndItem("crystalite_helmet", new CrystaliteHelmet()); + public static final Item CRYSTALITE_CHESTPLATE = registerEndItem( + "crystalite_chestplate", + new CrystaliteChestplate() + ); + public static final Item CRYSTALITE_LEGGINGS = registerEndItem("crystalite_leggings", new CrystaliteLeggings()); + public static final Item CRYSTALITE_BOOTS = registerEndItem("crystalite_boots", new CrystaliteBoots()); + public static final Item ARMORED_ELYTRA = registerEndItem( + "elytra_armored", + new ArmoredElytra( + "elytra_armored", + EndArmorMaterial.AETERNIUM, + Items.PHANTOM_MEMBRANE, + 900, + 0.97D, + true + ) + ); + public static final Item CRYSTALITE_ELYTRA = registerEndItem("elytra_crystalite", new CrystaliteElytra(650, 1.0D)); + + // Tools // + public static final TieredItem AETERNIUM_SHOVEL = registerEndTool("aeternium_shovel", new BaseShovelItem( + EndToolMaterial.AETERNIUM, 1.5F, -3.0F, makeEndItemSettings().fireResistant())); + public static final TieredItem AETERNIUM_SWORD = registerEndTool( + "aeternium_sword", + new BaseSwordItem( + EndToolMaterial.AETERNIUM, + 3, + -2.4F, + makeEndItemSettings().fireResistant() + ) + ); + public static final TieredItem AETERNIUM_PICKAXE = registerEndTool( + "aeternium_pickaxe", + new EndPickaxe( + EndToolMaterial.AETERNIUM, + 1, + -2.8F, + makeEndItemSettings().fireResistant() + ) + ); + public static final TieredItem AETERNIUM_AXE = registerEndTool( + "aeternium_axe", + new BaseAxeItem( + EndToolMaterial.AETERNIUM, + 5.0F, + -3.0F, + makeEndItemSettings().fireResistant() + ) + ); + public static final TieredItem AETERNIUM_HOE = registerEndTool( + "aeternium_hoe", + new BaseHoeItem( + EndToolMaterial.AETERNIUM, + -3, + 0.0F, + makeEndItemSettings().fireResistant() + ) + ); + public static final TieredItem AETERNIUM_HAMMER = registerEndTool( + "aeternium_hammer", + new EndHammerItem( + EndToolMaterial.AETERNIUM, + 6.0F, + -3.0F, + 0.3D, + makeEndItemSettings().fireResistant() + ) + ); + + // Toolparts // + public final static Item AETERNIUM_SHOVEL_HEAD = registerEndItem( + "aeternium_shovel_head", + new ModelProviderItem(makeEndItemSettings().fireResistant()) + ); + public final static Item AETERNIUM_PICKAXE_HEAD = registerEndItem( + "aeternium_pickaxe_head", + new ModelProviderItem(makeEndItemSettings().fireResistant()) + ); + public final static Item AETERNIUM_AXE_HEAD = registerEndItem( + "aeternium_axe_head", + new ModelProviderItem(makeEndItemSettings().fireResistant()) + ); + public final static Item AETERNIUM_HOE_HEAD = registerEndItem( + "aeternium_hoe_head", + new ModelProviderItem(makeEndItemSettings().fireResistant()) + ); + public final static Item AETERNIUM_HAMMER_HEAD = registerEndItem( + "aeternium_hammer_head", + new ModelProviderItem(makeEndItemSettings().fireResistant()) + ); + public final static Item AETERNIUM_SWORD_BLADE = registerEndItem( + "aeternium_sword_blade", + new ModelProviderItem(makeEndItemSettings().fireResistant()) + ); + public final static Item AETERNIUM_SWORD_HANDLE = registerEndItem( + "aeternium_sword_handle", + new ModelProviderItem(makeEndItemSettings().fireResistant()) + ); + + // ITEM_HAMMERS // + public static final TieredItem IRON_HAMMER = registerEndTool( + "iron_hammer", + new EndHammerItem( + Tiers.IRON, + 5.0F, + -3.2F, + 0.2D, + makeEndItemSettings() + ) + ); + public static final TieredItem GOLDEN_HAMMER = registerEndTool( + "golden_hammer", + new EndHammerItem( + Tiers.GOLD, + 4.5F, + -3.4F, + 0.3D, + makeEndItemSettings() + ) + ); + public static final TieredItem DIAMOND_HAMMER = registerEndTool( + "diamond_hammer", + new EndHammerItem( + Tiers.DIAMOND, + 5.5F, + -3.1F, + 0.2D, + makeEndItemSettings() + ) + ); + public static final TieredItem NETHERITE_HAMMER = registerEndTool( + "netherite_hammer", + new EndHammerItem( + Tiers.NETHERITE, + 5.0F, + -3.0F, + 0.2D, + makeEndItemSettings().fireResistant() + ) + ); + + // Food // + public final static Item SHADOW_BERRY_RAW = registerEndFood("shadow_berry_raw", 4, 0.5F); + public final static Item SHADOW_BERRY_COOKED = registerEndFood("shadow_berry_cooked", 6, 0.7F); + public final static Item END_FISH_RAW = registerEndFood("end_fish_raw", Foods.SALMON); + public final static Item END_FISH_COOKED = registerEndFood("end_fish_cooked", Foods.COOKED_SALMON); + public final static Item BUCKET_END_FISH = registerEndItem( + "bucket_end_fish", + new EndBucketItem(EndEntities.END_FISH) + ); + public final static Item BUCKET_CUBOZOA = registerEndItem("bucket_cubozoa", new EndBucketItem(EndEntities.CUBOZOA)); + public final static Item SWEET_BERRY_JELLY = registerEndFood("sweet_berry_jelly", 8, 0.7F); + public final static Item SHADOW_BERRY_JELLY = registerEndFood( + "shadow_berry_jelly", + 6, + 0.8F, + new MobEffectInstance(MobEffects.NIGHT_VISION, 400) + ); + public final static Item BLOSSOM_BERRY_JELLY = registerEndFood("blossom_berry_jelly", 8, 0.7F); + public final static Item BLOSSOM_BERRY = registerEndFood("blossom_berry", Foods.APPLE); + public final static Item AMBER_ROOT_RAW = registerEndFood("amber_root_raw", 2, 0.8F); + public final static Item CHORUS_MUSHROOM_RAW = registerEndFood("chorus_mushroom_raw", 3, 0.5F); + public final static Item CHORUS_MUSHROOM_COOKED = registerEndFood("chorus_mushroom_cooked", Foods.MUSHROOM_STEW); + public final static Item BOLUX_MUSHROOM_COOKED = registerEndFood("bolux_mushroom_cooked", Foods.MUSHROOM_STEW); + public final static Item CAVE_PUMPKIN_PIE = registerEndFood("cave_pumpkin_pie", Foods.PUMPKIN_PIE); + + // Drinks // + public final static Item UMBRELLA_CLUSTER_JUICE = registerEndDrink("umbrella_cluster_juice", 5, 0.7F); + + public static List getModItems() { + return BaseRegistry.getModItems(BetterEnd.MOD_ID); + } + + @Deprecated(forRemoval = true) + public static Item registerEndDisc(String name, int power, SoundEvent sound) { + return registerEndDisc(name, power, sound, 60); + } + + public static Item registerEndDisc(String name, int power, SoundEvent sound, int lengthInSeconds) { + return getItemRegistry().registerDisc(BetterEnd.makeID(name), power, sound, lengthInSeconds); + } + + public static Item registerEndItem(String name) { + return getItemRegistry().register(BetterEnd.makeID(name)); + } + + public static Item registerEndItem(String name, Item item) { + if (item instanceof EndArmorItem) { + return getItemRegistry().register(BetterEnd.makeID(name), item, "armour"); + } + return getItemRegistry().register(BetterEnd.makeID(name), item); + } + + public static TieredItem registerEndTool(String name, TieredItem item) { + if (!Configs.ITEM_CONFIG.getBoolean("tools", name, true)) { + return item; + } + return (TieredItem) getItemRegistry().registerTool(BetterEnd.makeID(name), item); + } + + public static Item registerEndEgg(String name, EntityType type, int background, int dots) { + return getItemRegistry().registerEgg(BetterEnd.makeID(name), type, background, dots); + } + + public static Item registerEndFood(String name, int hunger, float saturation, MobEffectInstance... effects) { + return getItemRegistry().registerFood(BetterEnd.makeID(name), hunger, saturation, effects); + } + + public static Item registerEndFood(String name, FoodProperties foodComponent) { + return getItemRegistry().registerFood(BetterEnd.makeID(name), foodComponent); + } + + public static Item registerEndDrink(String name, int hunger, float saturation) { + return getItemRegistry().registerDrink(BetterEnd.makeID(name), hunger, saturation); + } + + public static FabricItemSettings makeEndItemSettings() { + return getItemRegistry().makeItemSettings(); + } + + @NotNull + public static ItemRegistry getItemRegistry() { + return REGISTRY; + } + + @ApiStatus.Internal + public static void ensureStaticallyLoaded() { + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndMenuTypes.java b/src/main/java/org/betterx/betterend/registry/EndMenuTypes.java new file mode 100644 index 00000000..d92f6014 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndMenuTypes.java @@ -0,0 +1,31 @@ +package org.betterx.betterend.registry; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.EndStoneSmelter; +import org.betterx.betterend.client.gui.EndStoneSmelterMenu; + +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.MenuType; + +import java.util.function.BiFunction; + +public class EndMenuTypes { + public final static MenuType END_STONE_SMELTER = registerSimple( + BetterEnd.makeID(EndStoneSmelter.ID), + EndStoneSmelterMenu::new + ); + + static MenuType registerSimple( + ResourceLocation id, + BiFunction factory + ) { + MenuType type = new MenuType<>((syncId, inventory) -> factory.apply(syncId, inventory)); + return Registry.register(Registry.MENU, id, type); + } + + public final static void ensureStaticallyLoaded() { + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndModelProviders.java b/src/main/java/org/betterx/betterend/registry/EndModelProviders.java new file mode 100644 index 00000000..ca25a72b --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndModelProviders.java @@ -0,0 +1,19 @@ +package org.betterx.betterend.registry; + +import org.betterx.betterend.item.model.CrystaliteArmorProvider; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import shadow.fabric.api.client.rendering.v1.ArmorRenderingRegistry; + +@Environment(EnvType.CLIENT) +public class EndModelProviders { + + public final static CrystaliteArmorProvider CRYSTALITE_PROVIDER = new CrystaliteArmorProvider(); + + public final static void register() { + ArmorRenderingRegistry.registerModel(CRYSTALITE_PROVIDER, CRYSTALITE_PROVIDER.getRenderedItems()); + ArmorRenderingRegistry.registerTexture(CRYSTALITE_PROVIDER, CRYSTALITE_PROVIDER.getRenderedItems()); + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndParticles.java b/src/main/java/org/betterx/betterend/registry/EndParticles.java new file mode 100644 index 00000000..72388de8 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndParticles.java @@ -0,0 +1,62 @@ +package org.betterx.betterend.registry; + +import org.betterx.bclib.particles.BCLParticleType; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.particle.*; + +import com.mojang.serialization.Codec; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleType; +import net.minecraft.core.particles.SimpleParticleType; + +import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry; + +public class EndParticles { + public static final SimpleParticleType GLOWING_SPHERE = register("glowing_sphere"); + public static final SimpleParticleType PORTAL_SPHERE = register("portal_sphere"); + public static final ParticleType INFUSION = register( + "infusion", + InfusionParticleType.PARAMETERS_FACTORY, + InfusionParticleType.CODEC + ); + public static final SimpleParticleType SULPHUR_PARTICLE = register("sulphur_particle"); + public static final SimpleParticleType GEYSER_PARTICLE = registerFar("geyser_particle"); + public static final SimpleParticleType SNOWFLAKE = register("snowflake"); + public static final SimpleParticleType AMBER_SPHERE = register("amber_sphere"); + public static final SimpleParticleType BLACK_SPORE = register("black_spore"); + public static final SimpleParticleType TENANEA_PETAL = register("tenanea_petal"); + public static final SimpleParticleType JUNGLE_SPORE = register("jungle_spore"); + public static final SimpleParticleType FIREFLY = register("firefly"); + public static final SimpleParticleType SMARAGDANT = register("smaragdant_particle"); + + public static void register() { + ParticleFactoryRegistry.getInstance().register(GLOWING_SPHERE, ParticleGlowingSphere.FactoryGlowingSphere::new); + ParticleFactoryRegistry.getInstance().register(PORTAL_SPHERE, PaticlePortalSphere.FactoryPortalSphere::new); + ParticleFactoryRegistry.getInstance().register(INFUSION, InfusionParticle.InfusionFactory::new); + ParticleFactoryRegistry.getInstance().register(SULPHUR_PARTICLE, ParticleSulphur.FactorySulphur::new); + ParticleFactoryRegistry.getInstance().register(GEYSER_PARTICLE, ParticleGeyser.FactoryGeyser::new); + ParticleFactoryRegistry.getInstance().register(SNOWFLAKE, ParticleSnowflake.FactorySnowflake::new); + ParticleFactoryRegistry.getInstance().register(AMBER_SPHERE, ParticleGlowingSphere.FactoryGlowingSphere::new); + ParticleFactoryRegistry.getInstance().register(BLACK_SPORE, ParticleBlackSpore.FactoryBlackSpore::new); + ParticleFactoryRegistry.getInstance().register(TENANEA_PETAL, ParticleTenaneaPetal.FactoryTenaneaPetal::new); + ParticleFactoryRegistry.getInstance().register(JUNGLE_SPORE, ParticleJungleSpore.FactoryJungleSpore::new); + ParticleFactoryRegistry.getInstance().register(FIREFLY, FireflyParticle.FireflyParticleFactory::new); + ParticleFactoryRegistry.getInstance().register(SMARAGDANT, SmaragdantParticle.SmaragdantParticleFactory::new); + } + + private static SimpleParticleType register(String name) { + return BCLParticleType.register(BetterEnd.makeID(name)); + } + + private static SimpleParticleType registerFar(String name) { + return BCLParticleType.register(BetterEnd.makeID(name), true); + } + + private static ParticleType register( + String name, + ParticleOptions.Deserializer type, + Codec codec + ) { + return BCLParticleType.register(BetterEnd.makeID(name), type, codec); + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndPoiTypes.java b/src/main/java/org/betterx/betterend/registry/EndPoiTypes.java new file mode 100644 index 00000000..630916fd --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndPoiTypes.java @@ -0,0 +1,20 @@ +package org.betterx.betterend.registry; + +import org.betterx.bclib.api.v2.poi.BCLPoiType; +import org.betterx.bclib.api.v2.poi.PoiManager; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.RunedFlavolite; + +import java.util.Set; + +public class EndPoiTypes { + public static final BCLPoiType ETERNAL_PORTAL_INACTIVE = PoiManager.register( + BetterEnd.makeID("eternal_portal_inactive"), + Set.of(EndBlocks.FLAVOLITE_RUNED_ETERNAL.defaultBlockState().setValue(RunedFlavolite.ACTIVATED, false)), + 0, 1 + ); + + public static void register() { + + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndPortals.java b/src/main/java/org/betterx/betterend/registry/EndPortals.java new file mode 100644 index 00000000..55abacf2 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndPortals.java @@ -0,0 +1,163 @@ +package org.betterx.betterend.registry; + +import org.betterx.bclib.util.JsonFactory; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.BetterEnd; +import org.betterx.ui.ColorUtil; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; + +import net.fabricmc.loader.api.FabricLoader; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +import java.io.File; + +public class EndPortals { + + public final static ResourceLocation OVERWORLD_ID = Level.OVERWORLD.location(); + + private static PortalInfo[] portals; + + public static void loadPortals() { + File file = new File(FabricLoader.getInstance().getConfigDir().toString(), "betterend/portals.json"); + JsonObject json; + if (!file.exists()) { + file.getParentFile().mkdirs(); + json = makeDefault(file); + } else { + json = JsonFactory.getJsonObject(file); + } + if (!json.has("portals") || !json.get("portals").isJsonArray()) { + json = makeDefault(file); + } + JsonArray array = json.get("portals").getAsJsonArray(); + if (array.size() == 0) { + json = makeDefault(file); + array = json.get("portals").getAsJsonArray(); + } + portals = new PortalInfo[array.size()]; + for (int i = 0; i < portals.length; i++) { + portals[i] = new PortalInfo(array.get(i).getAsJsonObject()); + } + } + + public static int getCount() { + return MHelper.max(portals.length - 1, 1); + } + + public static ServerLevel getWorld(MinecraftServer server, int portalId) { + if (portalId < 0 || portalId >= portals.length) { + return server.overworld(); + } + return portals[portalId].getWorld(server); + } + + public static ResourceLocation getWorldId(int portalId) { + if (portalId < 0 || portalId >= portals.length) { + return OVERWORLD_ID; + } + return portals[portalId].dimension; + } + + public static int getPortalIdByItem(ResourceLocation item) { + for (int i = 0; i < portals.length; i++) { + if (portals[i].item.equals(item)) { + return i; + } + } + return 0; + } + + public static int getPortalIdByWorld(ResourceLocation world) { + for (int i = 0; i < portals.length; i++) { + if (portals[i].dimension.equals(world)) { + return i; + } + } + return 0; + } + + public static int getColor(int state) { + return portals[state].color; + } + + public static boolean isAvailableItem(ResourceLocation item) { + for (PortalInfo portal : portals) { + if (portal.item.equals(item)) { + return true; + } + } + return false; + } + + private static JsonObject makeDefault(File file) { + JsonObject jsonObject = new JsonObject(); + JsonFactory.storeJson(file, jsonObject); + JsonArray array = new JsonArray(); + jsonObject.add("portals", array); + array.add(makeDefault().toJson()); + JsonFactory.storeJson(file, jsonObject); + return jsonObject; + } + + private static PortalInfo makeDefault() { + return new PortalInfo( + new ResourceLocation("minecraft:overworld"), + BetterEnd.makeID("eternal_crystal"), + 255, + 255, + 255 + ); + } + + private static class PortalInfo { + private final ResourceLocation dimension; + private final ResourceLocation item; + private final int color; + private ServerLevel world; + + PortalInfo(JsonObject obj) { + this( + new ResourceLocation(JsonFactory.getString(obj, "dimension", "minecraft:overworld")), + new ResourceLocation(JsonFactory.getString(obj, "item", "betterend:eternal_crystal")), + JsonFactory.getInt(obj, "colorRed", 255), + JsonFactory.getInt(obj, "colorGreen", 255), + JsonFactory.getInt(obj, "colorBlue", 255) + ); + } + + PortalInfo(ResourceLocation dimension, ResourceLocation item, int r, int g, int b) { + this.dimension = dimension; + this.item = item; + this.color = ColorUtil.color(r, g, b); + } + + ServerLevel getWorld(MinecraftServer server) { + if (world != null) { + return world; + } + for (ServerLevel world : server.getAllLevels()) { + if (world.dimension().location().equals(dimension)) { + this.world = world; + return world; + } + } + return server.overworld(); + } + + JsonObject toJson() { + JsonObject obj = new JsonObject(); + obj.addProperty("dimension", dimension.toString()); + obj.addProperty("item", item.toString()); + obj.addProperty("colorRed", (color >> 16) & 255); + obj.addProperty("colorGreen", (color >> 8) & 255); + obj.addProperty("colorBlue", color & 255); + return obj; + } + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndScreens.java b/src/main/java/org/betterx/betterend/registry/EndScreens.java new file mode 100644 index 00000000..1b282570 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndScreens.java @@ -0,0 +1,11 @@ +package org.betterx.betterend.registry; + +import org.betterx.betterend.client.gui.EndStoneSmelterScreen; + +import net.minecraft.client.gui.screens.MenuScreens; + +public class EndScreens { + public static void register() { + MenuScreens.register(EndMenuTypes.END_STONE_SMELTER, EndStoneSmelterScreen::new); + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndSounds.java b/src/main/java/org/betterx/betterend/registry/EndSounds.java new file mode 100644 index 00000000..3e335c02 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndSounds.java @@ -0,0 +1,49 @@ +package org.betterx.betterend.registry; + +import org.betterx.betterend.BetterEnd; + +import net.minecraft.core.Registry; +import net.minecraft.sounds.SoundEvent; + +public class EndSounds { + // Music + public static final SoundEvent MUSIC_FOREST = register("music", "forest"); + public static final SoundEvent MUSIC_WATER = register("music", "water"); + public static final SoundEvent MUSIC_DARK = register("music", "dark"); + public static final SoundEvent MUSIC_OPENSPACE = register("music", "openspace"); + public static final SoundEvent MUSIC_CAVES = register("music", "caves"); + + // Ambient + public static final SoundEvent AMBIENT_FOGGY_MUSHROOMLAND = register("ambient", "foggy_mushroomland"); + public static final SoundEvent AMBIENT_CHORUS_FOREST = register("ambient", "chorus_forest"); + public static final SoundEvent AMBIENT_MEGALAKE = register("ambient", "megalake"); + public static final SoundEvent AMBIENT_DUST_WASTELANDS = register("ambient", "dust_wastelands"); + public static final SoundEvent AMBIENT_MEGALAKE_GROVE = register("ambient", "megalake_grove"); + public static final SoundEvent AMBIENT_BLOSSOMING_SPIRES = register("ambient", "blossoming_spires"); + public static final SoundEvent AMBIENT_SULPHUR_SPRINGS = register("ambient", "sulphur_springs"); + public static final SoundEvent AMBIENT_UMBRELLA_JUNGLE = register("ambient", "umbrella_jungle"); + public static final SoundEvent AMBIENT_GLOWING_GRASSLANDS = register("ambient", "glowing_grasslands"); + public static final SoundEvent AMBIENT_CAVES = register("ambient", "caves"); + public static final SoundEvent AMBIENT_AMBER_LAND = register("ambient", "amber_land"); + public static final SoundEvent UMBRA_VALLEY = register("ambient", "umbra_valley"); + + // Entity + public static final SoundEvent ENTITY_DRAGONFLY = register("entity", "dragonfly"); + public static final SoundEvent ENTITY_SHADOW_WALKER = register("entity", "shadow_walker"); + public static final SoundEvent ENTITY_SHADOW_WALKER_DAMAGE = register("entity", "shadow_walker_damage"); + public static final SoundEvent ENTITY_SHADOW_WALKER_DEATH = register("entity", "shadow_walker_death"); + + // Records + public static final SoundEvent RECORD_STRANGE_AND_ALIEN = register("record", "strange_and_alien"); + public static final SoundEvent RECORD_GRASPING_AT_STARS = register("record", "grasping_at_stars"); + public static final SoundEvent RECORD_ENDSEEKER = register("record", "endseeker"); + public static final SoundEvent RECORD_EO_DRACONA = register("record", "eo_dracona"); + + public static void register() { + } + + private static SoundEvent register(String type, String id) { + id = "betterend." + type + "." + id; + return Registry.register(Registry.SOUND_EVENT, id, new SoundEvent(BetterEnd.makeID(id))); + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndStructures.java b/src/main/java/org/betterx/betterend/registry/EndStructures.java new file mode 100644 index 00000000..5a394097 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndStructures.java @@ -0,0 +1,79 @@ +package org.betterx.betterend.registry; + +import org.betterx.bclib.api.v2.levelgen.structures.BCLStructure; +import org.betterx.bclib.api.v2.levelgen.structures.BCLStructureBuilder; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.world.structures.features.*; +import org.betterx.betterend.world.structures.piece.*; +import org.betterx.worlds.together.tag.v3.TagManager; + +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.levelgen.GenerationStep.Decoration; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceType; + +public class EndStructures { + public static final StructurePieceType VOXEL_PIECE = register("voxel", VoxelPiece::new); + public static final StructurePieceType MOUNTAIN_PIECE = register("mountain_piece", CrystalMountainPiece::new); + public static final StructurePieceType CAVE_PIECE = register("cave_piece", CavePiece::new); + public static final StructurePieceType LAKE_PIECE = register("lake_piece", LakePiece::new); + public static final StructurePieceType PAINTED_MOUNTAIN_PIECE = register( + "painted_mountain_piece", + PaintedMountainPiece::new + ); + public static final StructurePieceType NBT_PIECE = register("nbt_piece", NBTPiece::new); + + public static final BCLStructure GIANT_MOSSY_GLOWSHROOM = BCLStructureBuilder + .start(BetterEnd.makeID("giant_mossy_glowshroom"), GiantMossyGlowshroomStructure::new) + .step(Decoration.SURFACE_STRUCTURES) + .randomPlacement(16, 8) + .build(); + + public static final BCLStructure MEGALAKE = BCLStructureBuilder + .start(BetterEnd.makeID("megalake"), MegaLakeStructure::new) + .step(Decoration.RAW_GENERATION) + .randomPlacement(4, 1) + .build(); + + public static final BCLStructure MEGALAKE_SMALL = BCLStructureBuilder + .start(BetterEnd.makeID("megalake_small"), MegaLakeSmallStructure::new) + .step(Decoration.RAW_GENERATION) + .randomPlacement(4, 1) + .build(); + + public static final BCLStructure MOUNTAIN = BCLStructureBuilder + .start(BetterEnd.makeID("mountain"), MountainStructure::new) + .step(Decoration.RAW_GENERATION) + .randomPlacement(3, 2) + .build(); + public static final BCLStructure PAINTED_MOUNTAIN = BCLStructureBuilder + .start(BetterEnd.makeID("painted_mountain"), PaintedMountainStructure::new) + .step(Decoration.RAW_GENERATION) + .randomPlacement(3, 2) + .build(); + public static final BCLStructure ETERNAL_PORTAL = BCLStructureBuilder + .start(BetterEnd.makeID("eternal_portal"), EternalPortalStructure::new) + .step(Decoration.RAW_GENERATION) + .randomPlacement(16, 6) + .build(); + public static final BCLStructure GIANT_ICE_STAR = BCLStructureBuilder + .start(BetterEnd.makeID("giant_ice_star"), GiantIceStarStructure::new) + .step(Decoration.SURFACE_STRUCTURES) + .randomPlacement(16, 8) + .build(); + + public static void register() { + } + + private static StructurePieceType register(String id, StructurePieceType pieceType) { + return Registry.register(Registry.STRUCTURE_PIECE, BetterEnd.makeID(id), pieceType); + } + + public static void addBiomeStructures(ResourceLocation biomeID, Holder biome) { + if (!biomeID.getPath().contains("mountain") && !biomeID.getPath().contains("lake")) { + TagManager.BIOMES.add(ETERNAL_PORTAL.biomeTag, biome.value()); + } + } +} diff --git a/src/main/java/org/betterx/betterend/registry/EndTags.java b/src/main/java/org/betterx/betterend/registry/EndTags.java new file mode 100644 index 00000000..9c6f0c28 --- /dev/null +++ b/src/main/java/org/betterx/betterend/registry/EndTags.java @@ -0,0 +1,139 @@ +package org.betterx.betterend.registry; + +import org.betterx.bclib.api.v2.BonemealAPI; +import org.betterx.bclib.api.v2.ComposterAPI; +import org.betterx.bclib.blocks.BaseVineBlock; +import org.betterx.bclib.blocks.SimpleLeavesBlock; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.blocks.basis.EndTerrainBlock; +import org.betterx.betterend.blocks.basis.PedestalBlock; +import org.betterx.betterend.item.tool.EndHammerItem; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; +import org.betterx.worlds.together.tag.v3.CommonItemTags; +import org.betterx.worlds.together.tag.v3.MineableTags; +import org.betterx.worlds.together.tag.v3.TagManager; + +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.ItemTags; +import net.minecraft.tags.TagKey; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockBehaviour.Properties; +import net.minecraft.world.level.material.Material; + +import net.fabricmc.fabric.mixin.object.builder.AbstractBlockAccessor; +import net.fabricmc.fabric.mixin.object.builder.AbstractBlockSettingsAccessor; + +import com.google.common.collect.Lists; + +import java.util.List; + +public class EndTags { + // Table with common (c) tags: + // https://fabricmc.net/wiki/tutorial:tags + + // Block Tags + public static final TagKey PEDESTALS = TagManager.BLOCKS.makeTag(BetterEnd.MOD_ID, "pedestal"); + + // Item Tags + public static final TagKey ALLOYING_IRON = TagManager.ITEMS.makeTag(BetterEnd.MOD_ID, "alloying_iron"); + public static final TagKey ALLOYING_GOLD = TagManager.ITEMS.makeTag(BetterEnd.MOD_ID, "alloying_gold"); + public static final TagKey ALLOYING_COPPER = TagManager.ITEMS.makeTag(BetterEnd.MOD_ID, "alloying_copper"); + + public static void register() { + addEndGround(EndBlocks.THALLASIUM.ore); + addEndGround(EndBlocks.ENDSTONE_DUST); + addEndGround(EndBlocks.AMBER_ORE); + + EndBlocks.getModBlocks().forEach(block -> { + Properties properties = ((AbstractBlockAccessor) block).getSettings(); + Material material = ((AbstractBlockSettingsAccessor) properties).getMaterial(); + final Item item = block.asItem(); + + if (material.equals(Material.STONE) || material.equals(Material.METAL) || material.equals(Material.HEAVY_METAL)) { + TagManager.BLOCKS.add(MineableTags.PICKAXE, block); + } else if (material.equals(Material.WOOD)) { + TagManager.BLOCKS.add(MineableTags.AXE, block); + } else if (material.equals(Material.LEAVES) || material.equals(Material.PLANT) || material.equals(Material.WATER_PLANT) || material.equals( + Material.SPONGE)) { + TagManager.BLOCKS.add(MineableTags.HOE, block); + } else if (material.equals(Material.SAND)) { + TagManager.BLOCKS.add(MineableTags.SHOVEL, block); + } + + if (block instanceof EndTerrainBlock) { + addEndGround(block); + TagManager.BLOCKS.add(BlockTags.NYLIUM, block); + BonemealAPI.addSpreadableBlock(block, Blocks.END_STONE); + } else if (block instanceof LeavesBlock || block instanceof SimpleLeavesBlock) { + TagManager.BLOCKS.add(BlockTags.LEAVES, block); + ComposterAPI.allowCompost(0.3f, item); + } else if (block instanceof BaseVineBlock) { + TagManager.BLOCKS.add(BlockTags.CLIMBABLE, block); + } else if (block instanceof PedestalBlock) { + TagManager.BLOCKS.add(PEDESTALS, block); + } + + Material mat = block.defaultBlockState().getMaterial(); + if (mat.equals(Material.PLANT) || mat.equals(Material.REPLACEABLE_PLANT)) { + ComposterAPI.allowCompost(0.1F, item); + } + }); + addEndGround(EndBlocks.CAVE_MOSS); + TagManager.BLOCKS.add(BlockTags.NYLIUM, EndBlocks.CAVE_MOSS); + BonemealAPI.addSpreadableBlock(EndBlocks.CAVE_MOSS, Blocks.END_STONE); + BonemealAPI.addSpreadableBlock(EndBlocks.MOSSY_OBSIDIAN, Blocks.OBSIDIAN); + BonemealAPI.addSpreadableBlock(EndBlocks.MOSSY_DRAGON_BONE, EndBlocks.DRAGON_BONE_BLOCK); + + List ITEM_HAMMERS = Lists.newArrayList(); + EndItems.getModItems().forEach(item -> { + if (item.isEdible()) { + FoodProperties food = item.getFoodProperties(); + if (food != null) { + float compost = food.getNutrition() * food.getSaturationModifier() * 0.18F; + ComposterAPI.allowCompost(compost, item); + } + } + if (item instanceof EndHammerItem) { + ITEM_HAMMERS.add(item); + } + }); + + TagManager.BLOCKS.add( + CommonBlockTags.END_STONES, + EndBlocks.ENDER_ORE, + EndBlocks.BRIMSTONE + ); + TagManager.BLOCKS.add(CommonBlockTags.END_STONES, EndBlocks.BRIMSTONE); + TagManager.BLOCKS.add(BlockTags.ANVIL, EndBlocks.AETERNIUM_ANVIL); + TagManager.BLOCKS.add(BlockTags.BEACON_BASE_BLOCKS, EndBlocks.AETERNIUM_BLOCK); + TagManager.ITEMS.add(ItemTags.BEACON_PAYMENT_ITEMS, EndItems.AETERNIUM_INGOT); + TagManager.BLOCKS.add( + BlockTags.DRAGON_IMMUNE, + EndBlocks.ENDER_ORE, + EndBlocks.ETERNAL_PEDESTAL, + EndBlocks.FLAVOLITE_RUNED_ETERNAL, + EndBlocks.FLAVOLITE_RUNED + ); + TagManager.ITEMS.add(CommonItemTags.IRON_INGOTS, EndBlocks.THALLASIUM.ingot); + + TagManager.ITEMS.add(ALLOYING_IRON, Items.IRON_ORE, Items.DEEPSLATE_IRON_ORE, Items.RAW_IRON); + TagManager.ITEMS.add(ALLOYING_GOLD, Items.GOLD_ORE, Items.DEEPSLATE_GOLD_ORE, Items.RAW_GOLD); + TagManager.ITEMS.add(ALLOYING_COPPER, Items.COPPER_ORE, Items.DEEPSLATE_COPPER_ORE, Items.RAW_COPPER); + } + + public static void addEndGround(Block bl) { + TagManager.BLOCKS.add(CommonBlockTags.END_STONES, bl); + } + + public static void addBiomeSurfaceToEndGroup(EndBiome b) { + addEndGround(b.getTopMaterial().getBlock()); + addEndGround(b.getAltTopMaterial().getBlock()); + addEndGround(b.getUnderMaterial().getBlock()); + } +} diff --git a/src/main/java/org/betterx/betterend/rituals/EternalRitual.java b/src/main/java/org/betterx/betterend/rituals/EternalRitual.java new file mode 100644 index 00000000..c7c831da --- /dev/null +++ b/src/main/java/org/betterx/betterend/rituals/EternalRitual.java @@ -0,0 +1,808 @@ +package org.betterx.betterend.rituals; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.advancements.BECriteria; +import org.betterx.betterend.blocks.EndPortalBlock; +import org.betterx.betterend.blocks.RunedFlavolite; +import org.betterx.betterend.blocks.entities.EternalPedestalEntity; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndPoiTypes; +import org.betterx.betterend.registry.EndPortals; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Registry; +import net.minecraft.core.particles.BlockParticleOption; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.entity.ai.village.poi.PoiManager; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.dimension.DimensionType; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.LegacyRandomSource; +import net.minecraft.world.level.material.Material; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +import java.awt.*; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; +import org.jetbrains.annotations.Nullable; + +public class EternalRitual { + private final static Set STRUCTURE_MAP = Sets.newHashSet( + new Point(-4, -5), + new Point(-4, 5), + new Point(-6, 0), + new Point(4, -5), + new Point(4, 5), + new Point(6, 0) + ); + private final static Set FRAME_MAP = Sets.newHashSet( + new Point(0, 0), + new Point(0, 6), + new Point(1, 0), + new Point(1, 6), + new Point(2, 1), + new Point(2, 5), + new Point(3, 2), + new Point(3, 3), + new Point(3, 4) + ); + private final static Set PORTAL_MAP = Sets.newHashSet( + new Point(0, 0), + new Point(0, 1), + new Point(0, 2), + new Point(0, 3), + new Point(0, 4), + new Point(1, 0), + new Point(1, 1), + new Point(1, 2), + new Point(1, 3), + new Point(1, 4), + new Point(2, 1), + new Point(2, 2), + new Point(2, 3) + ); + private final static Set BASE_MAP = Sets.newHashSet( + new Point(3, 0), + new Point(2, 0), + new Point(2, 1), + new Point(1, 1), + new Point(1, 2), + new Point(0, 1), + new Point(0, 2) + ); + + private final static Block BASE = EndBlocks.FLAVOLITE.tiles; + private final static Block PEDESTAL = EndBlocks.ETERNAL_PEDESTAL; + private final static Block FRAME = EndBlocks.FLAVOLITE_RUNED_ETERNAL; + private final static Block PORTAL = EndBlocks.END_PORTAL_BLOCK; + private final static BooleanProperty ACTIVE = BlockProperties.ACTIVE; + + public final static int SEARCH_RADIUS = calculateSearchSteps(48); + + private Level world; + private Direction.Axis axis; + private ResourceLocation targetWorldId; + private BlockPos center; + private BlockPos exit; + private boolean active = false; + + public EternalRitual(Level world) { + this.world = world; + } + + public EternalRitual(Level world, BlockPos initial) { + this(world); + this.configure(initial); + } + + public void setWorld(Level world) { + this.world = world; + } + + @Nullable + public ResourceLocation getTargetWorldId() { + return targetWorldId; + } + + private boolean isInvalid() { + return world == null || world.isClientSide() || center == null || axis == null; + } + + public void checkStructure(Player player) { + if (isInvalid()) return; + Direction moveX, moveY; + if (Direction.Axis.X == axis) { + moveX = Direction.EAST; + moveY = Direction.NORTH; + } else { + moveX = Direction.SOUTH; + moveY = Direction.EAST; + } + boolean valid = checkFrame(world, center.below()); + Item item = null; + for (Point pos : STRUCTURE_MAP) { + BlockPos.MutableBlockPos checkPos = center.mutable(); + checkPos.move(moveX, pos.x).move(moveY, pos.y); + valid &= isActive(checkPos); + if (valid) { + EternalPedestalEntity pedestal = (EternalPedestalEntity) world.getBlockEntity(checkPos); + if (pedestal != null) { + Item pItem = pedestal.getItem(0).getItem(); + if (item == null) { + item = pItem; + } else if (!item.equals(pItem)) { + valid = false; + } + } + } + } + if (valid && item != null) { + activatePortal(item); + if (player instanceof ServerPlayer sp) { + BECriteria.PORTAL_ON.trigger(sp); + } + } + } + + private boolean checkFrame(Level world, BlockPos framePos) { + Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH : Direction.EAST; + boolean valid = true; + for (Point point : FRAME_MAP) { + BlockPos pos = framePos.mutable().move(moveDir, point.x).move(Direction.UP, point.y); + BlockState state = world.getBlockState(pos); + valid &= state.getBlock() instanceof RunedFlavolite; + pos = framePos.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); + state = world.getBlockState(pos); + valid &= state.getBlock() instanceof RunedFlavolite; + } + return valid; + } + + public boolean isActive() { + return active; + } + + private void activatePortal(Item keyItem) { + if (active) return; + ResourceLocation itemId = Registry.ITEM.getKey(keyItem); + int portalId = EndPortals.getPortalIdByItem(itemId); + Level targetWorld = getTargetWorld(portalId); + ResourceLocation worldId = targetWorld.dimension().location(); + try { + if (exit == null) { + initPortal(worldId, portalId); + } else { + if (!worldId.equals(targetWorldId)) { + initPortal(worldId, portalId); + } else if (!checkFrame(targetWorld, exit.below())) { + Direction.Axis portalAxis = (Direction.Axis.X == axis) ? Direction.Axis.Z : Direction.Axis.X; + generatePortal(targetWorld, exit, portalAxis, portalId); + } + activatePortal(targetWorld, exit, portalId); + } + activatePortal(world, center, portalId); + doEffects((ServerLevel) world, center); + active = true; + } catch (Exception ex) { + BetterEnd.LOGGER.error("Create End portals error.", ex); + removePortal(targetWorld, exit); + removePortal(world, center); + active = false; + } + } + + private void initPortal(ResourceLocation worldId, int portalId) { + targetWorldId = worldId; + exit = findPortalPos(portalId); + } + + private void doEffects(ServerLevel serverWorld, BlockPos center) { + Direction moveX, moveY; + if (Direction.Axis.X == axis) { + moveX = Direction.EAST; + moveY = Direction.NORTH; + } else { + moveX = Direction.SOUTH; + moveY = Direction.EAST; + } + for (Point pos : STRUCTURE_MAP) { + BlockPos.MutableBlockPos p = center.mutable(); + p.move(moveX, pos.x).move(moveY, pos.y); + serverWorld.sendParticles( + ParticleTypes.PORTAL, + p.getX() + 0.5, + p.getY() + 1.5, + p.getZ() + 0.5, + 20, + 0, + 0, + 0, + 1 + ); + serverWorld.sendParticles( + ParticleTypes.REVERSE_PORTAL, + p.getX() + 0.5, + p.getY() + 1.5, + p.getZ() + 0.5, + 20, + 0, + 0, + 0, + 0.3 + ); + } + serverWorld.playSound(null, center, SoundEvents.END_PORTAL_SPAWN, SoundSource.NEUTRAL, 16, 1); + } + + private void activatePortal(Level world, BlockPos center, int portalId) { + BlockPos framePos = center.below(); + Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH : Direction.EAST; + BlockState frame = FRAME.defaultBlockState().setValue(ACTIVE, true); + FRAME_MAP.forEach(point -> { + BlockPos pos = framePos.mutable().move(moveDir, point.x).move(Direction.UP, point.y); + BlockState state = world.getBlockState(pos); + if (state.hasProperty(ACTIVE) && !state.getValue(ACTIVE)) { + world.setBlockAndUpdate(pos, frame); + } + pos = framePos.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); + state = world.getBlockState(pos); + if (state.hasProperty(ACTIVE) && !state.getValue(ACTIVE)) { + world.setBlockAndUpdate(pos, frame); + } + }); + Direction.Axis portalAxis = Direction.Axis.X == axis ? Direction.Axis.Z : Direction.Axis.X; + BlockState portal = PORTAL.defaultBlockState() + .setValue(EndPortalBlock.AXIS, portalAxis) + .setValue(EndPortalBlock.PORTAL, portalId); + ParticleOptions effect = new BlockParticleOption(ParticleTypes.BLOCK, portal); + ServerLevel serverWorld = (ServerLevel) world; + + PORTAL_MAP.forEach(point -> { + BlockPos pos = center.mutable().move(moveDir, point.x).move(Direction.UP, point.y); + if (!world.getBlockState(pos).is(PORTAL)) { + world.setBlockAndUpdate(pos, portal); + serverWorld.sendParticles( + effect, + pos.getX() + 0.5, + pos.getY() + 0.5, + pos.getZ() + 0.5, + 10, + 0.5, + 0.5, + 0.5, + 0.1 + ); + serverWorld.sendParticles( + ParticleTypes.REVERSE_PORTAL, + pos.getX() + 0.5, + pos.getY() + 0.5, + pos.getZ() + 0.5, + 10, + 0.5, + 0.5, + 0.5, + 0.3 + ); + } + pos = center.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); + if (!world.getBlockState(pos).is(PORTAL)) { + world.setBlockAndUpdate(pos, portal); + serverWorld.sendParticles( + effect, + pos.getX() + 0.5, + pos.getY() + 0.5, + pos.getZ() + 0.5, + 10, + 0.5, + 0.5, + 0.5, + 0.1 + ); + serverWorld.sendParticles( + ParticleTypes.REVERSE_PORTAL, + pos.getX() + 0.5, + pos.getY() + 0.5, + pos.getZ() + 0.5, + 10, + 0.5, + 0.5, + 0.5, + 0.3 + ); + } + }); + } + + public void disablePortal(int state) { + if (!active || isInvalid()) return; + removePortal(getTargetWorld(state), exit); + removePortal(world, center); + } + + private void removePortal(Level world, BlockPos center) { + BlockPos framePos = center.below(); + Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH : Direction.EAST; + FRAME_MAP.forEach(point -> { + BlockPos pos = framePos.mutable().move(moveDir, point.x).move(Direction.UP, point.y); + BlockState state = world.getBlockState(pos); + if (state.is(FRAME) && state.getValue(ACTIVE)) { + world.setBlockAndUpdate(pos, state.setValue(ACTIVE, false)); + } + pos = framePos.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); + state = world.getBlockState(pos); + if (state.is(FRAME) && state.getValue(ACTIVE)) { + world.setBlockAndUpdate(pos, state.setValue(ACTIVE, false)); + } + }); + PORTAL_MAP.forEach(point -> { + BlockPos pos = center.mutable().move(moveDir, point.x).move(Direction.UP, point.y); + if (world.getBlockState(pos).is(PORTAL)) { + world.removeBlock(pos, false); + } + pos = center.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); + if (world.getBlockState(pos).is(PORTAL)) { + world.removeBlock(pos, false); + } + }); + this.active = false; + } + + @Nullable + private BlockPos findFrame(ServerLevel level, BlockPos.MutableBlockPos startPos) { + Optional found = EndPoiTypes.ETERNAL_PORTAL_INACTIVE.findPoiAround( + level, + startPos, + SEARCH_RADIUS >> 4 + 1, + level.getWorldBorder() + ); + if (found.isPresent()) { + if (checkFrame(level, found.get())) + return found.get(); + } + // List foundPos = findAllBlockPos( +// level, +// startPos, +// (SEARCH_RADIUS >> 4) + 1, +// FRAME, +// blockState -> blockState.is(FRAME) && !blockState.getValue(ACTIVE) +// ); +// for (BlockPos.MutableBlockPos testPos : foundPos) { +// if (checkFrame(level, testPos)) { +// return testPos; +// } +// } + return null; + } + + private BlockPos findPortalPos(int portalId) { + MinecraftServer server = world.getServer(); + ServerLevel targetWorld = (ServerLevel) getTargetWorld(portalId); + Registry registry = Objects.requireNonNull(server) + .registryAccess() + .registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY); + double multiplier = Objects.requireNonNull(registry.get(targetWorldId)).coordinateScale(); + BlockPos.MutableBlockPos basePos = center.mutable() + .set( + center.getX() / multiplier, + center.getY(), + center.getZ() / multiplier + ); + BlockPos framePos = findFrame(targetWorld, basePos.mutable()); + if (framePos != null) { + return framePos.above(); + } + Direction.Axis portalAxis = (Direction.Axis.X == axis) ? Direction.Axis.Z : Direction.Axis.X; + int worldCeil = targetWorld.getHeight() - 1; + + if (checkIsAreaValid(targetWorld, basePos, portalAxis)) { + generatePortal(targetWorld, basePos, portalAxis, portalId); + return basePos.immutable(); + } else { + Direction direction = Direction.EAST; + BlockPos.MutableBlockPos checkPos = basePos.mutable(); + int radius = (int) ((SEARCH_RADIUS / multiplier) + 1); + //make sure chunks are properly loaded for faster searches + PoiManager poiManager = targetWorld.getPoiManager(); + poiManager.ensureLoadedAndValid(world, checkPos, radius >> 4); + + for (int step = 1; step < radius; step++) { + for (int i = 0; i < (step >> 1); i++) { + ChunkAccess chunk = targetWorld.getChunk(checkPos); + if (chunk != null) { + int surfaceY = chunk.getHeight( + Heightmap.Types.WORLD_SURFACE, + checkPos.getX() & 15, + checkPos.getZ() & 15 + ); + int motionY = chunk.getHeight( + Heightmap.Types.MOTION_BLOCKING, + checkPos.getX() & 15, + checkPos.getZ() & 15 + ); + int ceil = Math.min(Math.max(surfaceY, motionY) + 1, worldCeil); + if (ceil < 5) continue; + checkPos.setY(ceil); + while (checkPos.getY() >= 5) { + if (checkIsAreaValid(targetWorld, checkPos, portalAxis)) { + generatePortal(targetWorld, checkPos, portalAxis, portalId); + return checkPos.immutable(); + } + checkPos.move(Direction.DOWN); + } + } + checkPos.move(direction); + } + direction = direction.getClockWise(); + } + } + if (targetWorld.dimension() == Level.END) { + net.minecraft.data.worldgen.features.EndFeatures.END_ISLAND.value().place( + targetWorld, + targetWorld.getChunkSource().getGenerator(), + new LegacyRandomSource(basePos.asLong()), + basePos.below() + ); + } else if (targetWorld.dimension() == Level.OVERWORLD) { + basePos.setY(targetWorld.getChunk(basePos) + .getHeight(Heightmap.Types.WORLD_SURFACE, basePos.getX(), basePos.getZ()) + 1); + } + EndFeatures.BIOME_ISLAND + .getPlacedFeature() + .value() + .place( + targetWorld, + targetWorld.getChunkSource().getGenerator(), + new LegacyRandomSource(basePos.asLong()), + basePos.below() + ); + generatePortal(targetWorld, basePos, portalAxis, portalId); + return basePos.immutable(); + } + + private Level getTargetWorld(int state) { + if (world.dimension() == Level.END) { + return EndPortals.getWorld(world.getServer(), state); + } + return Objects.requireNonNull(world.getServer()).getLevel(Level.END); + } + + private boolean checkIsAreaValid(Level world, BlockPos pos, Direction.Axis axis) { + if (pos.getY() >= world.getHeight() - 1) return false; + if (!isBaseValid(world, pos, axis)) return false; + return EternalRitual.checkArea(world, pos, axis); + } + + private boolean isBaseValid(Level world, BlockPos pos, Direction.Axis axis) { + boolean solid = true; + if (axis.equals(Direction.Axis.X)) { + pos = pos.below().offset(0, 0, -3); + for (int i = 0; i < 7; i++) { + BlockPos checkPos = pos.offset(0, 0, i); + BlockState state = world.getBlockState(checkPos); + solid &= validBlock(world, checkPos, state); + } + } else { + pos = pos.below().offset(-3, 0, 0); + for (int i = 0; i < 7; i++) { + BlockPos checkPos = pos.offset(i, 0, 0); + BlockState state = world.getBlockState(checkPos); + solid &= validBlock(world, checkPos, state); + } + } + return solid; + } + + private boolean validBlock(Level world, BlockPos pos, BlockState state) { + return state.isRedstoneConductor(world, pos) && state.isCollisionShapeFullBlock(world, pos); + } + + public void configure(BlockPos initial) { + BlockPos checkPos = initial.east(12); + if (this.hasPedestal(checkPos)) { + this.axis = Direction.Axis.X; + this.center = initial.east(6); + return; + } + checkPos = initial.west(12); + if (this.hasPedestal(checkPos)) { + this.axis = Direction.Axis.X; + this.center = initial.west(6); + return; + } + checkPos = initial.south(12); + if (this.hasPedestal(checkPos)) { + this.axis = Direction.Axis.Z; + this.center = initial.south(6); + return; + } + checkPos = initial.north(12); + if (this.hasPedestal(checkPos)) { + this.axis = Direction.Axis.Z; + this.center = initial.north(6); + return; + } + checkPos = initial.north(10); + if (this.hasPedestal(checkPos)) { + this.axis = Direction.Axis.X; + checkPos = checkPos.east(8); + if (this.hasPedestal(checkPos)) { + this.center = initial.north(5).east(4); + } else { + this.center = initial.north(5).west(4); + } + return; + } + checkPos = initial.south(10); + if (this.hasPedestal(checkPos)) { + this.axis = Direction.Axis.X; + checkPos = checkPos.east(8); + if (this.hasPedestal(checkPos)) { + this.center = initial.south(5).east(4); + } else { + this.center = initial.south(5).west(4); + } + return; + } + checkPos = initial.east(10); + if (this.hasPedestal(checkPos)) { + this.axis = Direction.Axis.Z; + checkPos = checkPos.south(8); + if (this.hasPedestal(checkPos)) { + this.center = initial.east(5).south(4); + } else { + this.center = initial.east(5).north(4); + } + return; + } + checkPos = initial.west(10); + if (this.hasPedestal(checkPos)) { + this.axis = Direction.Axis.Z; + checkPos = checkPos.south(8); + if (this.hasPedestal(checkPos)) { + this.center = initial.west(5).south(4); + } else { + this.center = initial.west(5).north(4); + } + } + } + + private boolean hasPedestal(BlockPos pos) { + return world.getBlockState(pos).is(PEDESTAL); + } + + private boolean isActive(BlockPos pos) { + BlockState state = world.getBlockState(pos); + if (state.is(PEDESTAL)) { + EternalPedestalEntity pedestal = (EternalPedestalEntity) world.getBlockEntity(pos); + if (pedestal != null) { + if (!pedestal.hasRitual()) { + pedestal.linkRitual(this); + } else { + EternalRitual ritual = pedestal.getRitual(); + if (!ritual.equals(this)) { + pedestal.linkRitual(this); + } + } + } + return state.getValue(ACTIVE); + } + return false; + } + + public CompoundTag toTag(CompoundTag tag) { + tag.put("center", NbtUtils.writeBlockPos(center)); + tag.putString("axis", axis.getName()); + tag.putBoolean("active", active); + if (targetWorldId != null) { + tag.putString("key_item", targetWorldId.toString()); + } + if (exit != null) { + tag.put("exit", NbtUtils.writeBlockPos(exit)); + } + return tag; + } + + public void fromTag(CompoundTag tag) { + axis = Direction.Axis.byName(tag.getString("axis")); + center = NbtUtils.readBlockPos(tag.getCompound("center")); + active = tag.getBoolean("active"); + if (tag.contains("exit")) { + exit = NbtUtils.readBlockPos(tag.getCompound("exit")); + } + if (tag.contains("key_item")) { + targetWorldId = new ResourceLocation(tag.getString("key_item")); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + EternalRitual ritual = (EternalRitual) o; + return world.equals(ritual.world) && Objects.equals(center, ritual.center) && Objects.equals(exit, ritual.exit); + } + + public static void generatePortal(Level world, BlockPos center, Direction.Axis axis, int portalId) { + BlockPos framePos = center.below(); + Direction moveDir = Direction.Axis.X == axis ? Direction.EAST : Direction.NORTH; + BlockState frame = FRAME.defaultBlockState().setValue(ACTIVE, true); + FRAME_MAP.forEach(point -> { + BlockPos pos = framePos.mutable().move(moveDir, point.x).move(Direction.UP, point.y); + world.setBlockAndUpdate(pos, frame); + pos = framePos.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); + world.setBlockAndUpdate(pos, frame); + }); + BlockState portal = PORTAL.defaultBlockState() + .setValue(EndPortalBlock.AXIS, axis) + .setValue(EndPortalBlock.PORTAL, portalId); + PORTAL_MAP.forEach(point -> { + BlockPos pos = center.mutable().move(moveDir, point.x).move(Direction.UP, point.y); + world.setBlockAndUpdate(pos, portal); + pos = center.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); + world.setBlockAndUpdate(pos, portal); + }); + generateBase(world, framePos, moveDir); + } + + private static void generateBase(Level world, BlockPos center, Direction moveX) { + BlockState base = BASE.defaultBlockState(); + Direction moveY = moveX.getClockWise(); + BASE_MAP.forEach(point -> { + BlockPos pos = center.mutable().move(moveX, point.x).move(moveY, point.y); + world.setBlockAndUpdate(pos, base); + pos = center.mutable().move(moveX, -point.x).move(moveY, point.y); + world.setBlockAndUpdate(pos, base); + pos = center.mutable().move(moveX, point.x).move(moveY, -point.y); + world.setBlockAndUpdate(pos, base); + pos = center.mutable().move(moveX, -point.x).move(moveY, -point.y); + world.setBlockAndUpdate(pos, base); + }); + } + + public static boolean checkArea(Level world, BlockPos center, Direction.Axis axis) { + Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH : Direction.EAST; + for (BlockPos checkPos : BlockPos.betweenClosed( + center.relative(moveDir.getClockWise()), + center.relative(moveDir.getCounterClockWise()) + )) { + for (Point point : PORTAL_MAP) { + BlockPos pos = checkPos.mutable().move(moveDir, point.x).move(Direction.UP, point.y); + BlockState state = world.getBlockState(pos); + if (isStateInvalid(state)) return false; + pos = checkPos.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); + state = world.getBlockState(pos); + if (isStateInvalid(state)) return false; + } + } + return true; + } + + private static boolean isStateInvalid(BlockState state) { + if (!state.getFluidState().isEmpty()) return true; + Material material = state.getMaterial(); + return !material.isReplaceable() && !material.equals(Material.PLANT); + } + + /** + * @param world World for search + * @param checkPos Start search position + * @param radius Search radius + * @param searchBlock Target block + * @param condition Predicate for test block states in the chunk section + * @return Position of the first found block or null. + */ + @Nullable + public static BlockPos.MutableBlockPos findBlockPos( + Level world, + BlockPos.MutableBlockPos checkPos, + int radius, + Block searchBlock, + Predicate condition + ) { + Direction moveDirection = Direction.EAST; + for (int step = 1; step < radius; step++) { + for (int i = 0; i < (step >> 1); i++) { + ChunkAccess chunk = world.getChunk(checkPos); + if (!(chunk instanceof LevelChunk) || ((LevelChunk) chunk).isEmpty()) continue; + for (LevelChunkSection section : chunk.getSections()) { + if (section == null || !section.getStates().maybeHas(condition)) continue; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + BlockState checkState = section.getBlockState(x, y, z); + if (checkState.is(searchBlock)) { + int worldX = (chunk.getPos().x << 4) + x; + int worldY = section.bottomBlockY() + y; + int worldZ = (chunk.getPos().z << 4) + z; + checkPos.set(worldX, worldY, worldZ); + return checkPos; + } + } + } + } + } + checkPos.move(moveDirection, 16); + } + moveDirection = moveDirection.getClockWise(); + } + return null; + } + + /** + * @param world World for search + * @param checkPos Start search position + * @param radius Search radius + * @param searchBlock Target block + * @param condition Predicate for test block states in the chunk section + * @return List of positions of the all found blocks or empty list. + */ + public static List findAllBlockPos( + ServerLevel world, + BlockPos.MutableBlockPos checkPos, + int radius, + Block searchBlock, + Predicate condition + ) { + //make sure chunks are properly loaded for faster searches + PoiManager poiManager = world.getPoiManager(); + poiManager.ensureLoadedAndValid(world, checkPos, radius >> 4); + + List posFound = Lists.newArrayList(); + Direction moveDirection = Direction.EAST; + for (int step = 1; step < radius; step++) { + for (int i = 0; i < (step >> 1); i++) { + ChunkAccess chunk = world.getChunk(checkPos); + if (!(chunk instanceof LevelChunk) || ((LevelChunk) chunk).isEmpty()) continue; + for (LevelChunkSection section : chunk.getSections()) { + if (section == null || !section.getStates().maybeHas(condition)) continue; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + BlockState checkState = section.getBlockState(x, y, z); + if (checkState.is(searchBlock)) { + int worldX = (chunk.getPos().x << 4) + x; + int worldY = section.bottomBlockY() + y; + int worldZ = (chunk.getPos().z << 4) + z; + checkPos.set(worldX, worldY, worldZ); + posFound.add(checkPos.mutable()); + } + } + } + } + } + checkPos.move(moveDirection, 16); + } + moveDirection = moveDirection.getClockWise(); + } + return posFound; + } + + public static int calculateSearchSteps(int chunkRadius) { + return chunkRadius * 4 - 1; + } +} diff --git a/src/main/java/org/betterx/betterend/rituals/InfusionRitual.java b/src/main/java/org/betterx/betterend/rituals/InfusionRitual.java new file mode 100644 index 00000000..353de131 --- /dev/null +++ b/src/main/java/org/betterx/betterend/rituals/InfusionRitual.java @@ -0,0 +1,262 @@ +package org.betterx.betterend.rituals; + +import org.betterx.betterend.advancements.BECriteria; +import org.betterx.betterend.blocks.entities.InfusionPedestalEntity; +import org.betterx.betterend.blocks.entities.PedestalBlockEntity; +import org.betterx.betterend.particle.InfusionParticleType; +import org.betterx.betterend.recipe.builders.InfusionRecipe; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.Container; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.phys.Vec3; + +import java.awt.*; +import java.util.Arrays; +import java.util.Objects; + +public class InfusionRitual implements Container { + private static final Point[] PEDESTALS_MAP = new Point[]{ + new Point(0, 3), + new Point(2, 2), + new Point(3, 0), + new Point(2, -2), + new Point(0, -3), + new Point(-2, -2), + new Point(-3, 0), + new Point(-2, 2) + }; + + private Level world; + private BlockPos worldPos; + private InfusionRecipe activeRecipe; + private boolean isDirty = false; + private boolean hasRecipe = false; + private int progress = 0; + private int time = 0; + + private final PedestalBlockEntity[] catalysts = new PedestalBlockEntity[8]; + private final InfusionPedestalEntity input; + + public InfusionRitual(InfusionPedestalEntity pedestal, Level world, BlockPos pos) { + this.input = pedestal; + this.world = world; + this.worldPos = pos; + } + + public void configure() { + if (world == null || worldPos == null) return; + for (int i = 0; i < catalysts.length; i++) { + Point point = PEDESTALS_MAP[i]; + MutableBlockPos checkPos = worldPos.mutable().move(Direction.EAST, point.x).move(Direction.NORTH, point.y); + BlockEntity catalystEntity = world.getBlockEntity(checkPos); + if (catalystEntity instanceof PedestalBlockEntity) { + catalysts[i] = (PedestalBlockEntity) catalystEntity; + } else { + catalysts[i] = null; + } + } + } + + public boolean checkRecipe() { + if (!isValid()) return false; + InfusionRecipe recipe = world.getRecipeManager().getRecipeFor(InfusionRecipe.TYPE, this, world).orElse(null); + if (hasRecipe()) { + if (recipe == null) { + reset(); + return false; + } else if (activeRecipe == null || recipe.getInfusionTime() != time) { + updateRecipe(recipe); + } + return true; + } + if (recipe != null) { + updateRecipe(recipe); + return true; + } + return false; + } + + private void updateRecipe(InfusionRecipe recipe) { + activeRecipe = recipe; + hasRecipe = true; + resetTimer(); + setChanged(); + } + + private void resetTimer() { + time = activeRecipe != null ? activeRecipe.getInfusionTime() : 0; + progress = 0; + } + + public void reset() { + activeRecipe = null; + hasRecipe = false; + resetTimer(); + setChanged(); + } + + public void tick() { + if (isDirty) { + configure(); + isDirty = false; + } + if (!checkRecipe()) return; + progress++; + if (progress == time) { + clearContent(); + input.setItem(0, activeRecipe.assemble(this)); + if (world instanceof ServerLevel sl) { + sl.getPlayers(p -> p.position() + .subtract(new Vec3(worldPos.getX(), worldPos.getY(), worldPos.getZ())) + .length() < 16) + .forEach(p -> BECriteria.INFUSION_FINISHED.trigger(p)); + } + reset(); + } else if (world instanceof ServerLevel) { + ServerLevel serverLevel = (ServerLevel) world; + BlockPos target = worldPos.above(); + double tx = target.getX() + 0.5; + double ty = target.getY() + 0.5; + double tz = target.getZ() + 0.5; + for (PedestalBlockEntity catalyst : catalysts) { + ItemStack stack = catalyst.getItem(0); + if (!stack.isEmpty()) { + BlockPos start = catalyst.getBlockPos(); + double sx = start.getX() + 0.5; + double sy = start.getY() + 1.25; + double sz = start.getZ() + 0.5; + serverLevel.sendParticles( + new InfusionParticleType(stack), + sx, + sy, + sz, + 0, + tx - sx, + ty - sy, + tz - sz, + 0.5 + ); + } + } + } + + } + + @Override + public boolean canPlaceItem(int slot, ItemStack stack) { + return isValid(); + } + + public boolean isValid() { + if (world == null || worldPos == null || input == null) return false; + return Arrays.stream(catalysts).noneMatch(Objects::isNull); + } + + public boolean hasRecipe() { + return hasRecipe; + } + + public void setLocation(Level world, BlockPos pos) { + this.world = world; + this.worldPos = pos; + this.isDirty = true; + } + + @Override + public void clearContent() { + if (!isValid()) return; + input.clearContent(); + Arrays.stream(catalysts).forEach(PedestalBlockEntity::clearContent); + } + + @Override + public int getContainerSize() { + return 9; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public ItemStack getItem(int slot) { + if (slot > 8) return ItemStack.EMPTY; + if (slot == 0) { + return input.getItem(0); + } else { + return catalysts[slot - 1].getItem(0); + } + } + + @Override + public ItemStack removeItem(int slot, int amount) { + return removeItemNoUpdate(slot); + } + + @Override + public ItemStack removeItemNoUpdate(int slot) { + if (slot > 8) return ItemStack.EMPTY; + if (slot == 0) { + return input.removeItemNoUpdate(0); + } else { + return catalysts[slot - 1].removeItemNoUpdate(0); + } + } + + @Override + public void setItem(int slot, ItemStack stack) { + if (slot > 8) return; + if (slot == 0) { + input.setItem(0, stack); + } else { + catalysts[slot - 1].setItem(0, stack); + } + } + + @Override + public void setChanged() { + if (isValid()) { + input.setChanged(); + Arrays.stream(catalysts).forEach(PedestalBlockEntity::setChanged); + } + } + + public void setDirty() { + this.isDirty = true; + } + + @Override + public boolean stillValid(Player player) { + return true; + } + + public void fromTag(CompoundTag tag) { + if (tag.contains("recipe")) { + hasRecipe = tag.getBoolean("recipe"); + progress = tag.getInt("progress"); + time = tag.getInt("time"); + } + } + + public CompoundTag toTag(CompoundTag tag) { + if (hasRecipe()) { + tag.putBoolean("recipe", hasRecipe); + tag.putInt("progress", progress); + tag.putInt("time", time); + } + return tag; + } + + public static Point[] getMap() { + return PEDESTALS_MAP; + } +} diff --git a/src/main/java/org/betterx/betterend/tab/CreativeTabs.java b/src/main/java/org/betterx/betterend/tab/CreativeTabs.java new file mode 100644 index 00000000..53bb823b --- /dev/null +++ b/src/main/java/org/betterx/betterend/tab/CreativeTabs.java @@ -0,0 +1,36 @@ +package org.betterx.betterend.tab; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.ItemStack; + +import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder; + +import java.util.stream.Collectors; + +public class CreativeTabs { + public static final CreativeModeTab TAB_BLOCKS; + public static final CreativeModeTab TAB_ITEMS; + + static { + TAB_BLOCKS = FabricItemGroupBuilder + .create(BetterEnd.makeID("end_blocks")) + .icon(() -> new ItemStack(EndBlocks.END_MYCELIUM)) + .appendItems(stacks -> stacks.addAll(EndBlocks.getModBlockItems() + .stream() + .map(ItemStack::new) + .collect(Collectors.toList()))) + .build(); + TAB_ITEMS = FabricItemGroupBuilder + .create(BetterEnd.makeID("end_items")) + .icon(() -> new ItemStack(EndItems.ETERNAL_CRYSTAL)) + .appendItems(stacks -> stacks.addAll(EndItems.getModItems() + .stream() + .map(ItemStack::new) + .collect(Collectors.toList()))) + .build(); + } +} diff --git a/src/main/java/org/betterx/betterend/util/BlockFixer.java b/src/main/java/org/betterx/betterend/util/BlockFixer.java new file mode 100644 index 00000000..be228b4f --- /dev/null +++ b/src/main/java/org/betterx/betterend/util/BlockFixer.java @@ -0,0 +1,230 @@ +package org.betterx.betterend.util; + +import org.betterx.bclib.blocks.BaseDoublePlantBlock; +import org.betterx.bclib.blocks.BaseVineBlock; +import org.betterx.bclib.blocks.StalactiteBlock; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.blocks.BlueVineBlock; +import org.betterx.betterend.blocks.basis.FurBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.FallingBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.dimension.DimensionType; + +import com.google.common.collect.Sets; + +import java.util.Set; +import java.util.stream.IntStream; + +public class BlockFixer { + private static final BlockState AIR = Blocks.AIR.defaultBlockState(); + private static final BlockState WATER = Blocks.WATER.defaultBlockState(); + + public static void fixBlocks(LevelAccessor level, BlockPos start, BlockPos end) { + final Registry registry = level.registryAccess() + .registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY); + final ResourceLocation dimKey = registry.getKey(level.dimensionType()); + if (dimKey != null && "world_blender".equals(dimKey.getNamespace())) { + return; + } + final Set doubleCheck = Sets.newConcurrentHashSet(); + final int dx = end.getX() - start.getX() + 1; + final int dz = end.getZ() - start.getZ() + 1; + final int count = dx * dz; + final int minY = Math.max(start.getY(), level.getMinBuildHeight()); + final int maxY = Math.min(end.getY(), level.getMaxBuildHeight()); + IntStream.range(0, count).forEach(index -> { + MutableBlockPos POS = new MutableBlockPos(); + POS.setX((index % dx) + start.getX()); + POS.setZ((index / dx) + start.getZ()); + BlockState state; + for (int y = minY; y <= maxY; y++) { + POS.setY(y); + state = level.getBlockState(POS); + + if (state.getBlock() instanceof FurBlock) { + doubleCheck.add(POS.immutable()); + } + // Liquids + else if (!state.getFluidState().isEmpty()) { + if (!state.canSurvive(level, POS)) { + setWithoutUpdate(level, POS, WATER); + POS.setY(POS.getY() - 1); + state = level.getBlockState(POS); + while (!state.canSurvive(level, POS)) { + state = state.getFluidState().isEmpty() ? AIR : WATER; + setWithoutUpdate(level, POS, state); + POS.setY(POS.getY() - 1); + state = level.getBlockState(POS); + } + } + POS.setY(y - 1); + if (level.isEmptyBlock(POS)) { + POS.setY(y); + while (!level.getFluidState(POS).isEmpty()) { + setWithoutUpdate(level, POS, AIR); + POS.setY(POS.getY() + 1); + } + continue; + } + for (Direction dir : BlocksHelper.HORIZONTAL) { + if (level.isEmptyBlock(POS.relative(dir))) { + try { + level.scheduleTick(POS, state.getFluidState().getType(), 0); + } catch (Exception e) { + } + break; + } + } + } else if (state.is(EndBlocks.SMARAGDANT_CRYSTAL)) { + POS.setY(POS.getY() - 1); + if (level.isEmptyBlock(POS)) { + POS.setY(POS.getY() + 1); + while (state.is(EndBlocks.SMARAGDANT_CRYSTAL)) { + setWithoutUpdate(level, POS, AIR); + POS.setY(POS.getY() + 1); + state = level.getBlockState(POS); + } + } + } else if (state.getBlock() instanceof StalactiteBlock) { + if (!state.canSurvive(level, POS)) { + if (level.getBlockState(POS.above()).getBlock() instanceof StalactiteBlock) { + while (state.getBlock() instanceof StalactiteBlock) { + setWithoutUpdate(level, POS, AIR); + POS.setY(POS.getY() + 1); + state = level.getBlockState(POS); + } + } else { + while (state.getBlock() instanceof StalactiteBlock) { + setWithoutUpdate(level, POS, AIR); + POS.setY(POS.getY() - 1); + state = level.getBlockState(POS); + } + } + } + } else if (state.is(EndBlocks.CAVE_PUMPKIN)) { + if (!level.getBlockState(POS.above()).is(EndBlocks.CAVE_PUMPKIN_SEED)) { + setWithoutUpdate(level, POS, AIR); + } + } else if (!state.canSurvive(level, POS)) { + // Chorus + if (state.is(Blocks.CHORUS_PLANT)) { + Set ends = Sets.newHashSet(); + Set add = Sets.newHashSet(); + ends.add(POS.immutable()); + + for (int i = 0; i < 64 && !ends.isEmpty(); i++) { + ends.forEach((pos) -> { + setWithoutUpdate(level, pos, AIR); + for (Direction dir : BlocksHelper.HORIZONTAL) { + BlockPos p = pos.relative(dir); + BlockState st = level.getBlockState(p); + if ((st.is(Blocks.CHORUS_PLANT) || st.is(Blocks.CHORUS_FLOWER)) && !st.canSurvive( + level, + p + )) { + add.add(p); + } + } + BlockPos p = pos.above(); + BlockState st = level.getBlockState(p); + if ((st.is(Blocks.CHORUS_PLANT) || st.is(Blocks.CHORUS_FLOWER)) && !st.canSurvive( + level, + p + )) { + add.add(p); + } + }); + ends.clear(); + ends.addAll(add); + add.clear(); + } + } + // Vines + else if (state.getBlock() instanceof BaseVineBlock) { + while (level.getBlockState(POS).getBlock() instanceof BaseVineBlock) { + setWithoutUpdate(level, POS, AIR); + POS.setY(POS.getY() - 1); + } + } + // Falling blocks + else if (state.getBlock() instanceof FallingBlock) { + BlockState falling = state; + + POS.setY(POS.getY() - 1); + state = level.getBlockState(POS); + + int ray = BlocksHelper.downRayRep(level, POS.immutable(), 64); + if (ray > 32) { + setWithoutUpdate(level, POS, Blocks.END_STONE.defaultBlockState()); + if (level.getRandom().nextBoolean()) { + POS.setY(POS.getY() - 1); + state = level.getBlockState(POS); + setWithoutUpdate(level, POS, Blocks.END_STONE.defaultBlockState()); + } + } else { + POS.setY(y); + BlockState replacement = AIR; + for (Direction dir : BlocksHelper.HORIZONTAL) { + state = level.getBlockState(POS.relative(dir)); + if (!state.getFluidState().isEmpty()) { + replacement = state; + break; + } + } + setWithoutUpdate(level, POS, replacement); + POS.setY(y - ray); + setWithoutUpdate(level, POS, falling); + } + } + // Blocks without support + else { + // Blue Vine + if (state.getBlock() instanceof BlueVineBlock) { + while (state.is(EndBlocks.BLUE_VINE) || state.is(EndBlocks.BLUE_VINE_LANTERN) || state.is( + EndBlocks.BLUE_VINE_FUR)) { + setWithoutUpdate(level, POS, AIR); + POS.setY(POS.getY() + 1); + state = level.getBlockState(POS); + } + } + // Double plants + if (state.getBlock() instanceof BaseDoublePlantBlock) { + setWithoutUpdate(level, POS, AIR); + POS.setY(POS.getY() + 1); + setWithoutUpdate(level, POS, AIR); + } + // Other blocks + else { + setWithoutUpdate(level, POS, getAirOrFluid(state)); + } + } + } + } + }); + + doubleCheck.forEach((pos) -> { + if (!level.getBlockState(pos).canSurvive(level, pos)) { + setWithoutUpdate(level, pos, AIR); + } + }); + } + + private static BlockState getAirOrFluid(BlockState state) { + return state.getFluidState().isEmpty() ? AIR : state.getFluidState().createLegacyBlock(); + } + + private static void setWithoutUpdate(LevelAccessor world, BlockPos pos, BlockState state) { + synchronized (world) { + BlocksHelper.setWithoutUpdate(world, pos, state); + } + } +} diff --git a/src/main/java/org/betterx/betterend/util/BonemealPlants.java b/src/main/java/org/betterx/betterend/util/BonemealPlants.java new file mode 100644 index 00000000..24e6655e --- /dev/null +++ b/src/main/java/org/betterx/betterend/util/BonemealPlants.java @@ -0,0 +1,123 @@ +package org.betterx.betterend.util; + +import org.betterx.bclib.api.v2.BonemealAPI; +import org.betterx.betterend.blocks.basis.EndTerrainBlock; +import org.betterx.betterend.registry.EndBiomes; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; + +import com.google.common.collect.Lists; + +import java.util.List; + +public class BonemealPlants { + public static void init() { + BonemealAPI.addLandGrass(EndBlocks.CREEPING_MOSS, EndBlocks.END_MOSS); + BonemealAPI.addLandGrass(EndBlocks.UMBRELLA_MOSS, EndBlocks.END_MOSS); + BonemealAPI.addLandGrass(EndBlocks.CREEPING_MOSS, EndBlocks.END_MYCELIUM); + BonemealAPI.addLandGrass(EndBlocks.UMBRELLA_MOSS, EndBlocks.END_MYCELIUM); + + BonemealAPI.addLandGrass(EndBlocks.CAVE_GRASS, EndBlocks.CAVE_MOSS); + BonemealAPI.addLandGrass(EndBlocks.CHORUS_GRASS, EndBlocks.CHORUS_NYLIUM); + BonemealAPI.addLandGrass(EndBlocks.CRYSTAL_GRASS, EndBlocks.CRYSTAL_MOSS); + BonemealAPI.addLandGrass(EndBlocks.SHADOW_PLANT, EndBlocks.SHADOW_GRASS); + BonemealAPI.addLandGrass(EndBlocks.BUSHY_GRASS, EndBlocks.PINK_MOSS); + BonemealAPI.addLandGrass(EndBlocks.AMBER_GRASS, EndBlocks.AMBER_MOSS); + + BonemealAPI.addLandGrass(EndBlocks.JUNGLE_GRASS, EndBlocks.JUNGLE_MOSS); + BonemealAPI.addLandGrass(EndBlocks.TWISTED_UMBRELLA_MOSS, EndBlocks.JUNGLE_MOSS); + BonemealAPI.addLandGrass(EndBlocks.SMALL_JELLYSHROOM, EndBlocks.JUNGLE_MOSS, 0.1F); + + BonemealAPI.addLandGrass( + EndBiomes.GLOWING_GRASSLANDS.getID(), + EndBlocks.BLOOMING_COOKSONIA, + EndBlocks.END_MOSS + ); + BonemealAPI.addLandGrass(EndBiomes.GLOWING_GRASSLANDS.getID(), EndBlocks.VAIOLUSH_FERN, EndBlocks.END_MOSS); + BonemealAPI.addLandGrass(EndBiomes.GLOWING_GRASSLANDS.getID(), EndBlocks.FRACTURN, EndBlocks.END_MOSS); + BonemealAPI.addLandGrass(EndBiomes.GLOWING_GRASSLANDS.getID(), EndBlocks.SALTEAGO, EndBlocks.END_MOSS); + + BonemealAPI.addLandGrass( + EndBiomes.GLOWING_GRASSLANDS.getID(), + EndBlocks.CREEPING_MOSS, + EndBlocks.END_MOSS, + 0.1F + ); + BonemealAPI.addLandGrass( + EndBiomes.GLOWING_GRASSLANDS.getID(), + EndBlocks.UMBRELLA_MOSS, + EndBlocks.END_MOSS, + 0.1F + ); + BonemealAPI.addLandGrass( + EndBiomes.GLOWING_GRASSLANDS.getID(), + EndBlocks.TWISTED_UMBRELLA_MOSS, + EndBlocks.END_MOSS, + 0.1F + ); + + BonemealAPI.addLandGrass(EndBlocks.ORANGO, EndBlocks.RUTISCUS); + BonemealAPI.addLandGrass(EndBlocks.AERIDIUM, EndBlocks.RUTISCUS, 0.2F); + BonemealAPI.addLandGrass(EndBlocks.LUTEBUS, EndBlocks.RUTISCUS, 0.2F); + BonemealAPI.addLandGrass(EndBlocks.LAMELLARIUM, EndBlocks.RUTISCUS); + + BonemealAPI.addLandGrass(EndBiomes.LANTERN_WOODS.getID(), EndBlocks.AERIDIUM, EndBlocks.RUTISCUS, 0.2F); + BonemealAPI.addLandGrass(EndBiomes.LANTERN_WOODS.getID(), EndBlocks.LAMELLARIUM, EndBlocks.RUTISCUS); + BonemealAPI.addLandGrass(EndBiomes.LANTERN_WOODS.getID(), EndBlocks.BOLUX_MUSHROOM, EndBlocks.RUTISCUS, 0.05F); + + BonemealAPI.addLandGrass( + EndBlocks.GLOBULAGUS, + EndBlocks.SANGNUM, + EndBlocks.MOSSY_OBSIDIAN, + EndBlocks.MOSSY_DRAGON_BONE + ); + BonemealAPI.addLandGrass( + EndBlocks.CLAWFERN, + EndBlocks.SANGNUM, + EndBlocks.MOSSY_OBSIDIAN, + EndBlocks.MOSSY_DRAGON_BONE + ); + BonemealAPI.addLandGrass(EndBlocks.SANGNUM, EndBlocks.SMALL_AMARANITA_MUSHROOM, 0.1F); + BonemealAPI.addLandGrass(EndBlocks.SMALL_AMARANITA_MUSHROOM, EndBlocks.MOSSY_OBSIDIAN, 0.1F); + BonemealAPI.addLandGrass(EndBlocks.SMALL_AMARANITA_MUSHROOM, EndBlocks.MOSSY_DRAGON_BONE, 0.1F); + + BonemealAPI.addLandGrass(EndBlocks.GLOBULAGUS, EndBlocks.MOSSY_DRAGON_BONE); + BonemealAPI.addLandGrass(EndBlocks.CLAWFERN, EndBlocks.MOSSY_DRAGON_BONE); + BonemealAPI.addLandGrass(EndBlocks.SMALL_AMARANITA_MUSHROOM, EndBlocks.MOSSY_DRAGON_BONE, 0.1F); + + BonemealAPI.addLandGrass(EndBlocks.GLOBULAGUS, EndBlocks.MOSSY_OBSIDIAN); + BonemealAPI.addLandGrass(EndBlocks.CLAWFERN, EndBlocks.MOSSY_OBSIDIAN); + BonemealAPI.addLandGrass(EndBlocks.SMALL_AMARANITA_MUSHROOM, EndBlocks.MOSSY_OBSIDIAN, 0.1F); + + Block[] charnias = new Block[]{ + EndBlocks.CHARNIA_CYAN, + EndBlocks.CHARNIA_GREEN, + EndBlocks.CHARNIA_ORANGE, + EndBlocks.CHARNIA_LIGHT_BLUE, + EndBlocks.CHARNIA_PURPLE, + EndBlocks.CHARNIA_RED + }; + List terrain = Lists.newArrayList(); + EndBlocks.getModBlocks().forEach(block -> { + if (block instanceof EndTerrainBlock) { + terrain.add(block); + } + }); + terrain.add(Blocks.END_STONE); + terrain.add(EndBlocks.ENDSTONE_DUST); + terrain.add(EndBlocks.CAVE_MOSS); + terrain.add(EndBlocks.SULPHURIC_ROCK.stone); + terrain.add(EndBlocks.VIOLECITE.stone); + terrain.add(EndBlocks.FLAVOLITE.stone); + terrain.add(EndBlocks.AZURE_JADESTONE.stone); + terrain.add(EndBlocks.VIRID_JADESTONE.stone); + terrain.add(EndBlocks.SANDY_JADESTONE.stone); + terrain.add(EndBlocks.BRIMSTONE); + Block[] terrainBlocks = terrain.toArray(new Block[terrain.size()]); + for (Block charnia : charnias) { + BonemealAPI.addWaterGrass(charnia, terrainBlocks); + } + } +} diff --git a/src/main/java/org/betterx/betterend/util/GlobalState.java b/src/main/java/org/betterx/betterend/util/GlobalState.java new file mode 100644 index 00000000..49650746 --- /dev/null +++ b/src/main/java/org/betterx/betterend/util/GlobalState.java @@ -0,0 +1,13 @@ +package org.betterx.betterend.util; + +import net.minecraft.core.BlockPos.MutableBlockPos; + +public class GlobalState { + private static final ThreadLocal STATE = ThreadLocal.withInitial(() -> new GlobalState()); + + public static GlobalState stateForThread() { + return STATE.get(); + } + + public final MutableBlockPos POS = new MutableBlockPos(); +} diff --git a/src/main/java/org/betterx/betterend/util/LangUtil.java b/src/main/java/org/betterx/betterend/util/LangUtil.java new file mode 100644 index 00000000..1a0f5d41 --- /dev/null +++ b/src/main/java/org/betterx/betterend/util/LangUtil.java @@ -0,0 +1,40 @@ +package org.betterx.betterend.util; + +import net.minecraft.client.resources.language.I18n; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; + + +public class LangUtil { + public final static String CONFIG_ELEMENT = "configuration"; + + private String element; + + public LangUtil(String element) { + this.element = element; + } + + public void setElement(String key) { + this.element = key; + } + + public String getString(String key) { + return getString(element, key); + } + + public MutableComponent getText(String key) { + return getText(element, key); + } + + public static String translate(String key) { + return I18n.get(key); + } + + public static String getString(String element, String key) { + return translate(String.format("%s.%s", element, key)); + } + + public static MutableComponent getText(String element, String key) { + return Component.translatable(getString(element, key)); + } +} diff --git a/src/main/java/org/betterx/betterend/util/LootTableUtil.java b/src/main/java/org/betterx/betterend/util/LootTableUtil.java new file mode 100644 index 00000000..1fcd0861 --- /dev/null +++ b/src/main/java/org/betterx/betterend/util/LootTableUtil.java @@ -0,0 +1,148 @@ +package org.betterx.betterend.util; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.complexmaterials.WoodenComplexMaterial; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndBiomes; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; + +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition; +import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; +import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; + +import net.fabricmc.fabric.api.loot.v2.LootTableEvents; + +public class LootTableUtil { + private static final ResourceLocation END_CITY_TREASURE_ID = new ResourceLocation("chests/end_city_treasure"); + private static final ResourceLocation COMMON = BetterEnd.makeID("chests/common"); + private static final ResourceLocation FOGGY_MUSHROOMLAND = BetterEnd.makeID("chests/foggy_mushroomland"); + private static final ResourceLocation CHORUS_FOREST = BetterEnd.makeID("chests/chorus_forest"); + private static final ResourceLocation SHADOW_FOREST = BetterEnd.makeID("chests/shadow_forest"); + private static final ResourceLocation LANTERN_WOODS = BetterEnd.makeID("chests/lantern_woods"); + private static final ResourceLocation UMBRELLA_JUNGLE = BetterEnd.makeID("chests/umbrella_jungle"); + + public static void init() { + LootTableEvents.MODIFY.register((resourceManager, lootManager, id, table, setter) -> { + if (END_CITY_TREASURE_ID.equals(id)) { + LootPool.Builder builder = LootPool.lootPool(); + builder.setRolls(ConstantValue.exactly(1)); + builder.when(LootItemRandomChanceCondition.randomChance(0.2f)); + builder.add(LootItem.lootTableItem(Items.GHAST_TEAR)); + table.withPool(builder); + + builder = LootPool.lootPool(); + builder.setRolls(UniformGenerator.between(0, 3)); + builder.add(LootItem.lootTableItem(EndItems.MUSIC_DISC_STRANGE_AND_ALIEN)); + builder.add(LootItem.lootTableItem(EndItems.MUSIC_DISC_GRASPING_AT_STARS)); + builder.add(LootItem.lootTableItem(EndItems.MUSIC_DISC_ENDSEEKER)); + builder.add(LootItem.lootTableItem(EndItems.MUSIC_DISC_EO_DRACONA)); + table.withPool(builder); + } else if (id.getNamespace().equals(BetterEnd.MOD_ID)) { + addCommonItems(table); + if (FOGGY_MUSHROOMLAND.equals(id)) { + LootPool.Builder builder = LootPool.lootPool(); + builder.setRolls(UniformGenerator.between(4, 8)); + builder.add(LootItem.lootTableItem(EndBlocks.MOSSY_GLOWSHROOM.getBlock(WoodenComplexMaterial.BLOCK_PLANKS))); + builder.add(LootItem.lootTableItem(EndBlocks.MOSSY_GLOWSHROOM_SAPLING)); + builder.add(LootItem.lootTableItem(EndBlocks.BLUE_VINE_SEED)); + table.withPool(builder); + } else if (CHORUS_FOREST.equals(id)) { + LootPool.Builder builder = LootPool.lootPool(); + builder.setRolls(UniformGenerator.between(4, 8)); + builder.add(LootItem.lootTableItem(EndBlocks.PYTHADENDRON.getBlock(WoodenComplexMaterial.BLOCK_PLANKS))); + builder.add(LootItem.lootTableItem(EndBlocks.PYTHADENDRON_SAPLING)); + builder.add(LootItem.lootTableItem(EndBlocks.CHORUS_MUSHROOM)); + table.withPool(builder); + } else if (SHADOW_FOREST.equals(id)) { + LootPool.Builder builder = LootPool.lootPool(); + builder.setRolls(UniformGenerator.between(4, 8)); + builder.add(LootItem.lootTableItem(EndBlocks.DRAGON_TREE.getBlock(WoodenComplexMaterial.BLOCK_PLANKS))); + builder.add(LootItem.lootTableItem(EndBlocks.DRAGON_TREE_SAPLING)); + builder.add(LootItem.lootTableItem(EndBlocks.SHADOW_BERRY)); + builder.add(LootItem.lootTableItem(EndItems.SHADOW_BERRY_RAW)); + table.withPool(builder); + } else if (LANTERN_WOODS.equals(id)) { + LootPool.Builder builder = LootPool.lootPool(); + builder.setRolls(UniformGenerator.between(4, 8)); + builder.add(LootItem.lootTableItem(EndBlocks.LUCERNIA.getBlock(WoodenComplexMaterial.BLOCK_PLANKS))); + builder.add(LootItem.lootTableItem(EndBlocks.LUCERNIA_SAPLING)); + builder.add(LootItem.lootTableItem(EndBlocks.BOLUX_MUSHROOM)); + table.withPool(builder); + } else if (UMBRELLA_JUNGLE.equals(id)) { + LootPool.Builder builder = LootPool.lootPool(); + builder.setRolls(UniformGenerator.between(4, 8)); + builder.add(LootItem.lootTableItem(EndBlocks.UMBRELLA_TREE.getBlock(WoodenComplexMaterial.BLOCK_PLANKS))); + builder.add(LootItem.lootTableItem(EndBlocks.UMBRELLA_TREE_SAPLING)); + builder.add(LootItem.lootTableItem(EndBlocks.SMALL_JELLYSHROOM)); + table.withPool(builder); + } + } + }); + } + + public static ResourceLocation getTable(Holder biome) { + BCLBiome bclBiome = BiomeAPI.getBiome(biome.value()); + if (bclBiome == EndBiomes.FOGGY_MUSHROOMLAND) { + return FOGGY_MUSHROOMLAND; + } else if (bclBiome == EndBiomes.CHORUS_FOREST) { + return CHORUS_FOREST; + } else if (bclBiome == EndBiomes.SHADOW_FOREST) { + return SHADOW_FOREST; + } else if (bclBiome == EndBiomes.LANTERN_WOODS) { + return LANTERN_WOODS; + } else if (bclBiome == EndBiomes.UMBRELLA_JUNGLE) { + return UMBRELLA_JUNGLE; + } + return COMMON; + } + + private static void addCommonItems(LootTable.Builder table) { + LootPool.Builder builder = LootPool.lootPool(); + builder.setRolls(UniformGenerator.between(0, 2)); + builder.add(LootItem.lootTableItem(EndItems.MUSIC_DISC_STRANGE_AND_ALIEN)); + builder.add(LootItem.lootTableItem(EndItems.MUSIC_DISC_GRASPING_AT_STARS)); + builder.add(LootItem.lootTableItem(EndItems.MUSIC_DISC_ENDSEEKER)); + builder.add(LootItem.lootTableItem(EndItems.MUSIC_DISC_EO_DRACONA)); + table.withPool(builder); + + builder = LootPool.lootPool(); + builder.setRolls(UniformGenerator.between(4, 8)); + builder.add(LootItem.lootTableItem(EndBlocks.THALLASIUM.ingot)); + builder.add(LootItem.lootTableItem(EndBlocks.THALLASIUM.rawOre)); + builder.add(LootItem.lootTableItem(Items.ENDER_PEARL)); + table.withPool(builder); + + builder = LootPool.lootPool(); + builder.setRolls(UniformGenerator.between(2, 4)); + builder.add(LootItem.lootTableItem(EndBlocks.TERMINITE.ingot)); + builder.add(LootItem.lootTableItem(EndItems.ENDER_SHARD)); + builder.add(LootItem.lootTableItem(EndBlocks.AURORA_CRYSTAL)); + builder.add(LootItem.lootTableItem(EndBlocks.THALLASIUM.axe)); + builder.add(LootItem.lootTableItem(EndBlocks.THALLASIUM.pickaxe)); + builder.add(LootItem.lootTableItem(EndBlocks.THALLASIUM.hoe)); + builder.add(LootItem.lootTableItem(EndBlocks.THALLASIUM.sword)); + builder.add(LootItem.lootTableItem(EndBlocks.THALLASIUM.shovel)); + builder.add(LootItem.lootTableItem(Items.ENDER_EYE)); + builder.add(LootItem.lootTableItem(Blocks.OBSIDIAN)); + table.withPool(builder); + + builder = LootPool.lootPool(); + builder.setRolls(UniformGenerator.between(0, 4)); + builder.add(LootItem.lootTableItem(EndBlocks.FLAVOLITE_RUNED)); + builder.add(LootItem.lootTableItem(EndItems.AETERNIUM_INGOT)); + builder.add(LootItem.lootTableItem(EndItems.AMBER_GEM)); + builder.add(LootItem.lootTableItem(Items.END_CRYSTAL)); + builder.add(LootItem.lootTableItem(Items.GHAST_TEAR)); + table.withPool(builder); + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/EndBiome.java b/src/main/java/org/betterx/betterend/world/biome/EndBiome.java new file mode 100644 index 00000000..708d777d --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/EndBiome.java @@ -0,0 +1,259 @@ +package org.betterx.betterend.world.biome; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder.BiomeSupplier; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeSettings; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.api.v2.levelgen.surface.SurfaceRuleBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.bclib.util.WeightedList; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.registry.EndTags; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.data.worldgen.placement.EndPlacements; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.KeyDispatchDataCodec; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.SurfaceRules; + +import java.util.List; +import java.util.Optional; + +public class EndBiome extends BCLBiome implements SurfaceMaterialProvider { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> + codecWithSettings( + instance, + Codec.BOOL.fieldOf("has_caves").orElse(true).forGetter(o -> o.hasCaves), + SurfaceMaterialProvider.CODEC.fieldOf("surface") + .orElse(Config.DEFAULT_MATERIAL) + .forGetter(o -> o.surfMatProv) + ).apply(instance, EndBiome::new) + ); + public static final KeyDispatchDataCodec KEY_CODEC = KeyDispatchDataCodec.of(CODEC); + + @Override + public KeyDispatchDataCodec codec() { + return KEY_CODEC; + } + + protected EndBiome( + float terrainHeight, + float fogDensity, + float genChance, + int edgeSize, + boolean vertical, + Optional edge, + ResourceLocation biomeID, + Optional> parameterPoints, + Optional biomeParent, + Optional> subbiomes, + Optional intendedType, + boolean hasCaves, + SurfaceMaterialProvider surface + ) { + super( + terrainHeight, + fogDensity, + genChance, + edgeSize, + vertical, + edge, + biomeID, + parameterPoints, + biomeParent, + subbiomes, + intendedType + ); + this.hasCaves = hasCaves; + this.surfMatProv = surface; + } + + private boolean hasCaves = true; + + void setHasCaves(boolean v) { + this.hasCaves = v; + } + + public boolean hasCaves() { + return hasCaves; + } + + public static class DefaultSurfaceMaterialProvider implements SurfaceMaterialProvider { + public static final BlockState END_STONE = Blocks.END_STONE.defaultBlockState(); + + @Override + public BlockState getTopMaterial() { + return getUnderMaterial(); + } + + @Override + public BlockState getAltTopMaterial() { + return getTopMaterial(); + } + + @Override + public BlockState getUnderMaterial() { + return END_STONE; + } + + @Override + public boolean generateFloorRule() { + return true; + } + + @Override + public SurfaceRuleBuilder surface() { + SurfaceRuleBuilder builder = SurfaceRuleBuilder.start(); + + if (generateFloorRule() && getTopMaterial() != getUnderMaterial()) { + if (getTopMaterial() != getAltTopMaterial()) { + builder.floor(getTopMaterial()); + } else { + builder.chancedFloor(getTopMaterial(), getAltTopMaterial()); + } + } + return builder.filler(getUnderMaterial()); + } + } + + public abstract static class Config { + public static final SurfaceMaterialProvider DEFAULT_MATERIAL = new DefaultSurfaceMaterialProvider(); + + protected static final SurfaceRules.RuleSource END_STONE = SurfaceRules.state(DefaultSurfaceMaterialProvider.END_STONE); + protected static final SurfaceRules.RuleSource END_MOSS = SurfaceRules.state(EndBlocks.END_MOSS.defaultBlockState()); + protected static final SurfaceRules.RuleSource ENDSTONE_DUST = SurfaceRules.state(EndBlocks.ENDSTONE_DUST.defaultBlockState()); + protected static final SurfaceRules.RuleSource END_MYCELIUM = SurfaceRules.state(EndBlocks.END_MYCELIUM.defaultBlockState()); + protected static final SurfaceRules.RuleSource FLAVOLITE = SurfaceRules.state(EndBlocks.FLAVOLITE.stone.defaultBlockState()); + protected static final SurfaceRules.RuleSource SULPHURIC_ROCK = SurfaceRules.state(EndBlocks.SULPHURIC_ROCK.stone.defaultBlockState()); + protected static final SurfaceRules.RuleSource BRIMSTONE = SurfaceRules.state(EndBlocks.BRIMSTONE.defaultBlockState()); + protected static final SurfaceRules.RuleSource PALLIDIUM_FULL = SurfaceRules.state(EndBlocks.PALLIDIUM_FULL.defaultBlockState()); + protected static final SurfaceRules.RuleSource PALLIDIUM_HEAVY = SurfaceRules.state(EndBlocks.PALLIDIUM_HEAVY.defaultBlockState()); + protected static final SurfaceRules.RuleSource PALLIDIUM_THIN = SurfaceRules.state(EndBlocks.PALLIDIUM_THIN.defaultBlockState()); + protected static final SurfaceRules.RuleSource PALLIDIUM_TINY = SurfaceRules.state(EndBlocks.PALLIDIUM_TINY.defaultBlockState()); + protected static final SurfaceRules.RuleSource UMBRALITH = SurfaceRules.state(EndBlocks.UMBRALITH.stone.defaultBlockState()); + + public final ResourceLocation ID; + + protected Config(String name) { + this.ID = BetterEnd.makeID(name); + } + + protected abstract void addCustomBuildData(BCLBiomeBuilder builder); + + public BiomeSupplier getSupplier() { + return EndBiome::new; + } + + protected boolean hasCaves() { + return true; + } + + protected boolean hasReturnGateway() { + return true; + } + + protected SurfaceMaterialProvider surfaceMaterial() { + return DEFAULT_MATERIAL; + } + } + + + public EndBiome(ResourceLocation biomeID, Biome biome, BCLBiomeSettings settings) { + super(biomeID, biome, settings); + } + + public static EndBiome create(Config biomeConfig) { + BCLBiomeBuilder builder = BCLBiomeBuilder + .start(biomeConfig.ID) + .music(SoundEvents.MUSIC_END) + .waterColor(4159204) + .waterFogColor(329011) + .fogColor(0xA080A0) + .skyColor(0) + .mood(EndSounds.AMBIENT_DUST_WASTELANDS) + .temperature(0.5f) + .wetness(0.5f) + .precipitation(Biome.Precipitation.NONE) + .surface(biomeConfig.surfaceMaterial().surface().build()) + .endLandBiome(); + + biomeConfig.addCustomBuildData(builder); + EndFeatures.addDefaultFeatures(biomeConfig.ID, builder, biomeConfig.hasCaves()); + + if (biomeConfig.hasReturnGateway()) { + builder.feature(GenerationStep.Decoration.SURFACE_STRUCTURES, EndPlacements.END_GATEWAY_RETURN); + } + + EndBiome biome = builder.build(biomeConfig.getSupplier()); + biome.setHasCaves(biomeConfig.hasCaves()); + biome.setSurfaceMaterial(biomeConfig.surfaceMaterial()); + + EndTags.addBiomeSurfaceToEndGroup(biome); + return biome; + } + + + protected SurfaceMaterialProvider surfMatProv = Config.DEFAULT_MATERIAL; + + protected void setSurfaceMaterial(SurfaceMaterialProvider prov) { + surfMatProv = prov; + } + + @Override + public BlockState getTopMaterial() { + return surfMatProv.getTopMaterial(); + } + + @Override + public BlockState getUnderMaterial() { + return surfMatProv.getUnderMaterial(); + } + + @Override + public BlockState getAltTopMaterial() { + return surfMatProv.getAltTopMaterial(); + } + + @Override + public boolean generateFloorRule() { + return surfMatProv.generateFloorRule(); + } + + @Override + public SurfaceRuleBuilder surface() { + return surfMatProv.surface(); + } + + public static BlockState findTopMaterial(BCLBiome biome) { + return BiomeAPI.findTopMaterial(biome).orElse(EndBiome.Config.DEFAULT_MATERIAL.getTopMaterial()); + } + + public static BlockState findTopMaterial(Biome biome) { + return findTopMaterial(BiomeAPI.getBiome(biome)); + } + + public static BlockState findTopMaterial(WorldGenLevel world, BlockPos pos) { + return findTopMaterial(BiomeAPI.getBiome(world.getBiome(pos))); + } + + public static BlockState findUnderMaterial(BCLBiome biome) { + return BiomeAPI.findUnderMaterial(biome).orElse(EndBiome.Config.DEFAULT_MATERIAL.getUnderMaterial()); + } + + public static BlockState findUnderMaterial(WorldGenLevel world, BlockPos pos) { + return findUnderMaterial(BiomeAPI.getBiome(world.getBiome(pos))); + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/air/BiomeIceStarfield.java b/src/main/java/org/betterx/betterend/world/biome/air/BiomeIceStarfield.java new file mode 100644 index 00000000..c8cd2f4b --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/air/BiomeIceStarfield.java @@ -0,0 +1,35 @@ +package org.betterx.betterend.world.biome.air; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.world.entity.EntityType; + +public class BiomeIceStarfield extends EndBiome.Config { + public BiomeIceStarfield() { + super("ice_starfield"); + } + + @Override + protected boolean hasCaves() { + return false; + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder.structure(EndStructures.GIANT_ICE_STAR) + .fogColor(224, 245, 254) + .temperature(0F) + .fogDensity(2.2F) + .foliageColor(193, 244, 244) + .genChance(0.25F) + .particles(EndParticles.SNOWFLAKE, 0.002F) + .feature(EndFeatures.ICE_STAR) + .feature(EndFeatures.ICE_STAR_SMALL) + .spawn(EntityType.ENDERMAN, 20, 1, 4) + .endVoidBiome(); + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/cave/EmptyAuroraCaveBiome.java b/src/main/java/org/betterx/betterend/world/biome/cave/EmptyAuroraCaveBiome.java new file mode 100644 index 00000000..d50abe63 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/cave/EmptyAuroraCaveBiome.java @@ -0,0 +1,105 @@ +package org.betterx.betterend.world.biome.cave; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder.BiomeSupplier; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeSettings; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.bclib.util.WeightedList; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.betterend.world.biome.EndBiome; + +import com.mojang.serialization.Codec; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.KeyDispatchDataCodec; +import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; + +import java.util.List; +import java.util.Optional; + +public class EmptyAuroraCaveBiome extends EndCaveBiome.Config { + public static final Codec CODEC = EndCaveBiome.simpleCaveBiomeCodec(EmptyAuroraCaveBiome.Biome::new); + public static final KeyDispatchDataCodec KEY_CODEC = KeyDispatchDataCodec.of(CODEC); + + public static class Biome extends EndCaveBiome { + public Biome(ResourceLocation biomeID, net.minecraft.world.level.biome.Biome biome, BCLBiomeSettings settings) { + super(biomeID, biome, settings); + this.addFloorFeature(EndFeatures.BIG_AURORA_CRYSTAL.configuredFeature, 1); + + this.addCeilFeature(EndFeatures.END_STONE_STALACTITE.configuredFeature, 1); + } + + @Override + public KeyDispatchDataCodec codec() { + return EmptyAuroraCaveBiome.KEY_CODEC; + } + + protected Biome( + float terrainHeight, + float fogDensity, + float genChance, + int edgeSize, + boolean vertical, + Optional edge, + ResourceLocation biomeID, + Optional> parameterPoints, + Optional biomeParent, + Optional> subbiomes, + Optional intendedType, + boolean hasCaves, + SurfaceMaterialProvider surface, + WeightedList>> floorFeatures, + WeightedList>> ceilFeatures + ) { + super( + terrainHeight, + fogDensity, + genChance, + edgeSize, + vertical, + edge, + biomeID, + parameterPoints, + biomeParent, + subbiomes, + intendedType, + hasCaves, + surface, + floorFeatures, + ceilFeatures + ); + } + + @Override + public float getFloorDensity() { + return 0.01F; + } + + @Override + public float getCeilDensity() { + return 0.1F; + } + } + + public EmptyAuroraCaveBiome() { + super("empty_aurora_cave"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + super.addCustomBuildData(builder); + builder.fogColor(150, 30, 68) + .fogDensity(2.0F) + .plantsColor(108, 25, 46) + .waterAndFogColor(186, 77, 237) + .particles(EndParticles.GLOWING_SPHERE, 0.001F); + } + + @Override + public BiomeSupplier getSupplier() { + return EmptyAuroraCaveBiome.Biome::new; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/cave/EmptyEndCaveBiome.java b/src/main/java/org/betterx/betterend/world/biome/cave/EmptyEndCaveBiome.java new file mode 100644 index 00000000..143f3895 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/cave/EmptyEndCaveBiome.java @@ -0,0 +1,100 @@ +package org.betterx.betterend.world.biome.cave; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder.BiomeSupplier; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeSettings; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.bclib.util.WeightedList; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.biome.EndBiome; + +import com.mojang.serialization.Codec; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.KeyDispatchDataCodec; +import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; + +import java.util.List; +import java.util.Optional; + +public class EmptyEndCaveBiome extends EndCaveBiome.Config { + public static final Codec CODEC = EndCaveBiome.simpleCaveBiomeCodec(EmptyEndCaveBiome.Biome::new); + public static final KeyDispatchDataCodec KEY_CODEC = KeyDispatchDataCodec.of(CODEC); + + public static class Biome extends EndCaveBiome { + public Biome(ResourceLocation biomeID, net.minecraft.world.level.biome.Biome biome, BCLBiomeSettings settings) { + super(biomeID, biome, settings); + + this.addFloorFeature(EndFeatures.END_STONE_STALAGMITE.configuredFeature, 1); + this.addCeilFeature(EndFeatures.END_STONE_STALACTITE.configuredFeature, 1); + } + + @Override + public KeyDispatchDataCodec codec() { + return EmptyEndCaveBiome.KEY_CODEC; + } + + protected Biome( + float terrainHeight, + float fogDensity, + float genChance, + int edgeSize, + boolean vertical, + Optional edge, + ResourceLocation biomeID, + Optional> parameterPoints, + Optional biomeParent, + Optional> subbiomes, + Optional intendedType, + boolean hasCaves, + SurfaceMaterialProvider surface, + WeightedList>> floorFeatures, + WeightedList>> ceilFeatures + ) { + super( + terrainHeight, + fogDensity, + genChance, + edgeSize, + vertical, + edge, + biomeID, + parameterPoints, + biomeParent, + subbiomes, + intendedType, + hasCaves, + surface, + floorFeatures, + ceilFeatures + ); + } + + @Override + public float getFloorDensity() { + return 0.1F; + } + + @Override + public float getCeilDensity() { + return 0.1F; + } + } + + public EmptyEndCaveBiome() { + super("empty_end_cave"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + super.addCustomBuildData(builder); + builder.fogDensity(2.0F); + } + + @Override + public BiomeSupplier getSupplier() { + return Biome::new; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/cave/EmptySmaragdantCaveBiome.java b/src/main/java/org/betterx/betterend/world/biome/cave/EmptySmaragdantCaveBiome.java new file mode 100644 index 00000000..0e095c12 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/cave/EmptySmaragdantCaveBiome.java @@ -0,0 +1,108 @@ +package org.betterx.betterend.world.biome.cave; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder.BiomeSupplier; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeSettings; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.bclib.util.WeightedList; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.betterend.world.biome.EndBiome; + +import com.mojang.serialization.Codec; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.KeyDispatchDataCodec; +import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; + +import java.util.List; +import java.util.Optional; + +public class EmptySmaragdantCaveBiome extends EndCaveBiome.Config { + public static final Codec CODEC = EndCaveBiome.simpleCaveBiomeCodec( + EmptySmaragdantCaveBiome.Biome::new); + public static final KeyDispatchDataCodec KEY_CODEC = KeyDispatchDataCodec.of(CODEC); + + public static class Biome extends EndCaveBiome { + public Biome(ResourceLocation biomeID, net.minecraft.world.level.biome.Biome biome, BCLBiomeSettings settings) { + super(biomeID, biome, settings); + + this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL.configuredFeature, 1); + this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL_SHARD.configuredFeature, 20); + + this.addCeilFeature(EndFeatures.END_STONE_STALACTITE.configuredFeature, 1); + } + + @Override + public KeyDispatchDataCodec codec() { + return EmptySmaragdantCaveBiome.KEY_CODEC; + } + + protected Biome( + float terrainHeight, + float fogDensity, + float genChance, + int edgeSize, + boolean vertical, + Optional edge, + ResourceLocation biomeID, + Optional> parameterPoints, + Optional biomeParent, + Optional> subbiomes, + Optional intendedType, + boolean hasCaves, + SurfaceMaterialProvider surface, + WeightedList>> floorFeatures, + WeightedList>> ceilFeatures + ) { + super( + terrainHeight, + fogDensity, + genChance, + edgeSize, + vertical, + edge, + biomeID, + parameterPoints, + biomeParent, + subbiomes, + intendedType, + hasCaves, + surface, + floorFeatures, + ceilFeatures + ); + } + + @Override + public float getFloorDensity() { + return 0.1F; + } + + @Override + public float getCeilDensity() { + return 0.1F; + } + } + + public EmptySmaragdantCaveBiome() { + super("empty_smaragdant_cave"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + super.addCustomBuildData(builder); + builder.fogColor(0, 253, 182) + .fogDensity(2.0F) + .plantsColor(0, 131, 145) + .waterAndFogColor(31, 167, 212) + .particles(EndParticles.SMARAGDANT, 0.001F); + } + + @Override + public BiomeSupplier getSupplier() { + return EmptySmaragdantCaveBiome.Biome::new; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/cave/EndCaveBiome.java b/src/main/java/org/betterx/betterend/world/biome/cave/EndCaveBiome.java new file mode 100644 index 00000000..df05f64a --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/cave/EndCaveBiome.java @@ -0,0 +1,185 @@ +package org.betterx.betterend.world.biome.cave; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder.BiomeSupplier; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeSettings; +import org.betterx.bclib.api.v3.levelgen.features.BCLFeature; +import org.betterx.bclib.api.v3.levelgen.features.BCLFeatureBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.bclib.util.WeightedList; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndBiomes; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.betterend.world.features.terrain.caves.CaveChunkPopulatorFeature; +import org.betterx.betterend.world.features.terrain.caves.CaveChunkPopulatorFeatureConfig; + +import com.mojang.datafixers.util.Function15; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.KeyDispatchDataCodec; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; + +import java.util.List; +import java.util.Optional; + +public class EndCaveBiome extends EndBiome { + public static final Codec CODEC = simpleCaveBiomeCodec(EndCaveBiome::new); + + public static Codec simpleCaveBiomeCodec(Function15, ResourceLocation, Optional>, Optional, Optional>, Optional, Boolean, SurfaceMaterialProvider, WeightedList>>, WeightedList>>, T> builder) { + return RecordCodecBuilder.create(instance -> + codecWithSettings( + instance, + Codec.BOOL.fieldOf("has_caves").orElse(true).forGetter(EndBiome::hasCaves), + SurfaceMaterialProvider.CODEC.fieldOf("surface") + .orElse(new DefaultSurfaceMaterialProvider()) + .forGetter(o -> o.surfMatProv), + WeightedList.listCodec(ConfiguredFeature.CODEC, "configured_features", "configured_feature") + .fieldOf("floor_features") + .forGetter(o -> (WeightedList) ((EndCaveBiome) o).floorFeatures), + WeightedList.listCodec(ConfiguredFeature.CODEC, "configured_features", "configured_feature") + .fieldOf("ceil_features") + .forGetter(o -> (WeightedList) ((EndCaveBiome) o).ceilFeatures) + ).apply(instance, builder) + ); + } + + public static final KeyDispatchDataCodec KEY_CODEC = KeyDispatchDataCodec.of(CODEC); + + @Override + public KeyDispatchDataCodec codec() { + return KEY_CODEC; + } + + protected EndCaveBiome( + float terrainHeight, + float fogDensity, + float genChance, + int edgeSize, + boolean vertical, + Optional edge, + ResourceLocation biomeID, + Optional> parameterPoints, + Optional biomeParent, + Optional> subbiomes, + Optional intendedType, + boolean hasCaves, + SurfaceMaterialProvider surface, + WeightedList>> floorFeatures, + WeightedList>> ceilFeatures + ) { + super( + terrainHeight, + fogDensity, + genChance, + edgeSize, + vertical, + edge, + biomeID, + parameterPoints, + biomeParent, + subbiomes, + intendedType, + hasCaves, + surface + ); + this.floorFeatures.addAll((WeightedList) floorFeatures); + this.ceilFeatures.addAll((WeightedList) ceilFeatures); + } + + public static abstract class Config extends EndBiome.Config { + protected Config(String name) { + super(name); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + + BCLFeature feature = BCLFeatureBuilder + .start( + BetterEnd.makeID(ID.getPath() + "_cave_populator"), + EndFeatures.CAVE_CHUNK_POPULATOR + ) + .configuration(new CaveChunkPopulatorFeatureConfig(ID)) + .buildAndRegister() + .place() + .decoration(GenerationStep.Decoration.UNDERGROUND_DECORATION) + .count(1) + .onlyInBiome() + .buildAndRegister(); + + builder.feature(feature) + .intendedType(EndBiomes.END_CAVE) + .music(EndSounds.MUSIC_CAVES) + .loop(EndSounds.AMBIENT_CAVES); + } + + @Override + protected boolean hasCaves() { + return false; + } + + @Override + protected boolean hasReturnGateway() { + return false; + } + + @Override + public BiomeSupplier getSupplier() { + return EndCaveBiome::new; + } + } + + private final WeightedList>> floorFeatures = new WeightedList<>(); + private final WeightedList>> ceilFeatures = new WeightedList<>(); + + public EndCaveBiome(ResourceLocation biomeID, Biome biome, BCLBiomeSettings settings) { + super(biomeID, biome, settings); + } + + public void addFloorFeature(Holder> feature, float weight) { + floorFeatures.add(feature, weight); + } + + public void addCeilFeature(Holder> feature, float weight) { + ceilFeatures.add(feature, weight); + } + + public Holder> getFloorFeature(RandomSource random) { + return floorFeatures.isEmpty() ? null : floorFeatures.get(random); + } + + public Holder> getCeilFeature(RandomSource random) { + return ceilFeatures.isEmpty() ? null : ceilFeatures.get(random); + } + + public float getFloorDensity() { + return 0; + } + + public float getCeilDensity() { + return 0; + } + + public BlockState getCeil(BlockPos pos) { + return null; + } + + public BlockState getWall(BlockPos pos) { + return null; + } + + public static EndCaveBiome create(EndBiome.Config biomeConfig) { + return (EndCaveBiome) EndBiome.create(biomeConfig); + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/cave/JadeCaveBiome.java b/src/main/java/org/betterx/betterend/world/biome/cave/JadeCaveBiome.java new file mode 100644 index 00000000..0cc08a86 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/cave/JadeCaveBiome.java @@ -0,0 +1,114 @@ +package org.betterx.betterend.world.biome.cave; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder.BiomeSupplier; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeSettings; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.bclib.util.WeightedList; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.world.biome.EndBiome; + +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.KeyDispatchDataCodec; +import net.minecraft.util.Mth; +import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; + +import java.util.List; +import java.util.Optional; + +public class JadeCaveBiome extends EndCaveBiome.Config { + public static final Codec CODEC = EndCaveBiome.simpleCaveBiomeCodec(JadeCaveBiome.Biome::new); + public static final KeyDispatchDataCodec KEY_CODEC = KeyDispatchDataCodec.of(CODEC); + + public static class Biome extends EndCaveBiome { + private static final OpenSimplexNoise WALL_NOISE = new OpenSimplexNoise("jade_cave".hashCode()); + private static final OpenSimplexNoise DEPTH_NOISE = new OpenSimplexNoise("depth_noise".hashCode()); + private static final BlockState[] JADE = new BlockState[3]; + + + public Biome(ResourceLocation biomeID, net.minecraft.world.level.biome.Biome biome, BCLBiomeSettings settings) { + super(biomeID, biome, settings); + + JADE[0] = EndBlocks.VIRID_JADESTONE.stone.defaultBlockState(); + JADE[1] = EndBlocks.AZURE_JADESTONE.stone.defaultBlockState(); + JADE[2] = EndBlocks.SANDY_JADESTONE.stone.defaultBlockState(); + } + + @Override + public KeyDispatchDataCodec codec() { + return JadeCaveBiome.KEY_CODEC; + } + + protected Biome( + float terrainHeight, + float fogDensity, + float genChance, + int edgeSize, + boolean vertical, + Optional edge, + ResourceLocation biomeID, + Optional> parameterPoints, + Optional biomeParent, + Optional> subbiomes, + Optional intendedType, + boolean hasCaves, + SurfaceMaterialProvider surface, + WeightedList>> floorFeatures, + WeightedList>> ceilFeatures + ) { + super( + terrainHeight, + fogDensity, + genChance, + edgeSize, + vertical, + edge, + biomeID, + parameterPoints, + biomeParent, + subbiomes, + intendedType, + hasCaves, + surface, + floorFeatures, + ceilFeatures + ); + } + + @Override + public BlockState getWall(BlockPos pos) { + double depth = DEPTH_NOISE.eval(pos.getX() * 0.02, pos.getZ() * 0.02) * 0.2 + 0.5; + int index = Mth.floor((pos.getY() + WALL_NOISE.eval( + pos.getX() * 0.2, + pos.getZ() * 0.2 + ) * 1.5) * depth + 0.5); + index = Mth.abs(index) % 3; + return JADE[index]; + } + } + + public JadeCaveBiome() { + super("jade_cave"); + } + + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + super.addCustomBuildData(builder); + builder.fogColor(118, 150, 112) + .fogDensity(2.0F) + .waterAndFogColor(95, 223, 255); + } + + @Override + public BiomeSupplier getSupplier() { + return JadeCaveBiome.Biome::new; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/cave/LushAuroraCaveBiome.java b/src/main/java/org/betterx/betterend/world/biome/cave/LushAuroraCaveBiome.java new file mode 100644 index 00000000..a32e9df9 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/cave/LushAuroraCaveBiome.java @@ -0,0 +1,134 @@ +package org.betterx.betterend.world.biome.cave; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder.BiomeSupplier; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeSettings; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.bclib.util.WeightedList; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.betterend.world.biome.EndBiome; + +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.KeyDispatchDataCodec; +import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; + +import java.util.List; +import java.util.Optional; + +public class LushAuroraCaveBiome extends EndCaveBiome.Config { + public static final Codec CODEC = EndCaveBiome.simpleCaveBiomeCodec(LushAuroraCaveBiome.Biome::new); + public static final KeyDispatchDataCodec KEY_CODEC = KeyDispatchDataCodec.of(CODEC); + + public static class Biome extends EndCaveBiome { + public Biome(ResourceLocation biomeID, net.minecraft.world.level.biome.Biome biome, BCLBiomeSettings settings) { + super(biomeID, biome, settings); + + this.addFloorFeature(EndFeatures.BIG_AURORA_CRYSTAL.configuredFeature, 1); + this.addFloorFeature(EndFeatures.CAVE_BUSH.configuredFeature, 5); + this.addFloorFeature(EndFeatures.CAVE_GRASS.configuredFeature, 40); + this.addFloorFeature(EndFeatures.END_STONE_STALAGMITE_CAVEMOSS.configuredFeature, 5); + + this.addCeilFeature(EndFeatures.CAVE_BUSH.configuredFeature, 1); + this.addCeilFeature(EndFeatures.CAVE_PUMPKIN.configuredFeature, 1); + this.addCeilFeature(EndFeatures.RUBINEA.configuredFeature, 3); + this.addCeilFeature(EndFeatures.MAGNULA.configuredFeature, 1); + this.addCeilFeature(EndFeatures.END_STONE_STALACTITE_CAVEMOSS.configuredFeature, 10); + } + + @Override + public KeyDispatchDataCodec codec() { + return LushAuroraCaveBiome.KEY_CODEC; + } + + protected Biome( + float terrainHeight, + float fogDensity, + float genChance, + int edgeSize, + boolean vertical, + Optional edge, + ResourceLocation biomeID, + Optional> parameterPoints, + Optional biomeParent, + Optional> subbiomes, + Optional intendedType, + boolean hasCaves, + SurfaceMaterialProvider surface, + WeightedList>> floorFeatures, + WeightedList>> ceilFeatures + ) { + super( + terrainHeight, + fogDensity, + genChance, + edgeSize, + vertical, + edge, + biomeID, + parameterPoints, + biomeParent, + subbiomes, + intendedType, + hasCaves, + surface, + floorFeatures, + ceilFeatures + ); + } + + @Override + public float getFloorDensity() { + return 0.2F; + } + + @Override + public float getCeilDensity() { + return 0.1F; + } + + @Override + public BlockState getCeil(BlockPos pos) { + return EndBlocks.CAVE_MOSS.defaultBlockState() + .setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.TOP); + } + } + + public LushAuroraCaveBiome() { + super("lush_aurora_cave"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + super.addCustomBuildData(builder); + builder.fogColor(150, 30, 68) + .fogDensity(2.0F) + .plantsColor(108, 25, 46) + .waterAndFogColor(186, 77, 237) + .particles(EndParticles.GLOWING_SPHERE, 0.001F) + ; + } + + @Override + public BiomeSupplier getSupplier() { + return LushAuroraCaveBiome.Biome::new; + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.CAVE_MOSS.defaultBlockState(); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/cave/LushSmaragdantCaveBiome.java b/src/main/java/org/betterx/betterend/world/biome/cave/LushSmaragdantCaveBiome.java new file mode 100644 index 00000000..68d6be94 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/cave/LushSmaragdantCaveBiome.java @@ -0,0 +1,120 @@ +package org.betterx.betterend.world.biome.cave; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder.BiomeSupplier; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeSettings; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.bclib.util.WeightedList; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.betterend.world.biome.EndBiome; + +import com.mojang.serialization.Codec; +import net.minecraft.core.Holder; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.KeyDispatchDataCodec; +import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; + +import java.util.List; +import java.util.Optional; + +public class LushSmaragdantCaveBiome extends EndCaveBiome.Config { + public static final Codec CODEC = EndCaveBiome.simpleCaveBiomeCodec( + LushSmaragdantCaveBiome.Biome::new); + public static final KeyDispatchDataCodec KEY_CODEC = KeyDispatchDataCodec.of(CODEC); + + public static class Biome extends EndCaveBiome { + public Biome(ResourceLocation biomeID, net.minecraft.world.level.biome.Biome biome, BCLBiomeSettings settings) { + super(biomeID, biome, settings); + + this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL.configuredFeature, 1); + this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL_SHARD.configuredFeature, 20); + + this.addCeilFeature(EndFeatures.END_STONE_STALACTITE.configuredFeature, 1); + } + + @Override + public KeyDispatchDataCodec codec() { + return LushSmaragdantCaveBiome.KEY_CODEC; + } + + protected Biome( + float terrainHeight, + float fogDensity, + float genChance, + int edgeSize, + boolean vertical, + Optional edge, + ResourceLocation biomeID, + Optional> parameterPoints, + Optional biomeParent, + Optional> subbiomes, + Optional intendedType, + boolean hasCaves, + SurfaceMaterialProvider surface, + WeightedList>> floorFeatures, + WeightedList>> ceilFeatures + ) { + super( + terrainHeight, + fogDensity, + genChance, + edgeSize, + vertical, + edge, + biomeID, + parameterPoints, + biomeParent, + subbiomes, + intendedType, + hasCaves, + surface, + floorFeatures, + ceilFeatures + ); + } + + @Override + public float getFloorDensity() { + return 0.1F; + } + + @Override + public float getCeilDensity() { + return 0.1F; + } + } + + public LushSmaragdantCaveBiome() { + super("lush_smaragdant_cave"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + super.addCustomBuildData(builder); + builder.fogColor(0, 253, 182) + .fogDensity(2.0F) + .plantsColor(0, 131, 145) + .waterAndFogColor(31, 167, 212) + .particles(EndParticles.SMARAGDANT, 0.001F); + } + + @Override + public BiomeSupplier getSupplier() { + return LushSmaragdantCaveBiome.Biome::new; + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.CAVE_MOSS.defaultBlockState(); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/AmberLandBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/AmberLandBiome.java new file mode 100644 index 00000000..4fcb9bb1 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/AmberLandBiome.java @@ -0,0 +1,52 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.*; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.tags.BiomeTags; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class AmberLandBiome extends EndBiome.Config { + public AmberLandBiome() { + super("amber_land"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .fogColor(255, 184, 71) + .fogDensity(2.0F) + .plantsColor(219, 115, 38) + .waterAndFogColor(145, 108, 72) + .music(EndSounds.MUSIC_FOREST) + .loop(EndSounds.AMBIENT_AMBER_LAND) + .particles(EndParticles.AMBER_SPHERE, 0.001F) + .feature(EndFeatures.AMBER_ORE) + .feature(EndFeatures.END_LAKE_RARE) + .feature(EndFeatures.HELIX_TREE) + .feature(EndFeatures.LANCELEAF) + .feature(EndFeatures.GLOW_PILLAR) + .feature(EndFeatures.AMBER_GRASS) + .feature(EndFeatures.AMBER_ROOT) + .feature(EndFeatures.BULB_MOSS) + .feature(EndFeatures.BULB_MOSS_WOOD) + .feature(EndFeatures.CHARNIA_ORANGE) + .feature(EndFeatures.CHARNIA_RED) + .structure(BiomeTags.HAS_END_CITY) + .spawn(EntityType.ENDERMAN, 50, 1, 4) + .spawn(EndEntities.END_SLIME, 30, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.AMBER_MOSS.defaultBlockState(); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/BlossomingSpiresBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/BlossomingSpiresBiome.java new file mode 100644 index 00000000..e24e66f1 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/BlossomingSpiresBiome.java @@ -0,0 +1,66 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndEntities; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class BlossomingSpiresBiome extends EndBiome.Config { + public BlossomingSpiresBiome() { + super("blossoming_spires"); + } + + @Override + protected boolean hasCaves() { + return false; + } + + @Override + protected boolean hasReturnGateway() { + return false; + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .fogColor(241, 146, 229) + .fogDensity(1.7F) + .plantsColor(122, 45, 122) + .music(EndSounds.MUSIC_FOREST) + .loop(EndSounds.AMBIENT_BLOSSOMING_SPIRES) + .feature(EndFeatures.SPIRE) + .feature(EndFeatures.FLOATING_SPIRE) + .feature(EndFeatures.TENANEA) + .feature(EndFeatures.TENANEA_BUSH) + .feature(EndFeatures.BULB_VINE) + .feature(EndFeatures.BUSHY_GRASS) + .feature(EndFeatures.BUSHY_GRASS_WG) + .feature(EndFeatures.BLOSSOM_BERRY) + .feature(EndFeatures.TWISTED_MOSS) + .feature(EndFeatures.TWISTED_MOSS_WOOD) + .feature(EndFeatures.SILK_MOTH_NEST) + .spawn(EntityType.ENDERMAN, 50, 1, 4) + .spawn(EndEntities.SILK_MOTH, 5, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.PINK_MOSS.defaultBlockState(); + } + + @Override + public BlockState getAltTopMaterial() { + return getTopMaterial(); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/ChorusForestBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/ChorusForestBiome.java new file mode 100644 index 00000000..a087f443 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/ChorusForestBiome.java @@ -0,0 +1,59 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndEntities; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.data.worldgen.placement.EndPlacements; +import net.minecraft.tags.BiomeTags; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.GenerationStep.Decoration; + +public class ChorusForestBiome extends EndBiome.Config { + public ChorusForestBiome() { + super("chorus_forest"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .fogColor(87, 26, 87) + .fogDensity(1.5F) + .plantsColor(122, 45, 122) + .waterAndFogColor(73, 30, 73) + .particles(ParticleTypes.PORTAL, 0.01F) + .loop(EndSounds.AMBIENT_CHORUS_FOREST) + .music(EndSounds.MUSIC_DARK) + .feature(EndFeatures.VIOLECITE_LAYER) + .feature(EndFeatures.END_LAKE_RARE) + .feature(EndFeatures.PYTHADENDRON_TREE) + .feature(EndFeatures.PYTHADENDRON_BUSH) + .feature(EndFeatures.PURPLE_POLYPORE) + .feature(Decoration.VEGETAL_DECORATION, EndPlacements.CHORUS_PLANT) + .feature(EndFeatures.CHORUS_GRASS) + .feature(EndFeatures.CHORUS_MUSHROOM) + .feature(EndFeatures.TAIL_MOSS) + .feature(EndFeatures.TAIL_MOSS_WOOD) + .feature(EndFeatures.CHARNIA_PURPLE) + .feature(EndFeatures.CHARNIA_RED_RARE) + .structure(BiomeTags.HAS_END_CITY) + .spawn(EndEntities.END_SLIME, 5, 1, 2) + .spawn(EntityType.ENDERMAN, 50, 1, 4); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.CHORUS_NYLIUM.defaultBlockState(); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/CrystalMountainsBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/CrystalMountainsBiome.java new file mode 100644 index 00000000..62c24dc2 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/CrystalMountainsBiome.java @@ -0,0 +1,59 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.SurfaceRuleBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.rules.SwitchRuleSource; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.betterend.world.surface.SplitNoiseCondition; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.SurfaceRules; + +import java.util.List; + +public class CrystalMountainsBiome extends EndBiome.Config { + public CrystalMountainsBiome() { + super("crystal_mountains"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .structure(EndStructures.MOUNTAIN) + .plantsColor(255, 133, 211) + .music(EndSounds.MUSIC_OPENSPACE) + .feature(EndFeatures.CRYSTAL_GRASS) + .spawn(EntityType.ENDERMAN, 50, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.CRYSTAL_MOSS.defaultBlockState(); + } + + @Override + public SurfaceRuleBuilder surface() { + SurfaceRules.RuleSource surfaceBlockRule = new SwitchRuleSource( + new SplitNoiseCondition(), + List.of( + SurfaceRules.state(EndBlocks.END_MOSS.defaultBlockState()), + SurfaceRules.state(Blocks.END_STONE.defaultBlockState()) + ) + ); + return super + .surface() + .rule(1, SurfaceRules.ifTrue(SurfaceRules.ON_FLOOR, surfaceBlockRule)); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/DragonGraveyardsBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/DragonGraveyardsBiome.java new file mode 100644 index 00000000..6cbf7183 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/DragonGraveyardsBiome.java @@ -0,0 +1,51 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class DragonGraveyardsBiome extends EndBiome.Config { + public DragonGraveyardsBiome() { + super("dragon_graveyards"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .genChance(0.1f) + .fogColor(244, 46, 79) + .fogDensity(1.3F) + .particles(EndParticles.FIREFLY, 0.0007F) + .music(EndSounds.MUSIC_OPENSPACE) + .loop(EndSounds.AMBIENT_GLOWING_GRASSLANDS) + .waterAndFogColor(203, 59, 167) + .plantsColor(244, 46, 79) + .feature(EndFeatures.OBSIDIAN_PILLAR_BASEMENT) + .feature(EndFeatures.DRAGON_BONE_BLOCK_ORE) + .feature(EndFeatures.FALLEN_PILLAR) + .feature(EndFeatures.OBSIDIAN_BOULDER) + .feature(EndFeatures.GIGANTIC_AMARANITA) + .feature(EndFeatures.LARGE_AMARANITA) + .feature(EndFeatures.SMALL_AMARANITA) + .feature(EndFeatures.GLOBULAGUS) + .feature(EndFeatures.CLAWFERN) + .spawn(EntityType.ENDERMAN, 50, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.SANGNUM.defaultBlockState(); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/DryShrublandBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/DryShrublandBiome.java new file mode 100644 index 00000000..99f832a8 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/DryShrublandBiome.java @@ -0,0 +1,45 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.tags.BiomeTags; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class DryShrublandBiome extends EndBiome.Config { + public DryShrublandBiome() { + super("dry_shrubland"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .fogColor(132, 35, 13) + .fogDensity(1.2F) + .waterAndFogColor(113, 88, 53) + .plantsColor(237, 122, 66) + .music(EndSounds.MUSIC_OPENSPACE) + .feature(EndFeatures.LUCERNIA_BUSH_RARE) + .feature(EndFeatures.ORANGO) + .feature(EndFeatures.AERIDIUM) + .feature(EndFeatures.LUTEBUS) + .feature(EndFeatures.LAMELLARIUM) + .structure(BiomeTags.HAS_END_CITY) + .spawn(EntityType.ENDERMAN, 50, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.RUTISCUS.defaultBlockState(); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/DustWastelandsBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/DustWastelandsBiome.java new file mode 100644 index 00000000..4be2f5f8 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/DustWastelandsBiome.java @@ -0,0 +1,57 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.SurfaceRuleBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.tags.BiomeTags; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.SurfaceRules; +import net.minecraft.world.level.levelgen.placement.CaveSurface; + +public class DustWastelandsBiome extends EndBiome.Config { + public DustWastelandsBiome() { + super("dust_wastelands"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .fogColor(226, 239, 168) + .fogDensity(2) + .waterAndFogColor(192, 180, 131) + .terrainHeight(1.5F) + .particles(ParticleTypes.WHITE_ASH, 0.01F) + .loop(EndSounds.AMBIENT_DUST_WASTELANDS) + .music(EndSounds.MUSIC_OPENSPACE) + .structure(BiomeTags.HAS_END_CITY) + .spawn(EntityType.ENDERMAN, 50, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.ENDSTONE_DUST.defaultBlockState(); + } + + @Override + public SurfaceRuleBuilder surface() { + return super + .surface() + .ceil(Blocks.END_STONE.defaultBlockState()) + .rule(4, SurfaceRules.ifTrue( + SurfaceRules.stoneDepthCheck(5, false, CaveSurface.FLOOR), + SurfaceRules.state(EndBlocks.ENDSTONE_DUST.defaultBlockState()) + )); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/FoggyMushroomlandBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/FoggyMushroomlandBiome.java new file mode 100644 index 00000000..2b07292d --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/FoggyMushroomlandBiome.java @@ -0,0 +1,66 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.*; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.tags.BiomeTags; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class FoggyMushroomlandBiome extends EndBiome.Config { + public FoggyMushroomlandBiome() { + super("foggy_mushroomland"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .structure(EndStructures.GIANT_MOSSY_GLOWSHROOM) + .plantsColor(73, 210, 209) + .fogColor(41, 122, 173) + .fogDensity(3) + .waterAndFogColor(119, 227, 250) + .particles(EndParticles.GLOWING_SPHERE, 0.001F) + .loop(EndSounds.AMBIENT_FOGGY_MUSHROOMLAND) + .music(EndSounds.MUSIC_FOREST) + .feature(EndFeatures.END_LAKE) + .feature(EndFeatures.MOSSY_GLOWSHROOM) + .feature(EndFeatures.BLUE_VINE) + .feature(EndFeatures.UMBRELLA_MOSS) + .feature(EndFeatures.CREEPING_MOSS) + .feature(EndFeatures.DENSE_VINE) + //.feature(EndFeatures.PEARLBERRY) + .feature(EndFeatures.CYAN_MOSS) + .feature(EndFeatures.CYAN_MOSS_WOOD) + .feature(EndFeatures.END_LILY) + .feature(EndFeatures.BUBBLE_CORAL) + .feature(EndFeatures.CHARNIA_CYAN) + .feature(EndFeatures.CHARNIA_LIGHT_BLUE) + .feature(EndFeatures.CHARNIA_RED_RARE) + .structure(BiomeTags.HAS_END_CITY) + .spawn(EndEntities.DRAGONFLY, 80, 2, 5) + .spawn(EndEntities.END_FISH, 20, 2, 5) + .spawn(EndEntities.CUBOZOA, 10, 3, 8) + .spawn(EndEntities.END_SLIME, 10, 1, 2) + .spawn(EntityType.ENDERMAN, 10, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.END_MOSS.defaultBlockState(); + } + + @Override + public BlockState getAltTopMaterial() { + return EndBlocks.END_MYCELIUM.defaultBlockState(); + } + }; + + + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/GlowingGrasslandsBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/GlowingGrasslandsBiome.java new file mode 100644 index 00000000..887240a6 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/GlowingGrasslandsBiome.java @@ -0,0 +1,56 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.tags.BiomeTags; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class GlowingGrasslandsBiome extends EndBiome.Config { + public GlowingGrasslandsBiome() { + super("glowing_grasslands"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .fogColor(99, 228, 247) + .fogDensity(1.3F) + .particles(EndParticles.FIREFLY, 0.001F) + .music(EndSounds.MUSIC_OPENSPACE) + .loop(EndSounds.AMBIENT_GLOWING_GRASSLANDS) + .waterAndFogColor(92, 250, 230) + .plantsColor(73, 210, 209) + .feature(EndFeatures.END_LAKE_RARE) + .feature(EndFeatures.LUMECORN) + .feature(EndFeatures.BLOOMING_COOKSONIA) + .feature(EndFeatures.SALTEAGO) + .feature(EndFeatures.VAIOLUSH_FERN) + .feature(EndFeatures.FRACTURN) + .feature(EndFeatures.UMBRELLA_MOSS_RARE) + .feature(EndFeatures.CREEPING_MOSS_RARE) + .feature(EndFeatures.TWISTED_UMBRELLA_MOSS_RARE) + .feature(EndFeatures.CHARNIA_CYAN) + .feature(EndFeatures.CHARNIA_GREEN) + .feature(EndFeatures.CHARNIA_LIGHT_BLUE) + .feature(EndFeatures.CHARNIA_RED_RARE) + .structure(BiomeTags.HAS_END_CITY) + .spawn(EntityType.ENDERMAN, 50, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.END_MOSS.defaultBlockState(); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/LanternWoodsBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/LanternWoodsBiome.java new file mode 100644 index 00000000..900d60db --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/LanternWoodsBiome.java @@ -0,0 +1,56 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.tags.BiomeTags; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class LanternWoodsBiome extends EndBiome.Config { + public LanternWoodsBiome() { + super("lantern_woods"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .fogColor(189, 82, 70) + .fogDensity(1.1F) + .waterAndFogColor(171, 234, 226) + .plantsColor(254, 85, 57) + .music(EndSounds.MUSIC_FOREST) + .particles(EndParticles.GLOWING_SPHERE, 0.001F) + .feature(EndFeatures.END_LAKE_NORMAL) + .feature(EndFeatures.FLAMAEA) + .feature(EndFeatures.LUCERNIA) + .feature(EndFeatures.LUCERNIA_BUSH) + .feature(EndFeatures.FILALUX) + .feature(EndFeatures.AERIDIUM) + .feature(EndFeatures.LAMELLARIUM) + .feature(EndFeatures.BOLUX_MUSHROOM) + .feature(EndFeatures.AURANT_POLYPORE) + .feature(EndFeatures.POND_ANEMONE) + .feature(EndFeatures.CHARNIA_ORANGE) + .feature(EndFeatures.CHARNIA_RED) + .feature(EndFeatures.RUSCUS) + .feature(EndFeatures.RUSCUS_WOOD) + .structure(BiomeTags.HAS_END_CITY) + .spawn(EntityType.ENDERMAN, 50, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.RUTISCUS.defaultBlockState(); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/MegalakeBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/MegalakeBiome.java new file mode 100644 index 00000000..d25390c0 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/MegalakeBiome.java @@ -0,0 +1,59 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.*; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class MegalakeBiome extends EndBiome.Config { + public MegalakeBiome() { + super("megalake"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .structure(EndStructures.MEGALAKE) + .plantsColor(73, 210, 209) + .fogColor(178, 209, 248) + .waterAndFogColor(96, 163, 255) + .fogDensity(1.75F) + .music(EndSounds.MUSIC_WATER) + .loop(EndSounds.AMBIENT_MEGALAKE) + .terrainHeight(0F) + .feature(EndFeatures.END_LOTUS) + .feature(EndFeatures.END_LOTUS_LEAF) + .feature(EndFeatures.BUBBLE_CORAL_RARE) + .feature(EndFeatures.END_LILY_RARE) + .feature(EndFeatures.UMBRELLA_MOSS) + .feature(EndFeatures.CREEPING_MOSS) + //.feature(EndFeatures.PEARLBERRY) + .feature(EndFeatures.CHARNIA_CYAN) + .feature(EndFeatures.CHARNIA_LIGHT_BLUE) + .feature(EndFeatures.CHARNIA_RED_RARE) + .feature(EndFeatures.MENGER_SPONGE) + .spawn(EndEntities.DRAGONFLY, 50, 1, 3) + .spawn(EndEntities.END_FISH, 50, 3, 8) + .spawn(EndEntities.CUBOZOA, 50, 3, 8) + .spawn(EndEntities.END_SLIME, 5, 1, 2) + .spawn(EntityType.ENDERMAN, 10, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.END_MOSS.defaultBlockState(); + } + + @Override + public BlockState getAltTopMaterial() { + return EndBlocks.ENDSTONE_DUST.defaultBlockState(); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/MegalakeGroveBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/MegalakeGroveBiome.java new file mode 100644 index 00000000..4ad52a8b --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/MegalakeGroveBiome.java @@ -0,0 +1,56 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.*; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class MegalakeGroveBiome extends EndBiome.Config { + public MegalakeGroveBiome() { + super("megalake_grove"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .structure(EndStructures.MEGALAKE_SMALL) + .plantsColor(73, 210, 209) + .fogColor(178, 209, 248) + .waterAndFogColor(96, 163, 255) + .fogDensity(2.0F) + .particles(EndParticles.GLOWING_SPHERE, 0.001F) + .music(EndSounds.MUSIC_WATER) + .loop(EndSounds.AMBIENT_MEGALAKE_GROVE) + .terrainHeight(0F) + .feature(EndFeatures.LACUGROVE) + .feature(EndFeatures.END_LOTUS) + .feature(EndFeatures.END_LOTUS_LEAF) + .feature(EndFeatures.BUBBLE_CORAL_RARE) + .feature(EndFeatures.END_LILY_RARE) + .feature(EndFeatures.UMBRELLA_MOSS) + //.feature(EndFeatures.PEARLBERRY) + .feature(EndFeatures.CREEPING_MOSS) + .feature(EndFeatures.CHARNIA_CYAN) + .feature(EndFeatures.CHARNIA_LIGHT_BLUE) + .feature(EndFeatures.CHARNIA_RED_RARE) + .feature(EndFeatures.MENGER_SPONGE) + .spawn(EndEntities.DRAGONFLY, 20, 1, 3) + .spawn(EndEntities.END_FISH, 20, 3, 8) + .spawn(EndEntities.CUBOZOA, 50, 3, 8) + .spawn(EndEntities.END_SLIME, 5, 1, 2) + .spawn(EntityType.ENDERMAN, 10, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.END_MOSS.defaultBlockState(); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/NeonOasisBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/NeonOasisBiome.java new file mode 100644 index 00000000..3a42f01a --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/NeonOasisBiome.java @@ -0,0 +1,83 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.SurfaceRuleBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.rules.SwitchRuleSource; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.betterend.world.surface.SplitNoiseCondition; + +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.tags.BiomeTags; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.SurfaceRules; +import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource; +import net.minecraft.world.level.levelgen.placement.CaveSurface; + +import java.util.List; + +public class NeonOasisBiome extends EndBiome.Config { + public NeonOasisBiome() { + super("neon_oasis"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .genChance(0.5F) + .fogColor(226, 239, 168) + .fogDensity(2) + .waterAndFogColor(106, 238, 215) + .particles(ParticleTypes.WHITE_ASH, 0.01F) + .loop(EndSounds.AMBIENT_DUST_WASTELANDS) + .music(EndSounds.MUSIC_OPENSPACE) + .feature(EndFeatures.DESERT_LAKE) + .feature(EndFeatures.NEON_CACTUS) + .feature(EndFeatures.UMBRELLA_MOSS) + .feature(EndFeatures.CREEPING_MOSS) + .feature(EndFeatures.CHARNIA_CYAN) + .feature(EndFeatures.CHARNIA_GREEN) + .feature(EndFeatures.CHARNIA_RED) + .structure(BiomeTags.HAS_END_CITY) + .spawn(EntityType.ENDERMAN, 50, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.ENDSTONE_DUST.defaultBlockState(); + } + + @Override + public BlockState getAltTopMaterial() { + return EndBlocks.END_MOSS.defaultBlockState(); + } + + @Override + public SurfaceRuleBuilder surface() { + RuleSource surfaceBlockRule = new SwitchRuleSource( + new SplitNoiseCondition(), + List.of( + SurfaceRules.state(EndBlocks.ENDSTONE_DUST.defaultBlockState()), + SurfaceRules.state(EndBlocks.END_MOSS.defaultBlockState()) + ) + ); + return super + .surface() + .ceil(Blocks.END_STONE.defaultBlockState()) + .rule(1, SurfaceRules.ifTrue(SurfaceRules.ON_FLOOR, surfaceBlockRule)) + .rule(4, SurfaceRules.ifTrue( + SurfaceRules.stoneDepthCheck(5, false, CaveSurface.FLOOR), + SurfaceRules.state(EndBlocks.ENDSTONE_DUST.defaultBlockState()) + )); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/PaintedMountainsBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/PaintedMountainsBiome.java new file mode 100644 index 00000000..d2cc0fde --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/PaintedMountainsBiome.java @@ -0,0 +1,60 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.SurfaceRuleBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.rules.SwitchRuleSource; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.betterend.world.surface.VerticalBandNoiseCondition; + +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.SurfaceRules; + +import java.util.List; + +public class PaintedMountainsBiome extends EndBiome.Config { + public PaintedMountainsBiome() { + super("painted_mountains"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .structure(EndStructures.PAINTED_MOUNTAIN) + .fogColor(226, 239, 168) + .fogDensity(2) + .waterAndFogColor(192, 180, 131) + .music(EndSounds.MUSIC_OPENSPACE) + .loop(EndSounds.AMBIENT_DUST_WASTELANDS) + .particles(ParticleTypes.WHITE_ASH, 0.01F) + .spawn(EntityType.ENDERMAN, 50, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.ENDSTONE_DUST.defaultBlockState(); + } + + public SurfaceRuleBuilder surface() { + SurfaceRules.RuleSource surfaceBlockRule = new SwitchRuleSource( + VerticalBandNoiseCondition.DEFAULT, + List.of( + SurfaceRules.state(Blocks.END_STONE.defaultBlockState()), + SurfaceRules.state(EndBlocks.FLAVOLITE.stone.defaultBlockState()), + SurfaceRules.state(EndBlocks.VIOLECITE.stone.defaultBlockState()) + ) + ); + return SurfaceRuleBuilder.start().rule(9, surfaceBlockRule); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/ShadowForestBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/ShadowForestBiome.java new file mode 100644 index 00000000..aafe2d6b --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/ShadowForestBiome.java @@ -0,0 +1,60 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndEntities; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.tags.BiomeTags; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class ShadowForestBiome extends EndBiome.Config { + public ShadowForestBiome() { + super("shadow_forest"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .fogColor(0, 0, 0) + .fogDensity(2.5F) + .plantsColor(45, 45, 45) + .waterAndFogColor(42, 45, 80) + .particles(ParticleTypes.MYCELIUM, 0.01F) + .loop(EndSounds.AMBIENT_CHORUS_FOREST) + .music(EndSounds.MUSIC_DARK) + .feature(EndFeatures.VIOLECITE_LAYER) + .feature(EndFeatures.END_LAKE_RARE) + .feature(EndFeatures.DRAGON_TREE) + .feature(EndFeatures.DRAGON_TREE_BUSH) + .feature(EndFeatures.SHADOW_PLANT) + .feature(EndFeatures.MURKWEED) + .feature(EndFeatures.NEEDLEGRASS) + .feature(EndFeatures.SHADOW_BERRY) + .feature(EndFeatures.TWISTED_VINE) + .feature(EndFeatures.PURPLE_POLYPORE) + .feature(EndFeatures.TAIL_MOSS) + .feature(EndFeatures.TAIL_MOSS_WOOD) + .feature(EndFeatures.CHARNIA_PURPLE) + .feature(EndFeatures.CHARNIA_RED_RARE) + .structure(BiomeTags.HAS_END_CITY) + .spawn(EndEntities.SHADOW_WALKER, 80, 2, 4) + .spawn(EntityType.ENDERMAN, 40, 1, 4) + .spawn(EntityType.PHANTOM, 1, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.SHADOW_GRASS.defaultBlockState(); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/SulphurSpringsBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/SulphurSpringsBiome.java new file mode 100644 index 00000000..b619b422 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/SulphurSpringsBiome.java @@ -0,0 +1,96 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.SurfaceRuleBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.rules.SwitchRuleSource; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.*; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.betterend.world.surface.SulphuricSurfaceNoiseCondition; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.SurfaceRules; +import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource; +import net.minecraft.world.level.levelgen.placement.CaveSurface; + +import java.util.List; + +public class SulphurSpringsBiome extends EndBiome.Config { + public SulphurSpringsBiome() { + super("sulphur_springs"); + } + + @Override + protected boolean hasCaves() { + return false; + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .music(EndSounds.MUSIC_OPENSPACE) + .loop(EndSounds.AMBIENT_SULPHUR_SPRINGS) + .waterColor(25, 90, 157) + .waterFogColor(30, 65, 61) + .fogColor(207, 194, 62) + .fogDensity(1.5F) + .terrainHeight(0F) + .particles(EndParticles.SULPHUR_PARTICLE, 0.001F) + .feature(EndFeatures.GEYSER) + .feature(EndFeatures.SURFACE_VENT) + .feature(EndFeatures.SULPHURIC_LAKE) + .feature(EndFeatures.SULPHURIC_CAVE) + .feature(EndFeatures.HYDRALUX) + .feature(EndFeatures.CHARNIA_GREEN) + .feature(EndFeatures.CHARNIA_ORANGE) + .feature(EndFeatures.CHARNIA_RED_RARE) + .spawn(EndEntities.END_FISH, 50, 3, 8) + .spawn(EndEntities.CUBOZOA, 50, 3, 8) + .spawn(EntityType.ENDERMAN, 50, 1, 4); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.FLAVOLITE.stone.defaultBlockState(); + } + + @Override + public BlockState getAltTopMaterial() { + return Blocks.END_STONE.defaultBlockState(); + } + + @Override + public boolean generateFloorRule() { + return false; + } + + @Override + public SurfaceRuleBuilder surface() { + RuleSource surfaceBlockRule = new SwitchRuleSource( + new SulphuricSurfaceNoiseCondition(), + List.of( + SurfaceRules.state(surfaceMaterial().getAltTopMaterial()), + SurfaceRules.state(surfaceMaterial().getTopMaterial()), + SULPHURIC_ROCK, + BRIMSTONE + ) + ); + return super + .surface() + .rule(2, SurfaceRules.ifTrue(SurfaceRules.ON_FLOOR, surfaceBlockRule)) + .rule( + 2, + SurfaceRules.ifTrue( + SurfaceRules.stoneDepthCheck(5, false, CaveSurface.FLOOR), + surfaceBlockRule + ) + ); + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/UmbraValleyBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/UmbraValleyBiome.java new file mode 100644 index 00000000..9ff06046 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/UmbraValleyBiome.java @@ -0,0 +1,94 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.SurfaceRuleBuilder; +import org.betterx.bclib.api.v2.levelgen.surface.rules.SwitchRuleSource; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.betterend.world.surface.UmbraSurfaceNoiseCondition; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.SurfaceRules; + +import java.util.List; + +public class UmbraValleyBiome extends EndBiome.Config { + private static final Block[] SURFACE_BLOCKS = new Block[]{ + EndBlocks.PALLIDIUM_FULL, + EndBlocks.PALLIDIUM_HEAVY, + EndBlocks.PALLIDIUM_THIN, + EndBlocks.PALLIDIUM_TINY, + EndBlocks.UMBRALITH.stone + }; + + public UmbraValleyBiome() { + super("umbra_valley"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .fogColor(100, 100, 100) + .plantsColor(172, 189, 190) + .waterAndFogColor(69, 104, 134) + .particles(EndParticles.AMBER_SPHERE, 0.0001F) + .loop(EndSounds.UMBRA_VALLEY) + .music(EndSounds.MUSIC_DARK) + .feature(EndFeatures.UMBRALITH_ARCH) + .feature(EndFeatures.THIN_UMBRALITH_ARCH) + .feature(EndFeatures.INFLEXIA) + .feature(EndFeatures.FLAMMALIX); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.UMBRALITH.stone.defaultBlockState(); + } + + @Override + public BlockState getUnderMaterial() { + return EndBlocks.UMBRALITH.stone.defaultBlockState(); + } + + @Override + public BlockState getAltTopMaterial() { + return EndBlocks.PALLIDIUM_FULL.defaultBlockState(); + } + + @Override + public boolean generateFloorRule() { + return false; + } + + @Override + public SurfaceRuleBuilder surface() { + return super.surface() + .rule(2, SurfaceRules.ifTrue( + SurfaceRules.ON_FLOOR, + new SwitchRuleSource( + new UmbraSurfaceNoiseCondition(), + List.of( + SurfaceRules.state(surfaceMaterial().getAltTopMaterial()), + PALLIDIUM_HEAVY, + PALLIDIUM_THIN, + PALLIDIUM_TINY, + SurfaceRules.state(surfaceMaterial().getTopMaterial()) + ) + ) + )); + } + }; + } + + public static Block getSurface(int x, int z) { + return SURFACE_BLOCKS[UmbraSurfaceNoiseCondition.getDepth(x, z)]; + } +} diff --git a/src/main/java/org/betterx/betterend/world/biome/land/UmbrellaJungleBiome.java b/src/main/java/org/betterx/betterend/world/biome/land/UmbrellaJungleBiome.java new file mode 100644 index 00000000..fe7077fc --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/biome/land/UmbrellaJungleBiome.java @@ -0,0 +1,60 @@ +package org.betterx.betterend.world.biome.land; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; +import org.betterx.bclib.interfaces.SurfaceMaterialProvider; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.registry.EndParticles; +import org.betterx.betterend.registry.EndSounds; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.tags.BiomeTags; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class UmbrellaJungleBiome extends EndBiome.Config { + public UmbrellaJungleBiome() { + super("umbrella_jungle"); + } + + @Override + protected void addCustomBuildData(BCLBiomeBuilder builder) { + builder + .fogColor(87, 223, 221) + .waterAndFogColor(119, 198, 253) + .foliageColor(27, 183, 194) + .fogDensity(2.3F) + .particles(EndParticles.JUNGLE_SPORE, 0.001F) + .music(EndSounds.MUSIC_FOREST) + .loop(EndSounds.AMBIENT_UMBRELLA_JUNGLE) + .feature(EndFeatures.END_LAKE) + .feature(EndFeatures.UMBRELLA_TREE) + .feature(EndFeatures.JELLYSHROOM) + .feature(EndFeatures.TWISTED_UMBRELLA_MOSS) + .feature(EndFeatures.SMALL_JELLYSHROOM_FLOOR) + .feature(EndFeatures.JUNGLE_GRASS) + .feature(EndFeatures.CYAN_MOSS) + .feature(EndFeatures.CYAN_MOSS_WOOD) + .feature(EndFeatures.JUNGLE_FERN_WOOD) + .feature(EndFeatures.SMALL_JELLYSHROOM_WALL) + .feature(EndFeatures.SMALL_JELLYSHROOM_WOOD) + .feature(EndFeatures.SMALL_JELLYSHROOM_CEIL) + .feature(EndFeatures.JUNGLE_VINE) + .feature(EndFeatures.CHARNIA_CYAN) + .feature(EndFeatures.CHARNIA_GREEN) + .feature(EndFeatures.CHARNIA_LIGHT_BLUE) + .feature(EndFeatures.CHARNIA_RED_RARE) + .structure(BiomeTags.HAS_END_CITY) + .spawn(EntityType.ENDERMAN, 50, 1, 2); + } + + @Override + protected SurfaceMaterialProvider surfaceMaterial() { + return new EndBiome.DefaultSurfaceMaterialProvider() { + @Override + public BlockState getTopMaterial() { + return EndBlocks.JUNGLE_MOSS.defaultBlockState(); + } + }; + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/world/features/BiomeIslandFeature.java b/src/main/java/org/betterx/betterend/world/features/BiomeIslandFeature.java new file mode 100644 index 00000000..f35beb91 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/BiomeIslandFeature.java @@ -0,0 +1,73 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFTranslate; +import org.betterx.bclib.sdf.primitive.SDFCappedCone; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class BiomeIslandFeature extends DefaultFeature { + private static final MutableBlockPos CENTER = new MutableBlockPos(); + private static final SDF ISLAND; + + private static OpenSimplexNoise simplexNoise = new OpenSimplexNoise(412L); + private static BlockState topBlock = Blocks.GRASS_BLOCK.defaultBlockState(); + private static BlockState underBlock = Blocks.DIRT.defaultBlockState(); + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + //Holder biome = world.getBiome(pos); + int dist = BlocksHelper.downRay(world, pos, 10) + 1; + BlockPos surfacePos = new BlockPos(pos.getX(), pos.getY() - dist, pos.getZ()); + BlockState topMaterial = EndBiome.findTopMaterial(world, surfacePos); + + if (BlocksHelper.isFluid(topMaterial)) { + topBlock = Blocks.GRAVEL.defaultBlockState(); + underBlock = Blocks.STONE.defaultBlockState(); + } else { + underBlock = EndBiome.findUnderMaterial(world, surfacePos); + } + + simplexNoise = new OpenSimplexNoise(world.getSeed()); + CENTER.set(pos); + ISLAND.fillRecursive(world, pos.below()); + return true; + } + + private static SDF createSDFIsland() { + SDF sdfCone = new SDFCappedCone().setRadius1(0).setRadius2(6).setHeight(4).setBlock(pos -> { + if (pos.getY() > CENTER.getY()) return AIR; + if (pos.getY() == CENTER.getY()) return topBlock; + return underBlock; + }); + sdfCone = new SDFTranslate().setTranslate(0, -2, 0).setSource(sdfCone); + sdfCone = new SDFDisplacement().setFunction(pos -> { + float deltaX = Math.abs(pos.x()); + float deltaY = Math.abs(pos.y()); + float deltaZ = Math.abs(pos.z()); + if (deltaY < 2.0f && (deltaX < 3.0f || deltaZ < 3.0F)) return 0.0f; + return (float) simplexNoise.eval(CENTER.getX() + pos.x(), CENTER.getY() + pos.y(), CENTER.getZ() + pos.z()); + }) + .setSource(sdfCone) + .setReplaceFunction(state -> BlocksHelper.isFluid(state) || state.getMaterial() + .isReplaceable()); + return sdfCone; + } + + static { + ISLAND = createSDFIsland(); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/BlueVineFeature.java b/src/main/java/org/betterx/betterend/world/features/BlueVineFeature.java new file mode 100644 index 00000000..31d77cc9 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/BlueVineFeature.java @@ -0,0 +1,51 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; + +public class BlueVineFeature extends ScatterFeature { + private boolean small; + + public BlueVineFeature() { + super(ScatterFeatureConfig.CODEC); + } + + @Override + @SuppressWarnings("deprecation") + public boolean canGenerate( + ScatterFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ) { + float d = MHelper.length( + center.getX() - blockPos.getX(), + center.getZ() - blockPos.getZ() + ) / radius * 0.6F + random.nextFloat() * 0.4F; + small = d > 0.5F; + return EndBlocks.BLUE_VINE_SEED.canSurvive(DefaultFeature.AIR, world, blockPos); + } + + @Override + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + if (small) { + BlocksHelper.setWithoutUpdate( + world, + blockPos, + EndBlocks.BLUE_VINE_SEED.defaultBlockState().setValue(EndPlantWithAgeBlock.AGE, random.nextInt(4)) + ); + } else { + EndPlantWithAgeBlock seed = ((EndPlantWithAgeBlock) EndBlocks.BLUE_VINE_SEED); + seed.growAdult(world, random, blockPos); + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/BuildingListFeature.java b/src/main/java/org/betterx/betterend/world/features/BuildingListFeature.java new file mode 100644 index 00000000..6085e89b --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/BuildingListFeature.java @@ -0,0 +1,145 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.util.StructureHelper; +import org.betterx.betterend.util.LootTableUtil; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.ChestBlock; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorType; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; + +import org.jetbrains.annotations.Nullable; + +public class BuildingListFeature extends NBTFeature { + private StructureInfo selected; + + public BuildingListFeature() { + super(BuildingListFeatureConfig.CODEC); + + } + + @Override + protected void addStructureData(StructurePlaceSettings data) { + data.addProcessor(new ChestProcessor()); + } + + @Override + protected StructureTemplate getStructure( + BuildingListFeatureConfig cfg, + WorldGenLevel world, + BlockPos pos, + RandomSource random + ) { + selected = cfg.getRandom(random); + return selected.getStructure(); + } + + @Override + protected boolean canSpawn(WorldGenLevel world, BlockPos pos, RandomSource random) { + int cx = pos.getX() >> 4; + int cz = pos.getZ() >> 4; + return ((cx + cz) & 1) == 0 && pos.getY() > 58 + && world.getBlockState(pos).isAir() + && world.getBlockState(pos.below()).is(CommonBlockTags.TERRAIN); + } + + @Override + protected Rotation getRotation(WorldGenLevel world, BlockPos pos, RandomSource random) { + return Rotation.getRandom(random); + } + + @Override + protected Mirror getMirror(WorldGenLevel world, BlockPos pos, RandomSource random) { + return Mirror.values()[random.nextInt(3)]; + } + + @Override + protected int getYOffset(StructureTemplate structure, WorldGenLevel world, BlockPos pos, RandomSource random) { + return selected.offsetY; + } + + @Override + protected TerrainMerge getTerrainMerge(WorldGenLevel world, BlockPos pos, RandomSource random) { + return selected.terrainMerge; + } + + public static final class StructureInfo { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + Codec.STRING.fieldOf("path").forGetter(o -> o.structurePath), + Codec.INT.fieldOf("offset_y").forGetter(o -> o.offsetY), + TerrainMerge.CODEC.fieldOf("terrain_merger").forGetter(o -> o.terrainMerge) + ) + .apply(instance, StructureInfo::new)); + public final TerrainMerge terrainMerge; + public final String structurePath; + public final int offsetY; + + private StructureTemplate structure; + + public StructureInfo(String structurePath, int offsetY, TerrainMerge terrainMerge) { + this.terrainMerge = terrainMerge; + this.structurePath = structurePath; + this.offsetY = offsetY; + } + + public StructureTemplate getStructure() { + if (structure == null) { + structure = StructureHelper.readStructure(structurePath); + } + return structure; + } + } + + class ChestProcessor extends StructureProcessor { + @Nullable + @Override + public StructureTemplate.StructureBlockInfo processBlock( + LevelReader levelReader, + BlockPos blockPos, + BlockPos blockPos2, + StructureBlockInfo structureBlockInfo, + StructureBlockInfo structureBlockInfo2, + StructurePlaceSettings structurePlaceSettings + ) { + BlockState blockState = structureBlockInfo2.state; + if (blockState.getBlock() instanceof ChestBlock) { + RandomSource random = structurePlaceSettings.getRandom(structureBlockInfo2.pos); + BlockPos chestPos = structureBlockInfo2.pos; + ChestBlock chestBlock = (ChestBlock) blockState.getBlock(); + BlockEntity entity = chestBlock.newBlockEntity(chestPos, blockState); + levelReader.getChunk(chestPos).setBlockEntity(entity); + RandomizableContainerBlockEntity chestEntity = (RandomizableContainerBlockEntity) entity; + Holder biome = levelReader.getNoiseBiome( + chestPos.getX() >> 2, + chestPos.getY() >> 2, + chestPos.getZ() >> 2 + ); + chestEntity.setLootTable(LootTableUtil.getTable(biome), random.nextLong()); + chestEntity.setChanged(); + } + return structureBlockInfo2; + } + + @Override + protected StructureProcessorType getType() { + return StructureProcessorType.NOP; + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/BuildingListFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/BuildingListFeatureConfig.java new file mode 100644 index 00000000..bf17c8d5 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/BuildingListFeatureConfig.java @@ -0,0 +1,31 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.util.ExtraCodecs; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.List; + +public class BuildingListFeatureConfig extends NBTFeatureConfig { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + ExtraCodecs.nonEmptyList(BuildingListFeature.StructureInfo.CODEC.listOf()) + .fieldOf("structures") + .forGetter(a -> a.list), + BlockState.CODEC.fieldOf("default").forGetter(o -> o.defaultBlock) + ) + .apply(instance, BuildingListFeatureConfig::new) + ); + protected final List list; + + public BuildingListFeatureConfig(List list, BlockState defaultBlock) { + super(defaultBlock); + this.list = list; + } + + public BuildingListFeature.StructureInfo getRandom(RandomSource random) { + return this.list.get(random.nextInt(this.list.size())); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/CavePumpkinFeature.java b/src/main/java/org/betterx/betterend/world/features/CavePumpkinFeature.java new file mode 100644 index 00000000..8be48cf8 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/CavePumpkinFeature.java @@ -0,0 +1,43 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.blocks.EndBlockProperties; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class CavePumpkinFeature extends DefaultFeature { + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.above()) + .is(CommonBlockTags.GEN_END_STONES) || !world.isEmptyBlock(pos) || !world.isEmptyBlock( + pos.below())) { + return false; + } + + int age = random.nextInt(4); + BlocksHelper.setWithoutUpdate( + world, + pos, + EndBlocks.CAVE_PUMPKIN_SEED.defaultBlockState().setValue(EndBlockProperties.AGE, age) + ); + if (age > 1) { + BlocksHelper.setWithoutUpdate( + world, + pos.below(), + EndBlocks.CAVE_PUMPKIN.defaultBlockState().setValue(EndBlockProperties.SMALL, age < 3) + ); + } + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/CharniaFeature.java b/src/main/java/org/betterx/betterend/world/features/CharniaFeature.java new file mode 100644 index 00000000..4e115604 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/CharniaFeature.java @@ -0,0 +1,8 @@ +package org.betterx.betterend.world.features; + +public class CharniaFeature extends UnderwaterPlantFeature { + @Override + protected int getChance() { + return 3; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/CrashedShipFeature.java b/src/main/java/org/betterx/betterend/world/features/CrashedShipFeature.java new file mode 100644 index 00000000..37b78739 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/CrashedShipFeature.java @@ -0,0 +1,153 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.StructureErode; +import org.betterx.bclib.util.StructureHelper; +import org.betterx.betterend.util.BlockFixer; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.templatesystem.*; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; +import net.minecraft.world.level.material.Material; + +public class CrashedShipFeature extends NBTFeature { + private static final StructureProcessor REPLACER; + private static final String STRUCTURE_PATH = "/data/minecraft/structures/end_city/ship.nbt"; + private StructureTemplate structure; + + public CrashedShipFeature() { + super(NBTFeatureConfig.CODEC); + } + + @Override + protected StructureTemplate getStructure( + NBTFeatureConfig cfg, + WorldGenLevel world, + BlockPos pos, + RandomSource random + ) { + if (structure == null) { + structure = world.getLevel().getStructureManager().getOrCreate(new ResourceLocation("end_city/ship")); + if (structure == null) { + structure = StructureHelper.readStructure(STRUCTURE_PATH); + } + } + return structure; + } + + @Override + protected boolean canSpawn(WorldGenLevel world, BlockPos pos, RandomSource random) { + long x = pos.getX() >> 4; + long z = pos.getX() >> 4; + if (x * x + z * z < 3600) { + return false; + } + return pos.getY() > 5 && world.getBlockState(pos.below()).is(CommonBlockTags.GEN_END_STONES); + } + + @Override + protected Rotation getRotation(WorldGenLevel world, BlockPos pos, RandomSource random) { + return Rotation.getRandom(random); + } + + @Override + protected Mirror getMirror(WorldGenLevel world, BlockPos pos, RandomSource random) { + return Mirror.values()[random.nextInt(3)]; + } + + @Override + protected int getYOffset(StructureTemplate structure, WorldGenLevel world, BlockPos pos, RandomSource random) { + int min = structure.getSize().getY() >> 3; + int max = structure.getSize().getY() >> 2; + return -MHelper.randRange(min, max, random); + } + + @Override + protected TerrainMerge getTerrainMerge(WorldGenLevel world, BlockPos pos, RandomSource random) { + return TerrainMerge.NONE; + } + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + BlockPos center = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + center = new BlockPos(((center.getX() >> 4) << 4) | 8, 128, ((center.getZ() >> 4) << 4) | 8); + center = getGround(world, center); + BoundingBox bounds = makeBox(center); + + if (!canSpawn(world, center, random)) { + return false; + } + + StructureTemplate structure = getStructure(featureConfig.config(), world, center, random); + Rotation rotation = getRotation(world, center, random); + Mirror mirror = getMirror(world, center, random); + BlockPos offset = StructureTemplate.transform( + new BlockPos(structure.getSize()), + mirror, + rotation, + BlockPos.ZERO + ); + center = center.offset(0, getYOffset(structure, world, center, random) + 0.5, 0); + StructurePlaceSettings placementData = new StructurePlaceSettings().setRotation(rotation).setMirror(mirror); + center = center.offset(-offset.getX() * 0.5, 0, -offset.getZ() * 0.5); + + BoundingBox structB = structure.getBoundingBox(placementData, center); + bounds = StructureHelper.intersectBoxes(bounds, structB); + + addStructureData(placementData); + structure.placeInWorld(world, center, center, placementData.setBoundingBox(bounds), random, 2); + + StructureErode.erodeIntense(world, bounds, random); + BlockFixer.fixBlocks( + world, + new BlockPos(bounds.minX(), bounds.minY(), bounds.minZ()), + new BlockPos(bounds.maxX(), bounds.maxY(), bounds.maxZ()) + ); + + return true; + } + + @Override + protected void addStructureData(StructurePlaceSettings data) { + data.addProcessor(BlockIgnoreProcessor.STRUCTURE_AND_AIR).addProcessor(REPLACER).setIgnoreEntities(true); + } + + static { + REPLACER = new StructureProcessor() { + @Override + public StructureBlockInfo processBlock( + LevelReader worldView, + BlockPos pos, + BlockPos blockPos, + StructureBlockInfo structureBlockInfo, + StructureBlockInfo structureBlockInfo2, + StructurePlaceSettings structurePlacementData + ) { + BlockState state = structureBlockInfo2.state; + if (state.is(Blocks.SPAWNER) || state.getMaterial().equals(Material.WOOL)) { + return new StructureBlockInfo(structureBlockInfo2.pos, DefaultFeature.AIR, null); + } + return structureBlockInfo2; + } + + @Override + protected StructureProcessorType getType() { + return StructureProcessorType.NOP; + } + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/DoublePlantFeature.java b/src/main/java/org/betterx/betterend/world/features/DoublePlantFeature.java new file mode 100644 index 00000000..9662207f --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/DoublePlantFeature.java @@ -0,0 +1,54 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.blocks.BaseDoublePlantBlock; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; + +public class DoublePlantFeature extends ScatterFeature { + private BlockState plant; + + public DoublePlantFeature() { + super(DoublePlantFeatureConfig.CODEC); + + } + + @Override + public boolean canGenerate( + DoublePlantFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ) { + float d = MHelper.length( + center.getX() - blockPos.getX(), + center.getZ() - blockPos.getZ() + ) / radius * 0.6F + random.nextFloat() * 0.4F; + plant = d < 0.5F ? cfg.getLargePlantState(random, blockPos) : cfg.getSmallPlantState(random, blockPos); + //noinspection deprecation + return plant.getBlock().canSurvive(plant, world, blockPos); + } + + @Override + public void generate( + DoublePlantFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos blockPos + ) { + if (plant.getBlock() instanceof BaseDoublePlantBlock) { + int rot = random.nextInt(4); + BlockState state = plant.setValue(BaseDoublePlantBlock.ROTATION, rot); + BlocksHelper.setWithoutUpdate(world, blockPos, state); + BlocksHelper.setWithoutUpdate(world, blockPos.above(), state.setValue(BaseDoublePlantBlock.TOP, true)); + } else { + BlocksHelper.setWithoutUpdate(world, blockPos, plant); + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/DoublePlantFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/DoublePlantFeatureConfig.java new file mode 100644 index 00000000..46914627 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/DoublePlantFeatureConfig.java @@ -0,0 +1,44 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +public class DoublePlantFeatureConfig extends ScatterFeatureConfig { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("small_state").forGetter(o -> o.smallPlant), + BlockStateProvider.CODEC.fieldOf("large_state").forGetter(o -> o.largePlant), + Codec.INT.fieldOf("radius").forGetter(o -> o.radius) + ) + .apply( + instance, + DoublePlantFeatureConfig::new + )); + + public final BlockStateProvider smallPlant; + public final BlockStateProvider largePlant; + + public DoublePlantFeatureConfig(Block smallPlant, Block largePlant, int radius) { + this(SimpleStateProvider.simple(smallPlant), SimpleStateProvider.simple(largePlant), radius); + } + + public DoublePlantFeatureConfig(BlockStateProvider smallPlant, BlockStateProvider largePlant, int radius) { + super(radius); + this.smallPlant = smallPlant; + this.largePlant = largePlant; + } + + BlockState getLargePlantState(RandomSource rnd, BlockPos pos) { + return largePlant.getState(rnd, pos); + } + + BlockState getSmallPlantState(RandomSource rnd, BlockPos pos) { + return smallPlant.getState(rnd, pos); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/EndLilyFeature.java b/src/main/java/org/betterx/betterend/world/features/EndLilyFeature.java new file mode 100644 index 00000000..cb2ec6a0 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/EndLilyFeature.java @@ -0,0 +1,25 @@ +package org.betterx.betterend.world.features; + +import org.betterx.betterend.blocks.EndLilySeedBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; + +public class EndLilyFeature extends UnderwaterPlantScatter { + public EndLilyFeature() { + super(ScatterFeatureConfig.CODEC); + } + + @Override + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + EndLilySeedBlock seed = (EndLilySeedBlock) EndBlocks.END_LILY_SEED; + seed.grow(world, random, blockPos); + } + + @Override + protected int getChance() { + return 15; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/EndLotusFeature.java b/src/main/java/org/betterx/betterend/world/features/EndLotusFeature.java new file mode 100644 index 00000000..f89cc0a9 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/EndLotusFeature.java @@ -0,0 +1,25 @@ +package org.betterx.betterend.world.features; + +import org.betterx.betterend.blocks.EndLotusSeedBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; + +public class EndLotusFeature extends UnderwaterPlantScatter { + public EndLotusFeature() { + super(ScatterFeatureConfig.CODEC); + } + + @Override + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + EndLotusSeedBlock seed = (EndLotusSeedBlock) EndBlocks.END_LOTUS_SEED; + seed.grow(world, random, blockPos); + } + + @Override + protected int getChance() { + return 15; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/EndLotusLeafFeature.java b/src/main/java/org/betterx/betterend/world/features/EndLotusLeafFeature.java new file mode 100644 index 00000000..e86fea94 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/EndLotusLeafFeature.java @@ -0,0 +1,88 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.blocks.EndLotusLeafBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +public class EndLotusLeafFeature extends ScatterFeature { + public EndLotusLeafFeature() { + super(ScatterFeatureConfig.CODEC); + } + + @Override + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + if (canGenerate(world, blockPos)) { + generateLeaf(world, blockPos); + } + } + + @Override + protected int getChance() { + return 15; + } + + @Override + protected BlockPos getCenterGround(ScatterFeatureConfig cfg, WorldGenLevel world, BlockPos pos) { + return DefaultFeature.getPosOnSurface(world, pos); + } + + private void generateLeaf(WorldGenLevel world, BlockPos pos) { + MutableBlockPos p = new MutableBlockPos(); + BlockState leaf = EndBlocks.END_LOTUS_LEAF.defaultBlockState(); + BlocksHelper.setWithoutUpdate(world, pos, leaf.setValue(EndLotusLeafBlock.SHAPE, TripleShape.BOTTOM)); + for (Direction move : BlocksHelper.HORIZONTAL) { + BlocksHelper.setWithoutUpdate( + world, + p.set(pos).move(move), + leaf.setValue(EndLotusLeafBlock.HORIZONTAL_FACING, move) + .setValue(EndLotusLeafBlock.SHAPE, TripleShape.MIDDLE) + ); + } + for (int i = 0; i < 4; i++) { + Direction d1 = BlocksHelper.HORIZONTAL[i]; + Direction d2 = BlocksHelper.HORIZONTAL[(i + 1) & 3]; + BlocksHelper.setWithoutUpdate( + world, + p.set(pos).move(d1).move(d2), + leaf.setValue(EndLotusLeafBlock.HORIZONTAL_FACING, d1) + .setValue(EndLotusLeafBlock.SHAPE, TripleShape.TOP) + ); + } + } + + private boolean canGenerate(WorldGenLevel world, BlockPos pos) { + MutableBlockPos p = new MutableBlockPos(); + p.setY(pos.getY()); + int count = 0; + for (int x = -1; x < 2; x++) { + p.setX(pos.getX() + x); + for (int z = -1; z < 2; z++) { + p.setZ(pos.getZ() + z); + if (world.isEmptyBlock(p) && world.getBlockState(p.below()).is(Blocks.WATER)) count++; + } + } + return count == 9; + } + + @Override + public boolean canGenerate( + ScatterFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ) { + return world.isEmptyBlock(blockPos) && world.getBlockState(blockPos.below()).is(Blocks.WATER); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/FilaluxFeature.java b/src/main/java/org/betterx/betterend/world/features/FilaluxFeature.java new file mode 100644 index 00000000..a99abc16 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/FilaluxFeature.java @@ -0,0 +1,43 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; + +public class FilaluxFeature extends SkyScatterFeature { + @Override + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + BlockState vine = EndBlocks.FILALUX.defaultBlockState(); + BlockState wings = EndBlocks.FILALUX_WINGS.defaultBlockState(); + BlocksHelper.setWithoutUpdate(world, blockPos, EndBlocks.FILALUX_LANTERN); + BlocksHelper.setWithoutUpdate( + world, + blockPos.above(), + wings.setValue(BlockStateProperties.FACING, Direction.UP) + ); + for (Direction dir : BlocksHelper.HORIZONTAL) { + BlocksHelper.setWithoutUpdate( + world, + blockPos.relative(dir), + wings.setValue(BlockStateProperties.FACING, dir) + ); + } + int length = MHelper.randRange(1, 3, random); + for (int i = 1; i <= length; i++) { + TripleShape shape = length > 1 ? TripleShape.TOP : TripleShape.BOTTOM; + if (i > 1) { + shape = i == length ? TripleShape.BOTTOM : TripleShape.MIDDLE; + } + BlocksHelper.setWithoutUpdate(world, blockPos.below(i), vine.setValue(BlockProperties.TRIPLE_SHAPE, shape)); + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/FullHeightScatterFeature.java b/src/main/java/org/betterx/betterend/world/features/FullHeightScatterFeature.java new file mode 100644 index 00000000..d67c315f --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/FullHeightScatterFeature.java @@ -0,0 +1,65 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.util.GlobalState; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public abstract class FullHeightScatterFeature extends DefaultFeature { + private final int radius; + + public FullHeightScatterFeature(int radius) { + this.radius = radius; + } + + public abstract boolean canGenerate( + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ); + + public abstract void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos); + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final MutableBlockPos POS = GlobalState.stateForThread().POS; + final RandomSource random = featureConfig.random(); + final BlockPos center = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + int maxY = world.getHeight(Heightmap.Types.WORLD_SURFACE_WG, center.getX(), center.getZ()); + int minY = BlocksHelper.upRay(world, new BlockPos(center.getX(), 0, center.getZ()), maxY); + for (int y = maxY; y > minY; y--) { + POS.set(center.getX(), y, center.getZ()); + if (world.getBlockState(POS).isAir() && !world.getBlockState(POS.below()).isAir()) { + float r = MHelper.randRange(radius * 0.5F, radius, random); + int count = MHelper.floor(r * r * MHelper.randRange(1.5F, 3F, random)); + for (int i = 0; i < count; i++) { + float pr = r * (float) Math.sqrt(random.nextFloat()); + float theta = random.nextFloat() * MHelper.PI2; + float x = pr * (float) Math.cos(theta); + float z = pr * (float) Math.sin(theta); + + POS.set(center.getX() + x, y + 5, center.getZ() + z); + int down = BlocksHelper.downRay(world, POS, 16); + if (down > 10) continue; + POS.setY(POS.getY() - down); + + if (canGenerate(world, random, center, POS, r)) { + generate(world, random, POS); + } + } + } + } + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/GlowPillarFeature.java b/src/main/java/org/betterx/betterend/world/features/GlowPillarFeature.java new file mode 100644 index 00000000..b0034e7a --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/GlowPillarFeature.java @@ -0,0 +1,41 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; + +public class GlowPillarFeature extends ScatterFeature { + public GlowPillarFeature() { + super(ScatterFeatureConfig.CODEC); + } + + @Override + public boolean canGenerate( + ScatterFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ) { + //noinspection deprecation + return EndBlocks.GLOWING_PILLAR_SEED.canSurvive(DefaultFeature.AIR, world, blockPos); + } + + @Override + public void generate( + ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos + ) { + EndPlantWithAgeBlock seed = ((EndPlantWithAgeBlock) EndBlocks.GLOWING_PILLAR_SEED); + seed.growAdult(world, random, blockPos); + } + + @Override + protected int getChance() { + return 10; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/HydraluxFeature.java b/src/main/java/org/betterx/betterend/world/features/HydraluxFeature.java new file mode 100644 index 00000000..440a7511 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/HydraluxFeature.java @@ -0,0 +1,25 @@ +package org.betterx.betterend.world.features; + +import org.betterx.betterend.blocks.HydraluxSaplingBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; + +public class HydraluxFeature extends UnderwaterPlantScatter { + public HydraluxFeature() { + super(ScatterFeatureConfig.CODEC); + } + + @Override + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + HydraluxSaplingBlock seed = (HydraluxSaplingBlock) EndBlocks.HYDRALUX_SAPLING; + seed.grow(world, random, blockPos); + } + + @Override + protected int getChance() { + return 15; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/InvertedScatterFeature.java b/src/main/java/org/betterx/betterend/world/features/InvertedScatterFeature.java new file mode 100644 index 00000000..3bb7e353 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/InvertedScatterFeature.java @@ -0,0 +1,67 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.util.GlobalState; + +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; + +public abstract class InvertedScatterFeature extends Feature { + + + public InvertedScatterFeature(Codec codec) { + super(codec); + } + + public abstract boolean canGenerate( + FC cfg, + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ); + + public abstract void generate(FC cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos); + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + FC cfg = featureConfig.config(); + final MutableBlockPos POS = GlobalState.stateForThread().POS; + final RandomSource random = featureConfig.random(); + final BlockPos center = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + int maxY = world.getHeight(Heightmap.Types.WORLD_SURFACE, center.getX(), center.getZ()); + int minY = BlocksHelper.upRay(world, new BlockPos(center.getX(), 0, center.getZ()), maxY); + for (int y = maxY; y > minY; y--) { + POS.set(center.getX(), y, center.getZ()); + if (world.getBlockState(POS).isAir() && !world.getBlockState(POS.above()).isAir()) { + float r = MHelper.randRange(cfg.radius * 0.5F, cfg.radius, random); + int count = MHelper.floor(r * r * MHelper.randRange(0.5F, 1.5F, random)); + for (int i = 0; i < count; i++) { + float pr = r * (float) Math.sqrt(random.nextFloat()); + float theta = random.nextFloat() * MHelper.PI2; + float x = pr * (float) Math.cos(theta); + float z = pr * (float) Math.sin(theta); + + POS.set(center.getX() + x, center.getY() - 7, center.getZ() + z); + int up = BlocksHelper.upRay(world, POS, 16); + if (up > 14) continue; + POS.setY(POS.getY() + up); + + if (canGenerate(cfg, world, random, center, POS, r)) { + generate(cfg, world, random, POS); + } + } + } + } + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/LanceleafFeature.java b/src/main/java/org/betterx/betterend/world/features/LanceleafFeature.java new file mode 100644 index 00000000..d4fc631a --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/LanceleafFeature.java @@ -0,0 +1,39 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; + +public class LanceleafFeature extends ScatterFeature { + public LanceleafFeature() { + super(ScatterFeatureConfig.CODEC); + } + + @Override + public boolean canGenerate( + ScatterFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ) { + //noinspection deprecation + return EndBlocks.LANCELEAF_SEED.canSurvive(DefaultFeature.AIR, world, blockPos); + } + + @Override + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + EndPlantWithAgeBlock seed = ((EndPlantWithAgeBlock) EndBlocks.LANCELEAF_SEED); + seed.growAdult(world, random, blockPos); + } + + @Override + protected int getChance() { + return 5; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/MengerSpongeFeature.java b/src/main/java/org/betterx/betterend/world/features/MengerSpongeFeature.java new file mode 100644 index 00000000..6bac370e --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/MengerSpongeFeature.java @@ -0,0 +1,42 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.function.Function; + +public class MengerSpongeFeature extends UnderwaterPlantScatter { + private static final Function REPLACE; + + public MengerSpongeFeature() { + super(ScatterFeatureConfig.CODEC); + } + + @Override + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + BlocksHelper.setWithoutUpdate(world, blockPos, EndBlocks.MENGER_SPONGE_WET); + if (random.nextBoolean()) { + for (Direction dir : BlocksHelper.DIRECTIONS) { + BlockPos pos = blockPos.relative(dir); + if (REPLACE.apply(world.getBlockState(pos))) { + BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.MENGER_SPONGE_WET); + } + } + } + } + + static { + REPLACE = (state) -> { + if (state.is(EndBlocks.END_LOTUS_STEM)) { + return false; + } + return !state.getFluidState().isEmpty() || state.getMaterial().isReplaceable(); + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/NBTFeature.java b/src/main/java/org/betterx/betterend/world/features/NBTFeature.java new file mode 100644 index 00000000..d9e47c48 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/NBTFeature.java @@ -0,0 +1,245 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.api.v2.levelgen.structures.templatesystem.DestructionStructureProcessor; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.core.Vec3i; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtIo; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.RandomSource; +import net.minecraft.util.StringRepresentable; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; + +import java.io.IOException; +import java.io.InputStream; + +public abstract class NBTFeature extends Feature { + public NBTFeature(Codec codec) { + super(codec); + } + + protected static final DestructionStructureProcessor DESTRUCTION = new DestructionStructureProcessor(); + + protected abstract StructureTemplate getStructure(FC cfg, WorldGenLevel world, BlockPos pos, RandomSource random); + + protected abstract boolean canSpawn(WorldGenLevel world, BlockPos pos, RandomSource random); + + protected abstract Rotation getRotation(WorldGenLevel world, BlockPos pos, RandomSource random); + + protected abstract Mirror getMirror(WorldGenLevel world, BlockPos pos, RandomSource random); + + protected abstract int getYOffset( + StructureTemplate structure, + WorldGenLevel world, + BlockPos pos, + RandomSource random + ); + + protected abstract TerrainMerge getTerrainMerge(WorldGenLevel world, BlockPos pos, RandomSource random); + + protected abstract void addStructureData(StructurePlaceSettings data); + + protected BlockPos getGround(WorldGenLevel world, BlockPos center) { + Holder biome = world.getBiome(center); + ResourceLocation id = BiomeAPI.getBiomeID(biome); + if (id.getNamespace().contains("moutain") || id.getNamespace().contains("lake")) { + int y = getAverageY(world, center); + return new BlockPos(center.getX(), y, center.getZ()); + } else { + int y = getAverageYWG(world, center); + return new BlockPos(center.getX(), y, center.getZ()); + } + } + + protected int getAverageY(WorldGenLevel world, BlockPos center) { + int y = DefaultFeature.getYOnSurface(world, center.getX(), center.getZ()); + y += DefaultFeature.getYOnSurface(world, center.getX() - 2, center.getZ() - 2); + y += DefaultFeature.getYOnSurface(world, center.getX() + 2, center.getZ() - 2); + y += DefaultFeature.getYOnSurface(world, center.getX() - 2, center.getZ() + 2); + y += DefaultFeature.getYOnSurface(world, center.getX() + 2, center.getZ() + 2); + return y / 5; + } + + protected int getAverageYWG(WorldGenLevel world, BlockPos center) { + int y = DefaultFeature.getYOnSurfaceWG(world, center.getX(), center.getZ()); + y += DefaultFeature.getYOnSurfaceWG(world, center.getX() - 2, center.getZ() - 2); + y += DefaultFeature.getYOnSurfaceWG(world, center.getX() + 2, center.getZ() - 2); + y += DefaultFeature.getYOnSurfaceWG(world, center.getX() - 2, center.getZ() + 2); + y += DefaultFeature.getYOnSurfaceWG(world, center.getX() + 2, center.getZ() + 2); + return y / 5; + } + + @Override + public boolean place(FeaturePlaceContext context) { + FC cfg = context.config(); + WorldGenLevel world = context.level(); + RandomSource random = context.random(); + BlockPos center = context.origin(); + + center = new BlockPos(((center.getX() >> 4) << 4) | 8, 128, ((center.getZ() >> 4) << 4) | 8); + center = getGround(world, center); + + if (!canSpawn(world, center, random)) { + return false; + } + + int posY = center.getY() + 1; + StructureTemplate structure = getStructure(cfg, world, center, random); + Rotation rotation = getRotation(world, center, random); + Mirror mirror = getMirror(world, center, random); + BlockPos offset = StructureTemplate.transform( + new BlockPos(structure.getSize()), + mirror, + rotation, + BlockPos.ZERO + ); + center = center.offset(0, getYOffset(structure, world, center, random) + 0.5, 0); + + BoundingBox bounds = makeBox(center); + StructurePlaceSettings placementData = new StructurePlaceSettings() + .setRotation(rotation) + .setMirror(mirror) + .setBoundingBox(bounds); + addStructureData(placementData); + center = center.offset(-offset.getX() * 0.5, 0, -offset.getZ() * 0.5); + structure.placeInWorld(world, center, center, placementData, random, 4); + + TerrainMerge merge = getTerrainMerge(world, center, random); + int x1 = center.getX(); + int z1 = center.getZ(); + int x2 = x1 + offset.getX(); + int z2 = z1 + offset.getZ(); + if (merge != TerrainMerge.NONE) { + MutableBlockPos mut = new MutableBlockPos(); + + if (x2 < x1) { + int a = x1; + x1 = x2; + x2 = a; + } + + if (z2 < z1) { + int a = z1; + z1 = z2; + z2 = a; + } + + int surfMax = posY - 1; + for (int x = x1; x <= x2; x++) { + mut.setX(x); + for (int z = z1; z <= z2; z++) { + mut.setZ(z); + mut.setY(surfMax); + BlockState state = world.getBlockState(mut); + if (!isTerrain(state) && state.isFaceSturdy(world, mut, Direction.DOWN)) { + for (int i = 0; i < 10; i++) { + mut.setY(mut.getY() - 1); + BlockState stateSt = world.getBlockState(mut); + if (!isTerrain(stateSt)) { + if (merge == TerrainMerge.SURFACE) { + boolean isTop = mut.getY() == surfMax && state.getMaterial().isSolidBlocking(); + Holder b = world.getBiome(mut); + BlockState top = (isTop + ? BiomeAPI.findTopMaterial(b) + : BiomeAPI.findUnderMaterial(b)).orElse(cfg.defaultBlock); + BlocksHelper.setWithoutUpdate(world, mut, top); + } else { + BlocksHelper.setWithoutUpdate(world, mut, state); + } + } else { + if (isTerrain(state) && state.getMaterial().isSolidBlocking()) { + if (merge == TerrainMerge.SURFACE) { + Holder b = world.getBiome(mut); + BlockState bottom = BiomeAPI.findUnderMaterial(b).orElse(cfg.defaultBlock); + BlocksHelper.setWithoutUpdate(world, mut, bottom); + } else { + BlocksHelper.setWithoutUpdate(world, mut, state); + } + } + break; + } + } + } + } + } + } + //BlocksHelper.fixBlocks(world, new BlockPos(x1, center.getY(), z1), new BlockPos(x2, center.getY() + offset.getY(), z2)); + + return true; + } + + private boolean isTerrain(BlockState state) { + return state.is(CommonBlockTags.END_STONES) || state.is(CommonBlockTags.NETHER_STONES); + } + + protected BoundingBox makeBox(BlockPos pos) { + int sx = ((pos.getX() >> 4) << 4) - 16; + int sz = ((pos.getZ() >> 4) << 4) - 16; + int ex = sx + 47; + int ez = sz + 47; + return BoundingBox.fromCorners(new Vec3i(sx, 0, sz), new Vec3i(ex, 255, ez)); + } + + protected static StructureTemplate readStructure(ResourceLocation resource) { + String ns = resource.getNamespace(); + String nm = resource.getPath(); + + try { + InputStream inputstream = MinecraftServer.class.getResourceAsStream("/data/" + ns + "/structures/" + nm + ".nbt"); + return readStructureFromStream(inputstream); + } catch (IOException e) { + e.printStackTrace(); + } + + return null; + } + + private static StructureTemplate readStructureFromStream(InputStream stream) throws IOException { + CompoundTag nbttagcompound = NbtIo.readCompressed(stream); + + StructureTemplate template = new StructureTemplate(); + template.load(nbttagcompound); + + return template; + } + + public enum TerrainMerge implements StringRepresentable { + NONE, SURFACE, OBJECT; + + public static final Codec CODEC = StringRepresentable.fromEnum(TerrainMerge::values); + + public static TerrainMerge getFromString(String type) { + if (type.equals("surface")) { + return SURFACE; + } else if (type.equals("object")) { + return OBJECT; + } else { + return NONE; + } + } + + @Override + public String getSerializedName() { + return this.name(); + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/NBTFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/NBTFeatureConfig.java new file mode 100644 index 00000000..1552b7d0 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/NBTFeatureConfig.java @@ -0,0 +1,20 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; + +public class NBTFeatureConfig implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockState.CODEC.fieldOf("default").forGetter(o -> o.defaultBlock) + ) + .apply(instance, NBTFeatureConfig::new) + ); + public final BlockState defaultBlock; + + public NBTFeatureConfig(BlockState defaultBlock) { + this.defaultBlock = defaultBlock; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/NeonCactusFeature.java b/src/main/java/org/betterx/betterend/world/features/NeonCactusFeature.java new file mode 100644 index 00000000..8bd90cb3 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/NeonCactusFeature.java @@ -0,0 +1,30 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.betterend.blocks.NeonCactusPlantBlock; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class NeonCactusFeature extends DefaultFeature { + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + BlockState ground = world.getBlockState(pos.below()); + if (!ground.is(EndBlocks.ENDSTONE_DUST) && !ground.is(EndBlocks.END_MOSS)) { + return false; + } + + NeonCactusPlantBlock cactus = ((NeonCactusPlantBlock) EndBlocks.NEON_CACTUS); + cactus.growPlant(world, pos, random); + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/ScatterFeature.java b/src/main/java/org/betterx/betterend/world/features/ScatterFeature.java new file mode 100644 index 00000000..fbbcd779 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/ScatterFeature.java @@ -0,0 +1,96 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.util.GlobalState; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; + +public abstract class ScatterFeature extends Feature { + public ScatterFeature(Codec codec) { + super(codec); + } + + public abstract boolean canGenerate( + FC cfg, + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ); + + public abstract void generate(FC cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos); + + protected BlockPos getCenterGround(FC cfg, WorldGenLevel world, BlockPos pos) { + return DefaultFeature.getPosOnSurfaceWG(world, pos); + } + + protected boolean canSpawn(FC cfg, WorldGenLevel world, BlockPos pos) { + if (pos.getY() < 5) { + return false; + } else return world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES); + } + + protected boolean getGroundPlant(FC cfg, WorldGenLevel world, MutableBlockPos pos) { + int down = BlocksHelper.downRay(world, pos, 16); + if (down > Math.abs(getYOffset() * 2)) { + return false; + } + pos.setY(pos.getY() - down); + return true; + } + + protected int getYOffset() { + return 5; + } + + protected int getChance() { + return 1; + } + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + FC cfg = featureConfig.config(); + final MutableBlockPos POS = GlobalState.stateForThread().POS; + final RandomSource random = featureConfig.random(); + BlockPos center = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + center = getCenterGround(cfg, world, center); + + if (!canSpawn(cfg, world, center)) { + return false; + } + + float r = MHelper.randRange(cfg.radius * 0.5F, cfg.radius, random); + int count = MHelper.floor(r * r * MHelper.randRange(1.5F, 3F, random)); + for (int i = 0; i < count; i++) { + float pr = r * (float) Math.sqrt(random.nextFloat()); + float theta = random.nextFloat() * MHelper.PI2; + float x = pr * (float) Math.cos(theta); + float z = pr * (float) Math.sin(theta); + + POS.set(center.getX() + x, center.getY() + getYOffset(), center.getZ() + z); + if (getGroundPlant(cfg, world, POS) && canGenerate( + cfg, + world, + random, + center, + POS, + r + ) && (getChance() < 2 || random.nextInt(getChance()) == 0)) { + generate(cfg, world, random, POS); + } + } + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/ScatterFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/ScatterFeatureConfig.java new file mode 100644 index 00000000..99c7e6ae --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/ScatterFeatureConfig.java @@ -0,0 +1,35 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; + +public class ScatterFeatureConfig implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + Codec.INT.fieldOf("radius").forGetter(o -> o.radius) + ) + .apply(instance, ScatterFeatureConfig::new)); + + public final int radius; + + public ScatterFeatureConfig(int radius) { + this.radius = radius; + } + + public static ScatterFeatureConfig blueVine() { + return new ScatterFeatureConfig(5); + } + + public static ScatterFeatureConfig filalux() { + return new ScatterFeatureConfig(10); + } + + public static ScatterFeatureConfig glowPillar() { + return new ScatterFeatureConfig(9); + } + + public static ScatterFeatureConfig lanceleaf() { + return new ScatterFeatureConfig(7); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/SilkMothNestFeature.java b/src/main/java/org/betterx/betterend/world/features/SilkMothNestFeature.java new file mode 100644 index 00000000..492ba320 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/SilkMothNestFeature.java @@ -0,0 +1,67 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.util.GlobalState; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class SilkMothNestFeature extends DefaultFeature { + private boolean canGenerate(WorldGenLevel world, BlockPos pos) { + BlockState state = world.getBlockState(pos.above()); + if (state.is(BlockTags.LEAVES) || state.is(BlockTags.LOGS)) { + state = world.getBlockState(pos); + if ((state.isAir() || state.is(EndBlocks.TENANEA_OUTER_LEAVES)) && world.isEmptyBlock(pos.below())) { + for (Direction dir : BlocksHelper.HORIZONTAL) { + return !world.getBlockState(pos.below().relative(dir)).getMaterial().blocksMotion(); + } + } + } + return false; + } + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final MutableBlockPos POS = GlobalState.stateForThread().POS; + final RandomSource random = featureConfig.random(); + final BlockPos center = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + int maxY = world.getHeight(Heightmap.Types.WORLD_SURFACE, center.getX(), center.getZ()); + int minY = BlocksHelper.upRay(world, new BlockPos(center.getX(), 0, center.getZ()), maxY); + POS.set(center); + for (int y = maxY; y > minY; y--) { + POS.setY(y); + if (canGenerate(world, POS)) { + Direction dir = BlocksHelper.randomHorizontal(random); + BlocksHelper.setWithoutUpdate( + world, + POS, + EndBlocks.SILK_MOTH_NEST.defaultBlockState() + .setValue(BlockStateProperties.HORIZONTAL_FACING, dir) + .setValue(BlockProperties.ACTIVE, false) + ); + POS.setY(y - 1); + BlocksHelper.setWithoutUpdate( + world, + POS, + EndBlocks.SILK_MOTH_NEST.defaultBlockState() + .setValue(BlockStateProperties.HORIZONTAL_FACING, dir) + ); + return true; + } + } + return false; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/SingleInvertedScatterFeature.java b/src/main/java/org/betterx/betterend/world/features/SingleInvertedScatterFeature.java new file mode 100644 index 00000000..b76495ec --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/SingleInvertedScatterFeature.java @@ -0,0 +1,48 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.blocks.BaseAttachedBlock; +import org.betterx.bclib.util.BlocksHelper; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; + +public class SingleInvertedScatterFeature extends InvertedScatterFeature { + private BlockState block; + + public SingleInvertedScatterFeature() { + super(SinglePlantFeatureConfig.CODEC); + } + + @Override + public boolean canGenerate( + SinglePlantFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ) { + if (!world.isEmptyBlock(blockPos)) { + return false; + } + block = cfg.getPlantState(random, blockPos); + BlockState state = block; + if (block.getBlock() instanceof BaseAttachedBlock) { + state = state.setValue(BlockStateProperties.FACING, Direction.DOWN); + } + return state.canSurvive(world, blockPos); + } + + @Override + public void generate(SinglePlantFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + BlockState state = block; + if (block.getBlock() instanceof BaseAttachedBlock) { + state = state.setValue(BlockStateProperties.FACING, Direction.DOWN); + } + BlocksHelper.setWithoutUpdate(world, blockPos, state); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/SinglePlantFeature.java b/src/main/java/org/betterx/betterend/world/features/SinglePlantFeature.java new file mode 100644 index 00000000..30500466 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/SinglePlantFeature.java @@ -0,0 +1,61 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.blocks.BaseCropBlock; +import org.betterx.bclib.blocks.BaseDoublePlantBlock; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; + +public class SinglePlantFeature extends ScatterFeature { + + BlockState plant; + + public SinglePlantFeature() { + super(SinglePlantFeatureConfig.CODEC); + } + + @Override + protected BlockPos getCenterGround(SinglePlantFeatureConfig cfg, WorldGenLevel world, BlockPos pos) { + return cfg.rawHeightmap + ? DefaultFeature.getPosOnSurfaceWG(world, pos) + : DefaultFeature.getPosOnSurface(world, pos); + } + + @Override + public boolean canGenerate( + SinglePlantFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ) { + this.plant = cfg.getPlantState(random, blockPos); + //noinspection deprecation + return plant.getBlock().canSurvive(plant, world, blockPos); + } + + @Override + public void generate(SinglePlantFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + if (this.plant.getBlock() instanceof BaseDoublePlantBlock) { + int rot = random.nextInt(4); + BlockState state = this.plant.setValue(BaseDoublePlantBlock.ROTATION, rot); + BlocksHelper.setWithoutUpdate(world, blockPos, state); + BlocksHelper.setWithoutUpdate(world, blockPos.above(), state.setValue(BaseDoublePlantBlock.TOP, true)); + } else if (this.plant.getBlock() instanceof BaseCropBlock) { + BlockState state = this.plant.setValue(BaseCropBlock.AGE, 3); + BlocksHelper.setWithoutUpdate(world, blockPos, state); + } else if (this.plant.getBlock() instanceof EndPlantWithAgeBlock) { + int age = random.nextInt(4); + BlockState state = this.plant.setValue(EndPlantWithAgeBlock.AGE, age); + BlocksHelper.setWithoutUpdate(world, blockPos, state); + } else { + BlocksHelper.setWithoutUpdate(world, blockPos, this.plant); + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/SinglePlantFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/SinglePlantFeatureConfig.java new file mode 100644 index 00000000..5ac20f6e --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/SinglePlantFeatureConfig.java @@ -0,0 +1,59 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +public class SinglePlantFeatureConfig extends ScatterFeatureConfig { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("state").forGetter(o -> o.plant), + Codec.INT.fieldOf("radius").forGetter(o -> o.radius), + Codec.BOOL.fieldOf("raw_heightmap").forGetter(o -> o.rawHeightmap), + Codec.INT.fieldOf("chance").forGetter(o -> o.chance) + ) + .apply( + instance, + SinglePlantFeatureConfig::new + )); + + public final BlockStateProvider plant; + public final boolean rawHeightmap; + public final int chance; + + public SinglePlantFeatureConfig(Block plant, int radius) { + this(SimpleStateProvider.simple(plant), radius, true, 1); + } + + public SinglePlantFeatureConfig(Block plant, int radius, int chance) { + this(SimpleStateProvider.simple(plant), radius, true, chance); + } + + public SinglePlantFeatureConfig(Block plant, int radius, boolean rawHeightmap) { + this(SimpleStateProvider.simple(plant), radius, rawHeightmap, 1); + } + + public SinglePlantFeatureConfig(Block plant, int radius, boolean rawHeightmap, int chance) { + this(SimpleStateProvider.simple(plant), radius, rawHeightmap, chance); + } + + public SinglePlantFeatureConfig(BlockStateProvider plant, int radius, boolean rawHeightmap, int chance) { + super(radius); + this.plant = plant; + this.rawHeightmap = rawHeightmap; + this.chance = chance; + } + + public BlockState getPlantState(RandomSource rnd, BlockPos pos) { + return plant.getState(rnd, pos); + } + + public static SinglePlantFeatureConfig charnia(Block plant) { + return new SinglePlantFeatureConfig(plant, 6); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/SkyScatterFeature.java b/src/main/java/org/betterx/betterend/world/features/SkyScatterFeature.java new file mode 100644 index 00000000..71e024db --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/SkyScatterFeature.java @@ -0,0 +1,61 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; + +public abstract class SkyScatterFeature extends ScatterFeature { + public SkyScatterFeature() { + super(ScatterFeatureConfig.CODEC); + } + + @Override + protected int getChance() { + return 10; + } + + @Override + public boolean canGenerate( + ScatterFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ) { + if (!world.isEmptyBlock(blockPos)) { + return false; + } + + for (Direction dir : BlocksHelper.HORIZONTAL) { + if (!world.isEmptyBlock(blockPos.relative(dir))) { + return false; + } + } + + int maxD = getYOffset() + 2; + int maxV = getYOffset() - 2; + + return BlocksHelper.upRay(world, blockPos, maxD) > maxV && BlocksHelper.downRay(world, blockPos, maxD) > maxV; + } + + @Override + protected boolean canSpawn(ScatterFeatureConfig cfg, WorldGenLevel world, BlockPos pos) { + return true; + } + + @Override + protected BlockPos getCenterGround(ScatterFeatureConfig cfg, WorldGenLevel world, BlockPos pos) { + return new BlockPos(pos.getX(), MHelper.randRange(32, 192, world.getRandom()), pos.getZ()); + } + + protected boolean getGroundPlant(WorldGenLevel world, MutableBlockPos pos) { + pos.setY(pos.getY() + MHelper.randRange(-getYOffset(), getYOffset(), world.getRandom())); + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantFeature.java b/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantFeature.java new file mode 100644 index 00000000..27180c76 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantFeature.java @@ -0,0 +1,44 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.blocks.BaseDoublePlantBlock; +import org.betterx.bclib.util.BlocksHelper; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; + +public class UnderwaterPlantFeature extends UnderwaterPlantScatter { + private BlockState plant; + + public UnderwaterPlantFeature() { + super(SinglePlantFeatureConfig.CODEC); + + } + + @Override + public boolean canGenerate( + SinglePlantFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ) { + plant = cfg.getPlantState(random, blockPos); + //noinspection deprecation + return super.canSpawn(cfg, world, blockPos) && plant.getBlock().canSurvive(plant, world, blockPos); + } + + @Override + public void generate(SinglePlantFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + if (plant.getBlock() instanceof BaseDoublePlantBlock) { + int rot = random.nextInt(4); + BlockState state = plant.setValue(BaseDoublePlantBlock.ROTATION, rot); + BlocksHelper.setWithoutUpdate(world, blockPos, state); + BlocksHelper.setWithoutUpdate(world, blockPos.above(), state.setValue(BaseDoublePlantBlock.TOP, true)); + } else { + BlocksHelper.setWithoutUpdate(world, blockPos, plant); + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantScatter.java b/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantScatter.java new file mode 100644 index 00000000..2fd45dea --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantScatter.java @@ -0,0 +1,64 @@ +package org.betterx.betterend.world.features; + +import org.betterx.betterend.util.GlobalState; + +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; + +public abstract class UnderwaterPlantScatter extends ScatterFeature { + public UnderwaterPlantScatter(Codec codec) { + super(codec); + } + + @Override + protected BlockPos getCenterGround(FC cfg, WorldGenLevel world, BlockPos pos) { + final MutableBlockPos POS = GlobalState.stateForThread().POS; + POS.setX(pos.getX()); + POS.setZ(pos.getZ()); + POS.setY(0); + return getGround(world, POS).immutable(); + } + + @Override + public boolean canGenerate( + FC cfg, + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ) { + return world.getBlockState(blockPos).is(Blocks.WATER); + } + + @Override + protected boolean canSpawn(FC cfg, WorldGenLevel world, BlockPos pos) { + return world.getBlockState(pos).is(Blocks.WATER); + } + + @Override + protected boolean getGroundPlant(FC cfg, WorldGenLevel world, MutableBlockPos pos) { + return getGround(world, pos).getY() < 128; + } + + @Override + protected int getYOffset() { + return -5; + } + + @Override + protected int getChance() { + return 5; + } + + private BlockPos getGround(WorldGenLevel world, MutableBlockPos pos) { + while (pos.getY() < 128 && world.getFluidState(pos).isEmpty()) { + pos.setY(pos.getY() + 1); + } + return pos; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/VineFeature.java b/src/main/java/org/betterx/betterend/world/features/VineFeature.java new file mode 100644 index 00000000..87e6cc9b --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/VineFeature.java @@ -0,0 +1,76 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.blocks.BaseVineBlock; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.util.BlocksHelper; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; + +public class VineFeature extends InvertedScatterFeature { + private BlockState plant; + boolean vine; + + public VineFeature() { + super(VineFeatureConfig.CODEC); + } + + @Override + public boolean canGenerate( + VineFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos center, + BlockPos blockPos, + float radius + ) { + plant = cfg.getPlantState(random, blockPos); + + BlockState state = world.getBlockState(blockPos); + return state.getMaterial().isReplaceable() && canPlaceBlock(state, world, blockPos); + } + + @Override + public void generate(VineFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + int h = BlocksHelper.downRay(world, blockPos, random.nextInt(cfg.maxLength)) - 1; + if (h > 2) { + BlockState top = getTopState(); + BlockState middle = getMiddleState(); + BlockState bottom = getBottomState(); + BlocksHelper.setWithoutUpdate(world, blockPos, top); + for (int i = 1; i < h; i++) { + BlocksHelper.setWithoutUpdate(world, blockPos.below(i), middle); + } + BlocksHelper.setWithoutUpdate(world, blockPos.below(h), bottom); + } + } + + private boolean canPlaceBlock(BlockState state, WorldGenLevel world, BlockPos blockPos) { + if (plant == null) return false; + if (plant.getBlock() instanceof BaseVineBlock vineBlock) { + vine = true; + return vineBlock.canGenerate(state, world, blockPos); + } else { + vine = false; + return plant.getBlock().canSurvive(state, world, blockPos); + } + } + + private BlockState getTopState() { + BlockState state = plant; + return vine ? state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP) : state; + } + + private BlockState getMiddleState() { + BlockState state = plant; + return vine ? state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE) : state; + } + + private BlockState getBottomState() { + BlockState state = plant; + return vine ? state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM) : state; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/VineFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/VineFeatureConfig.java new file mode 100644 index 00000000..63908104 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/VineFeatureConfig.java @@ -0,0 +1,42 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +public class VineFeatureConfig extends ScatterFeatureConfig { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("state").forGetter(o -> o.plant), + Codec.INT.fieldOf("radius").forGetter(o -> o.radius), + Codec.INT.fieldOf("max_length").forGetter(o -> o.maxLength) + ) + .apply( + instance, + VineFeatureConfig::new + )); + + + public final BlockStateProvider plant; + public final int maxLength; + + public VineFeatureConfig(Block vineBlock, int maxLength) { + this(SimpleStateProvider.simple(vineBlock), 6, maxLength); + } + + public VineFeatureConfig(BlockStateProvider plant, int radius, int maxLength) { + super(radius); + this.plant = plant; + this.maxLength = maxLength; + } + + public BlockState getPlantState(RandomSource rnd, BlockPos pos) { + return plant.getState(rnd, pos); + } + +} diff --git a/src/main/java/org/betterx/betterend/world/features/WallPlantFeature.java b/src/main/java/org/betterx/betterend/world/features/WallPlantFeature.java new file mode 100644 index 00000000..faa053de --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/WallPlantFeature.java @@ -0,0 +1,58 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.blocks.BaseAttachedBlock; +import org.betterx.bclib.blocks.BaseWallPlantBlock; +import org.betterx.bclib.util.BlocksHelper; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; + +public class WallPlantFeature extends WallScatterFeature { + protected BlockState plant; + + public WallPlantFeature() { + super(WallPlantFeatureConfig.CODEC); + } + + @Override + public boolean canGenerate( + WallPlantFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos pos, + Direction dir + ) { + plant = cfg.getPlantState(random, pos); + Block block = plant.getBlock(); + if (block instanceof BaseWallPlantBlock) { + BlockState state = plant.setValue(BaseWallPlantBlock.FACING, dir); + return block.canSurvive(state, world, pos); + } else if (block instanceof BaseAttachedBlock) { + BlockState state = plant.setValue(BlockStateProperties.FACING, dir); + return block.canSurvive(state, world, pos); + } + return block.canSurvive(plant, world, pos); + } + + @Override + public void generate( + WallPlantFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos pos, + Direction dir + ) { + Block block = plant.getBlock(); + if (block instanceof BaseWallPlantBlock) { + plant = plant.setValue(BaseWallPlantBlock.FACING, dir); + } else if (block instanceof BaseAttachedBlock) { + plant = plant.setValue(BlockStateProperties.FACING, dir); + } + BlocksHelper.setWithoutUpdate(world, pos, plant); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/WallPlantFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/WallPlantFeatureConfig.java new file mode 100644 index 00000000..010db91d --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/WallPlantFeatureConfig.java @@ -0,0 +1,39 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +public class WallPlantFeatureConfig extends ScatterFeatureConfig { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("state").forGetter(o -> o.plant), + Codec.INT.fieldOf("radius").forGetter(o -> o.radius) + ) + .apply( + instance, + WallPlantFeatureConfig::new + )); + + + public final BlockStateProvider plant; + + public WallPlantFeatureConfig(Block plant, int radius) { + this(SimpleStateProvider.simple(plant), radius); + } + + public WallPlantFeatureConfig(BlockStateProvider plant, int radius) { + super(radius); + this.plant = plant; + } + + public BlockState getPlantState(RandomSource rnd, BlockPos pos) { + return plant.getState(rnd, pos); + } + +} diff --git a/src/main/java/org/betterx/betterend/world/features/WallPlantOnLogFeature.java b/src/main/java/org/betterx/betterend/world/features/WallPlantOnLogFeature.java new file mode 100644 index 00000000..204443c6 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/WallPlantOnLogFeature.java @@ -0,0 +1,24 @@ +package org.betterx.betterend.world.features; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; + +public class WallPlantOnLogFeature extends WallPlantFeature { + @Override + public boolean canGenerate( + WallPlantFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos pos, + Direction dir + ) { + plant = cfg.getPlantState(random, pos); + BlockPos blockPos = pos.relative(dir.getOpposite()); + BlockState blockState = world.getBlockState(blockPos); + return blockState.is(BlockTags.LOGS); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/WallScatterFeature.java b/src/main/java/org/betterx/betterend/world/features/WallScatterFeature.java new file mode 100644 index 00000000..4e610908 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/WallScatterFeature.java @@ -0,0 +1,71 @@ +package org.betterx.betterend.world.features; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; + +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; + +public abstract class WallScatterFeature extends Feature { + private static final Direction[] DIR = BlocksHelper.makeHorizontal(); + + public WallScatterFeature(Codec codec) { + super(codec); + } + + public abstract boolean canGenerate(FC cfg, WorldGenLevel world, RandomSource random, BlockPos pos, Direction dir); + + public abstract void generate(FC cfg, WorldGenLevel world, RandomSource random, BlockPos pos, Direction dir); + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + FC cfg = featureConfig.config(); + final RandomSource random = featureConfig.random(); + final BlockPos center = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + int maxY = world.getHeight(Heightmap.Types.WORLD_SURFACE, center.getX(), center.getZ()); + int minY = BlocksHelper.upRay(world, new BlockPos(center.getX(), 0, center.getZ()), maxY); + if (maxY < 10 || maxY < minY) { + return false; + } + int py = MHelper.randRange(minY, maxY, random); + + MutableBlockPos mut = new MutableBlockPos(); + for (int x = -cfg.radius; x <= cfg.radius; x++) { + mut.setX(center.getX() + x); + for (int y = -cfg.radius; y <= cfg.radius; y++) { + mut.setY(py + y); + for (int z = -cfg.radius; z <= cfg.radius; z++) { + mut.setZ(center.getZ() + z); + if (random.nextInt(4) == 0 && world.isEmptyBlock(mut)) { + shuffle(random); + for (Direction dir : DIR) { + if (canGenerate(cfg, world, random, mut, dir)) { + generate(cfg, world, random, mut, dir); + break; + } + } + } + } + } + } + + return true; + } + + private void shuffle(RandomSource random) { + for (int i = 0; i < 4; i++) { + int j = random.nextInt(4); + Direction d = DIR[i]; + DIR[i] = DIR[j]; + DIR[j] = d; + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/bushes/BushFeature.java b/src/main/java/org/betterx/betterend/world/features/bushes/BushFeature.java new file mode 100644 index 00000000..fe084e4c --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/bushes/BushFeature.java @@ -0,0 +1,99 @@ +package org.betterx.betterend.world.features.bushes; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFScale3D; +import org.betterx.bclib.sdf.operator.SDFSubtraction; +import org.betterx.bclib.sdf.operator.SDFTranslate; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.material.Material; + +import java.util.function.Function; + +public class BushFeature extends Feature { + private static final Function REPLACE; + + public BushFeature() { + super(BushFeatureConfig.CODEC); + } + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES) && !world.getBlockState(pos.above()) + .is(CommonBlockTags.END_STONES)) + return false; + + BushFeatureConfig cfg = featureConfig.config(); + Block leaves = cfg.leaves.getState(random, pos).getBlock(); + BlockState stem = cfg.stem.getState(random, pos); + float radius = MHelper.randRange(1.8F, 3.5F, random); + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextInt()); + SDF sphere = new SDFSphere().setRadius(radius).setBlock(leaves); + sphere = new SDFScale3D().setScale(1, 0.5F, 1).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> (float) noise.eval( + vec.x() * 0.2, + vec.y() * 0.2, + vec.z() * 0.2 + ) * 3).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> MHelper.randRange(-2F, 2F, random)).setSource(sphere); + sphere = new SDFSubtraction().setSourceA(sphere) + .setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere)); + sphere.setReplaceFunction(REPLACE); + sphere.addPostProcess((info) -> { + if (info.getState().getBlock() instanceof LeavesBlock) { + int distance = info.getPos().distManhattan(pos); + if (distance < 7) { + return info.getState().setValue(LeavesBlock.DISTANCE, distance); + } else { + return DefaultFeature.AIR; + } + } + return info.getState(); + }); + sphere.fillRecursive(world, pos); + BlocksHelper.setWithoutUpdate(world, pos, stem); + for (Direction d : Direction.values()) { + BlockPos p = pos.relative(d); + if (world.isEmptyBlock(p)) { + if (leaves instanceof LeavesBlock) { + BlocksHelper.setWithoutUpdate( + world, + p, + leaves.defaultBlockState().setValue(LeavesBlock.DISTANCE, 1) + ); + } else { + BlocksHelper.setWithoutUpdate(world, p, leaves.defaultBlockState()); + } + } + } + + return true; + } + + static { + REPLACE = (state) -> { + if (state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/bushes/BushFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/bushes/BushFeatureConfig.java new file mode 100644 index 00000000..f2ad3adf --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/bushes/BushFeatureConfig.java @@ -0,0 +1,36 @@ +package org.betterx.betterend.world.features.bushes; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +public class BushFeatureConfig implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("leaves").forGetter(o -> o.leaves), + BlockStateProvider.CODEC.fieldOf("stem").forGetter(o -> o.stem) + ) + .apply(instance, BushFeatureConfig::new)); + + + public final BlockStateProvider leaves; + public final BlockStateProvider stem; + + public BushFeatureConfig(Block leaves, Block stem) { + this( + SimpleStateProvider.simple(leaves), + SimpleStateProvider.simple(stem) + ); + } + + public BushFeatureConfig( + BlockStateProvider leaves, + BlockStateProvider stem + ) { + this.leaves = leaves; + this.stem = stem; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/bushes/BushWithOuterFeature.java b/src/main/java/org/betterx/betterend/world/features/bushes/BushWithOuterFeature.java new file mode 100644 index 00000000..72ea2286 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/bushes/BushWithOuterFeature.java @@ -0,0 +1,117 @@ +package org.betterx.betterend.world.features.bushes; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFScale3D; +import org.betterx.bclib.sdf.operator.SDFSubtraction; +import org.betterx.bclib.sdf.operator.SDFTranslate; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.material.Material; + +import java.util.function.Function; + +public class BushWithOuterFeature extends Feature { + private static final Direction[] DIRECTIONS = Direction.values(); + private static final Function REPLACE; + + + public BushWithOuterFeature() { + super(BushWithOuterFeatureConfig.CODEC); + } + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + BushWithOuterFeatureConfig cfg = featureConfig.config(); + BlockState outer_leaves = cfg.outer_leaves.getState(random, pos); + Block leaves = cfg.leaves.getState(random, pos).getBlock(); + BlockState stem = cfg.stem.getState(random, pos); + + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES) && !world.getBlockState(pos.above()) + .is(CommonBlockTags.END_STONES)) + return false; + + float radius = MHelper.randRange(1.8F, 3.5F, random); + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextInt()); + SDF sphere = new SDFSphere().setRadius(radius).setBlock(leaves); + sphere = new SDFScale3D().setScale(1, 0.5F, 1).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> (float) noise.eval( + vec.x() * 0.2, + vec.y() * 0.2, + vec.z() * 0.2 + ) * 3).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> MHelper.randRange(-2F, 2F, random)).setSource(sphere); + sphere = new SDFSubtraction().setSourceA(sphere) + .setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere)); + sphere.setReplaceFunction(REPLACE); + sphere.addPostProcess((info) -> { + if (info.getState().getBlock() instanceof LeavesBlock) { + int distance = info.getPos().distManhattan(pos); + if (distance < 7) { + return info.getState().setValue(LeavesBlock.DISTANCE, distance); + } else { + return DefaultFeature.AIR; + } + } + return info.getState(); + }).addPostProcess((info) -> { + if (info.getState().getBlock() instanceof LeavesBlock) { + MHelper.shuffle(DIRECTIONS, random); + for (Direction dir : DIRECTIONS) { + if (info.getState(dir).isAir()) { + info.setBlockPos( + info.getPos().relative(dir), + outer_leaves.setValue(BlockStateProperties.FACING, dir) + ); + } + } + } + return info.getState(); + }); + sphere.fillRecursive(world, pos); + BlocksHelper.setWithoutUpdate(world, pos, stem); + for (Direction d : Direction.values()) { + BlockPos p = pos.relative(d); + if (world.isEmptyBlock(p)) { + if (leaves instanceof LeavesBlock) { + BlocksHelper.setWithoutUpdate( + world, + p, + leaves.defaultBlockState().setValue(LeavesBlock.DISTANCE, 1) + ); + } else { + BlocksHelper.setWithoutUpdate(world, p, leaves.defaultBlockState()); + } + } + } + + return true; + } + + static { + REPLACE = (state) -> { + if (state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/bushes/BushWithOuterFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/bushes/BushWithOuterFeatureConfig.java new file mode 100644 index 00000000..e88ace38 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/bushes/BushWithOuterFeatureConfig.java @@ -0,0 +1,37 @@ +package org.betterx.betterend.world.features.bushes; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +public class BushWithOuterFeatureConfig extends BushFeatureConfig { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("leaves").forGetter(o -> o.leaves), + BlockStateProvider.CODEC.fieldOf("outer_leaves").forGetter(o -> o.outer_leaves), + BlockStateProvider.CODEC.fieldOf("stem").forGetter(o -> o.stem) + ) + .apply(instance, BushWithOuterFeatureConfig::new)); + + + public final BlockStateProvider outer_leaves; + + public BushWithOuterFeatureConfig(Block leaves, Block outer_leaves, Block stem) { + this( + SimpleStateProvider.simple(leaves), + SimpleStateProvider.simple(outer_leaves), + SimpleStateProvider.simple(stem) + ); + } + + public BushWithOuterFeatureConfig( + BlockStateProvider leaves, + BlockStateProvider outer_leaves, + BlockStateProvider stem + ) { + super(leaves, stem); + this.outer_leaves = outer_leaves; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/bushes/LargeAmaranitaFeature.java b/src/main/java/org/betterx/betterend/world/features/bushes/LargeAmaranitaFeature.java new file mode 100644 index 00000000..f6c6b13a --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/bushes/LargeAmaranitaFeature.java @@ -0,0 +1,55 @@ +package org.betterx.betterend.world.features.bushes; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class LargeAmaranitaFeature extends DefaultFeature { + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES)) return false; + + MutableBlockPos mut = new MutableBlockPos().set(pos); + int height = MHelper.randRange(2, 3, random); + for (int i = 1; i < height; i++) { + mut.setY(mut.getY() + 1); + if (!world.isEmptyBlock(mut)) { + return false; + } + } + mut.set(pos); + + BlockState state = EndBlocks.LARGE_AMARANITA_MUSHROOM.defaultBlockState(); + BlocksHelper.setWithUpdate(world, mut, state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM)); + if (height > 2) { + BlocksHelper.setWithUpdate( + world, + mut.move(Direction.UP), + state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE) + ); + } + BlocksHelper.setWithUpdate( + world, + mut.move(Direction.UP), + state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP) + ); + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/bushes/Lumecorn.java b/src/main/java/org/betterx/betterend/world/features/bushes/Lumecorn.java new file mode 100644 index 00000000..f50e0dda --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/bushes/Lumecorn.java @@ -0,0 +1,82 @@ +package org.betterx.betterend.world.features.bushes; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.EndBlockProperties.LumecornShape; +import org.betterx.betterend.blocks.LumecornBlock; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class Lumecorn extends DefaultFeature { + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES)) return false; + + int height = MHelper.randRange(4, 7, random); + MutableBlockPos mut = new MutableBlockPos().set(pos); + for (int i = 1; i < height; i++) { + mut.move(Direction.UP); + if (!world.isEmptyBlock(mut)) { + return false; + } + } + mut.set(pos); + BlockState topMiddle = EndBlocks.LUMECORN.defaultBlockState() + .setValue(LumecornBlock.SHAPE, LumecornShape.LIGHT_TOP_MIDDLE); + BlockState middle = EndBlocks.LUMECORN.defaultBlockState() + .setValue(LumecornBlock.SHAPE, LumecornShape.LIGHT_MIDDLE); + BlockState bottom = EndBlocks.LUMECORN.defaultBlockState() + .setValue(LumecornBlock.SHAPE, LumecornShape.LIGHT_BOTTOM); + BlockState top = EndBlocks.LUMECORN.defaultBlockState().setValue(LumecornBlock.SHAPE, LumecornShape.LIGHT_TOP); + if (height == 4) { + BlocksHelper.setWithoutUpdate( + world, + mut, + EndBlocks.LUMECORN.defaultBlockState().setValue(LumecornBlock.SHAPE, LumecornShape.BOTTOM_SMALL) + ); + BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), bottom); + BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), topMiddle); + BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), top); + return true; + } + if (random.nextBoolean()) { + BlocksHelper.setWithoutUpdate( + world, + mut, + EndBlocks.LUMECORN.defaultBlockState().setValue(LumecornBlock.SHAPE, LumecornShape.BOTTOM_SMALL) + ); + } else { + BlocksHelper.setWithoutUpdate( + world, + mut, + EndBlocks.LUMECORN.defaultBlockState().setValue(LumecornBlock.SHAPE, LumecornShape.BOTTOM_BIG) + ); + BlocksHelper.setWithoutUpdate( + world, + mut.move(Direction.UP), + EndBlocks.LUMECORN.defaultBlockState().setValue(LumecornBlock.SHAPE, LumecornShape.MIDDLE) + ); + height--; + } + BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), bottom); + for (int i = 4; i < height; i++) { + BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), middle); + } + BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), topMiddle); + BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), top); + return false; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/bushes/TenaneaBushFeature.java b/src/main/java/org/betterx/betterend/world/features/bushes/TenaneaBushFeature.java new file mode 100644 index 00000000..a851da12 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/bushes/TenaneaBushFeature.java @@ -0,0 +1,138 @@ +package org.betterx.betterend.world.features.bushes; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFScale3D; +import org.betterx.bclib.sdf.operator.SDFSubtraction; +import org.betterx.bclib.sdf.operator.SDFTranslate; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.basis.FurBlock; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.function.Function; + +public class TenaneaBushFeature extends DefaultFeature { + private static final Function REPLACE; + private static final Direction[] DIRECTIONS = Direction.values(); + + public TenaneaBushFeature() { + } + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES)) return false; + + float radius = MHelper.randRange(1.8F, 3.5F, random); + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextInt()); + BlockState leaves = EndBlocks.TENANEA_LEAVES.defaultBlockState(); + SDF sphere = new SDFSphere().setRadius(radius).setBlock(leaves); + sphere = new SDFScale3D().setScale(1, 0.75F, 1).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> (float) noise.eval( + vec.x() * 0.2, + vec.y() * 0.2, + vec.z() * 0.2 + ) * 3).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> MHelper.randRange(-2F, 2F, random)).setSource(sphere); + sphere = new SDFSubtraction().setSourceA(sphere) + .setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere)); + sphere.setReplaceFunction(REPLACE); + List support = Lists.newArrayList(); + sphere.addPostProcess((info) -> { + if (info.getState().getBlock() instanceof LeavesBlock) { + int distance = info.getPos().distManhattan(pos); + if (distance < 7) { + if (random.nextInt(4) == 0 && info.getStateDown().isAir()) { + BlockPos d = info.getPos().below(); + support.add(d); + } + + MHelper.shuffle(DIRECTIONS, random); + for (Direction d : DIRECTIONS) { + if (info.getState(d).isAir()) { + info.setBlockPos( + info.getPos().relative(d), + EndBlocks.TENANEA_OUTER_LEAVES.defaultBlockState().setValue(FurBlock.FACING, d) + ); + } + } + + return info.getState().setValue(LeavesBlock.DISTANCE, distance); + } else { + return AIR; + } + } + return info.getState(); + }); + sphere.fillRecursive(world, pos); + BlockState stem = EndBlocks.TENANEA.getBark().defaultBlockState(); + BlocksHelper.setWithoutUpdate(world, pos, stem); + for (Direction d : Direction.values()) { + BlockPos p = pos.relative(d); + if (world.isEmptyBlock(p)) { + BlocksHelper.setWithoutUpdate(world, p, leaves.setValue(LeavesBlock.DISTANCE, 1)); + } + } + + MutableBlockPos mut = new MutableBlockPos(); + BlockState top = EndBlocks.TENANEA_FLOWERS.defaultBlockState() + .setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP); + BlockState middle = EndBlocks.TENANEA_FLOWERS.defaultBlockState() + .setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE); + BlockState bottom = EndBlocks.TENANEA_FLOWERS.defaultBlockState() + .setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM); + support.forEach((bpos) -> { + BlockState state = world.getBlockState(bpos); + if (state.isAir() || state.is(EndBlocks.TENANEA_OUTER_LEAVES)) { + int count = MHelper.randRange(3, 8, random); + mut.set(bpos); + if (world.getBlockState(mut.above()).is(EndBlocks.TENANEA_LEAVES)) { + BlocksHelper.setWithoutUpdate(world, mut, top); + for (int i = 1; i < count; i++) { + mut.setY(mut.getY() - 1); + if (world.isEmptyBlock(mut.below())) { + BlocksHelper.setWithoutUpdate(world, mut, middle); + } else { + break; + } + } + BlocksHelper.setWithoutUpdate(world, mut, bottom); + } + } + }); + + return true; + } + + static { + REPLACE = (state) -> { + if (state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/ArchFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/ArchFeature.java new file mode 100644 index 00000000..eb174b41 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/ArchFeature.java @@ -0,0 +1,78 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFRotation; +import org.betterx.bclib.sdf.primitive.SDFTorus; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; + +public class ArchFeature extends Feature { + public ArchFeature() { + super(ArchFeatureConfig.CODEC); + } + + @Override + public boolean place(FeaturePlaceContext featurePlaceContext) { + ArchFeatureConfig cfg = featurePlaceContext.config(); + final WorldGenLevel world = featurePlaceContext.level(); + BlockPos origin = featurePlaceContext.origin(); + RandomSource random = featurePlaceContext.random(); + BlockState cfgBlockState = cfg.block.getState(random, origin); + Block cfgBlock = cfgBlockState.getBlock(); + BlockPos pos = DefaultFeature.getPosOnSurfaceWG( + world, + new BlockPos((origin.getX() & 0xFFFFFFF0) | 7, 0, (origin.getZ() & 0xFFFFFFF0) | 7) + ); + if (!world.getBlockState(pos.below(5)).is(CommonBlockTags.GEN_END_STONES)) { + return false; + } + + float bigRadius = MHelper.randRange(10F, 20F, random); + float smallRadius = MHelper.randRange(3F, 7F, random); + if (smallRadius + bigRadius > 23) { + smallRadius = 23 - bigRadius; + } + SDF arch = new SDFTorus().setBigRadius(bigRadius).setSmallRadius(smallRadius).setBlock(cfgBlock); + arch = new SDFRotation().setRotation(MHelper.randomHorizontal(random), (float) Math.PI * 0.5F).setSource(arch); + + final float smallRadiusF = smallRadius; + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + arch = new SDFDisplacement().setFunction((vec) -> (float) (Math.abs(noise.eval( + vec.x() * 0.1, + vec.y() * 0.1, + vec.z() * 0.1 + )) * 3F + Math.abs(noise.eval( + vec.x() * 0.3, + vec.y() * 0.3 + 100, + vec.z() * 0.3 + )) * 1.3F) - smallRadiusF * Math.abs(1 - vec.y() / bigRadius)).setSource(arch); + + arch.addPostProcess((info) -> { + if (info.getStateUp().isAir()) { + return cfg.surfaceFunction.apply(info.getPos()); + } + return info.getState(); + }); + + float side = (bigRadius + smallRadius + 3F) * 2; + if (side > 47) { + side = 47; + } + arch.fillArea(world, pos, AABB.ofSize(Vec3.atCenterOf(pos), side, side, side)); + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/ArchFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/terrain/ArchFeatureConfig.java new file mode 100644 index 00000000..b4c47aca --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/ArchFeatureConfig.java @@ -0,0 +1,58 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.betterend.world.biome.land.UmbraValleyBiome; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.util.StringRepresentable; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +import java.util.function.Function; + +public class ArchFeatureConfig implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("states").forGetter(o -> o.block), + SurfaceFunction.CODEC.fieldOf("surface_function").forGetter(o -> o.surfaceFunction) + ) + .apply(instance, ArchFeatureConfig::new)); + + + public final BlockStateProvider block; + public final SurfaceFunction surfaceFunction; + + public ArchFeatureConfig(Block block, SurfaceFunction surfaceFunction) { + this(SimpleStateProvider.simple(block), surfaceFunction); + } + + public ArchFeatureConfig(BlockStateProvider block, SurfaceFunction surfaceFunction) { + this.block = block; + this.surfaceFunction = surfaceFunction; + } + + public enum SurfaceFunction implements StringRepresentable { + UMBRA_VALLEY("umbra_valley", pos -> UmbraValleyBiome.getSurface(pos.getX(), pos.getZ()).defaultBlockState()); + public static final Codec CODEC = StringRepresentable.fromEnum(SurfaceFunction::values); + private final Function surfaceFunction; + private final String name; + + SurfaceFunction(String name, Function surfaceFunction) { + this.name = name; + this.surfaceFunction = surfaceFunction; + } + + @Override + public String getSerializedName() { + return name; + } + + public BlockState apply(BlockPos pos) { + return this.surfaceFunction.apply(pos); + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/BigAuroraCrystalFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/BigAuroraCrystalFeature.java new file mode 100644 index 00000000..1acc66c7 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/BigAuroraCrystalFeature.java @@ -0,0 +1,54 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFRotation; +import org.betterx.bclib.sdf.primitive.SDFHexPrism; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +public class BigAuroraCrystalFeature extends DefaultFeature { + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + int maxY = pos.getY() + BlocksHelper.upRay(world, pos, 16); + int minY = pos.getY() - BlocksHelper.downRay(world, pos, 16); + + if (maxY - minY < 10) { + return false; + } + + int y = MHelper.randRange(minY, maxY, random); + pos = new BlockPos(pos.getX(), y, pos.getZ()); + + int height = MHelper.randRange(5, 25, random); + SDF prism = new SDFHexPrism().setHeight(height) + .setRadius(MHelper.randRange(1.7F, 3F, random)) + .setBlock(EndBlocks.AURORA_CRYSTAL); + Vector3f vec = MHelper.randomHorizontal(random); + prism = new SDFRotation().setRotation(vec, random.nextFloat()).setSource(prism); + prism.setReplaceFunction((bState) -> { + return bState.getMaterial() + .isReplaceable() || bState.is(CommonBlockTags.GEN_END_STONES) || bState.getMaterial() + .equals(Material.PLANT) || bState + .getMaterial() + .equals(Material.LEAVES); + }); + prism.fillRecursive(world, pos); + BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.AURORA_CRYSTAL); + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/DesertLakeFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/DesertLakeFeature.java new file mode 100644 index 00000000..ee8a97b6 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/DesertLakeFeature.java @@ -0,0 +1,248 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.util.BlockFixer; +import org.betterx.betterend.util.GlobalState; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Material; + +public class DesertLakeFeature extends DefaultFeature { + private static final BlockState END_STONE = Blocks.END_STONE.defaultBlockState(); + private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(15152); + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final MutableBlockPos POS = GlobalState.stateForThread().POS; + + final RandomSource random = featureConfig.random(); + BlockPos blockPos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + double radius = MHelper.randRange(8.0, 15.0, random); + double depth = radius * 0.5 * MHelper.randRange(0.8, 1.2, random); + int dist = MHelper.floor(radius); + int dist2 = MHelper.floor(radius * 1.5); + int bott = MHelper.floor(depth); + blockPos = getPosOnSurfaceWG(world, blockPos); + + if (blockPos.getY() < 10) return false; + + int waterLevel = blockPos.getY(); + + BlockPos pos = getPosOnSurfaceRaycast(world, blockPos.north(dist).above(10), 20); + if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; + waterLevel = MHelper.min(pos.getY(), waterLevel); + + pos = getPosOnSurfaceRaycast(world, blockPos.south(dist).above(10), 20); + if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; + waterLevel = MHelper.min(pos.getY(), waterLevel); + + pos = getPosOnSurfaceRaycast(world, blockPos.east(dist).above(10), 20); + if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; + waterLevel = MHelper.min(pos.getY(), waterLevel); + + pos = getPosOnSurfaceRaycast(world, blockPos.west(dist).above(10), 20); + if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; + waterLevel = MHelper.min(pos.getY(), waterLevel); + BlockState state; + + int minX = blockPos.getX() - dist2; + int maxX = blockPos.getX() + dist2; + int minZ = blockPos.getZ() - dist2; + int maxZ = blockPos.getZ() + dist2; + int maskMinX = minX - 1; + int maskMinZ = minZ - 1; + + boolean[][] mask = new boolean[maxX - minX + 3][maxZ - minZ + 3]; + for (int x = minX; x <= maxX; x++) { + POS.setX(x); + int mx = x - maskMinX; + for (int z = minZ; z <= maxZ; z++) { + POS.setZ(z); + int mz = z - maskMinZ; + if (!mask[mx][mz]) { + for (int y = waterLevel + 1; y <= waterLevel + 20; y++) { + POS.setY(y); + FluidState fluid = world.getFluidState(POS); + if (!fluid.isEmpty()) { + for (int i = -1; i < 2; i++) { + int px = mx + i; + for (int j = -1; j < 2; j++) { + int pz = mz + j; + mask[px][pz] = true; + } + } + break; + } + } + } + } + } + + for (int x = minX; x <= maxX; x++) { + POS.setX(x); + int x2 = x - blockPos.getX(); + x2 *= x2; + int mx = x - maskMinX; + for (int z = minZ; z <= maxZ; z++) { + POS.setZ(z); + int z2 = z - blockPos.getZ(); + z2 *= z2; + int mz = z - maskMinZ; + if (!mask[mx][mz]) { + double size = 1; + for (int y = blockPos.getY(); y <= blockPos.getY() + 20; y++) { + POS.setY(y); + double add = y - blockPos.getY(); + if (add > 5) { + size *= 0.8; + add = 5; + } + double r = (add * 1.8 + radius * (NOISE.eval( + x * 0.2, + y * 0.2, + z * 0.2 + ) * 0.25 + 0.75)) - 1.0 / size; + if (r > 0) { + r *= r; + if (x2 + z2 <= r) { + state = world.getBlockState(POS); + if (state.is(CommonBlockTags.GEN_END_STONES)) { + BlocksHelper.setWithoutUpdate(world, POS, AIR); + } + pos = POS.below(); + if (world.getBlockState(pos).is(CommonBlockTags.GEN_END_STONES)) { + state = EndBiome.findTopMaterial( + world, + pos + ); //world.getBiome(pos).getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); + if (y > waterLevel + 1) BlocksHelper.setWithoutUpdate(world, pos, state); + else if (y > waterLevel) + BlocksHelper.setWithoutUpdate( + world, + pos, + random.nextBoolean() + ? state + : EndBlocks.ENDSTONE_DUST.defaultBlockState() + ); + else + BlocksHelper.setWithoutUpdate( + world, + pos, + EndBlocks.ENDSTONE_DUST.defaultBlockState() + ); + } + } + } else { + break; + } + } + } + } + } + + double aspect = (radius / depth); + + for (int x = blockPos.getX() - dist; x <= blockPos.getX() + dist; x++) { + POS.setX(x); + int x2 = x - blockPos.getX(); + x2 *= x2; + int mx = x - maskMinX; + for (int z = blockPos.getZ() - dist; z <= blockPos.getZ() + dist; z++) { + POS.setZ(z); + int z2 = z - blockPos.getZ(); + z2 *= z2; + int mz = z - maskMinZ; + if (!mask[mx][mz]) { + for (int y = blockPos.getY() - bott; y < blockPos.getY(); y++) { + POS.setY(y); + double y2 = (double) (y - blockPos.getY()) * aspect; + y2 *= y2; + double r = radius * (NOISE.eval(x * 0.2, y * 0.2, z * 0.2) * 0.25 + 0.75); + double rb = r * 1.2; + r *= r; + rb *= rb; + if (y2 + x2 + z2 <= r) { + state = world.getBlockState(POS); + if (canReplace(state)) { + state = world.getBlockState(POS.above()); + state = canReplace(state) ? (y < waterLevel ? WATER : AIR) : state; + BlocksHelper.setWithoutUpdate(world, POS, state); + } + pos = POS.below(); + if (world.getBlockState(pos).is(CommonBlockTags.GEN_END_STONES)) { + BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.ENDSTONE_DUST.defaultBlockState()); + } + pos = POS.above(); + while (canReplace(state = world.getBlockState(pos)) && !state.isAir() && state + .getFluidState() + .isEmpty()) { + BlocksHelper.setWithoutUpdate(world, pos, pos.getY() < waterLevel ? WATER : AIR); + pos = pos.above(); + } + } + // Make border + else if (y2 + x2 + z2 <= rb) { + state = world.getBlockState(POS); + if (state.is(CommonBlockTags.GEN_END_STONES) && world.isEmptyBlock(POS.above())) { + BlocksHelper.setWithoutUpdate(world, POS, EndBlocks.END_MOSS); + } else if (y < waterLevel) { + if (world.isEmptyBlock(POS.above())) { + state = EndBiome.findTopMaterial( + world, + pos + ); //world.getBiome(POS).getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); + BlocksHelper.setWithoutUpdate( + world, + POS, + random.nextBoolean() ? state : EndBlocks.ENDSTONE_DUST.defaultBlockState() + ); + BlocksHelper.setWithoutUpdate(world, POS.below(), END_STONE); + } else { + BlocksHelper.setWithoutUpdate( + world, + POS, + EndBlocks.ENDSTONE_DUST.defaultBlockState() + ); + BlocksHelper.setWithoutUpdate(world, POS.below(), END_STONE); + } + } + } + } + } + } + } + + BlockFixer.fixBlocks( + world, + new BlockPos(minX - 2, waterLevel - 2, minZ - 2), + new BlockPos(maxX + 2, blockPos.getY() + 20, maxZ + 2) + ); + + return true; + } + + private boolean canReplace(BlockState state) { + return state.getMaterial() + .isReplaceable() || state.is(CommonBlockTags.GEN_END_STONES) || state.is(EndBlocks.ENDSTONE_DUST) || state + .getMaterial() + .equals( + Material.PLANT) || state + .getMaterial() + .equals(Material.WATER_PLANT); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/EndLakeFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/EndLakeFeature.java new file mode 100644 index 00000000..ab30804f --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/EndLakeFeature.java @@ -0,0 +1,240 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.util.BlockFixer; +import org.betterx.betterend.util.GlobalState; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Material; + +public class EndLakeFeature extends DefaultFeature { + private static final BlockState END_STONE = Blocks.END_STONE.defaultBlockState(); + private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(15152); + + public EndLakeFeature() { + + } + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final MutableBlockPos POS = GlobalState.stateForThread().POS; + final RandomSource random = featureConfig.random(); + BlockPos blockPos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + double radius = MHelper.randRange(10.0, 20.0, random); + double depth = radius * 0.5 * MHelper.randRange(0.8, 1.2, random); + int dist = MHelper.floor(radius); + int dist2 = MHelper.floor(radius * 1.5); + int bott = MHelper.floor(depth); + blockPos = getPosOnSurfaceWG(world, blockPos); + + if (blockPos.getY() < 10) return false; + + int waterLevel = blockPos.getY(); + + BlockPos pos = getPosOnSurfaceRaycast(world, blockPos.north(dist).above(10), 20); + if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; + waterLevel = MHelper.min(pos.getY(), waterLevel); + + pos = getPosOnSurfaceRaycast(world, blockPos.south(dist).above(10), 20); + if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; + waterLevel = MHelper.min(pos.getY(), waterLevel); + + pos = getPosOnSurfaceRaycast(world, blockPos.east(dist).above(10), 20); + if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; + waterLevel = MHelper.min(pos.getY(), waterLevel); + + pos = getPosOnSurfaceRaycast(world, blockPos.west(dist).above(10), 20); + if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; + waterLevel = MHelper.min(pos.getY(), waterLevel); + BlockState state; + + int minX = blockPos.getX() - dist2; + int maxX = blockPos.getX() + dist2; + int minZ = blockPos.getZ() - dist2; + int maxZ = blockPos.getZ() + dist2; + int maskMinX = minX - 1; + int maskMinZ = minZ - 1; + + boolean[][] mask = new boolean[maxX - minX + 3][maxZ - minZ + 3]; + for (int x = minX; x <= maxX; x++) { + POS.setX(x); + int mx = x - maskMinX; + for (int z = minZ; z <= maxZ; z++) { + POS.setZ(z); + int mz = z - maskMinZ; + if (!mask[mx][mz]) { + for (int y = waterLevel + 1; y <= waterLevel + 20; y++) { + POS.setY(y); + FluidState fluid = world.getFluidState(POS); + if (!fluid.isEmpty()) { + for (int i = -1; i < 2; i++) { + int px = mx + i; + for (int j = -1; j < 2; j++) { + int pz = mz + j; + mask[px][pz] = true; + } + } + break; + } + } + } + } + } + + for (int x = minX; x <= maxX; x++) { + POS.setX(x); + int x2 = x - blockPos.getX(); + x2 *= x2; + int mx = x - maskMinX; + for (int z = minZ; z <= maxZ; z++) { + POS.setZ(z); + int z2 = z - blockPos.getZ(); + z2 *= z2; + int mz = z - maskMinZ; + if (!mask[mx][mz]) { + double size = 1; + for (int y = blockPos.getY(); y <= blockPos.getY() + 20; y++) { + POS.setY(y); + double add = y - blockPos.getY(); + if (add > 5) { + size *= 0.8; + add = 5; + } + double r = (add * 1.8 + radius * (NOISE.eval( + x * 0.2, + y * 0.2, + z * 0.2 + ) * 0.25 + 0.75)) - 1.0 / size; + if (r > 0) { + r *= r; + if (x2 + z2 <= r) { + state = world.getBlockState(POS); + if (state.is(CommonBlockTags.GEN_END_STONES)) { + BlocksHelper.setWithoutUpdate(world, POS, AIR); + } + pos = POS.below(); + if (world.getBlockState(pos).is(CommonBlockTags.GEN_END_STONES)) { + state = EndBiome.findTopMaterial(world, pos); + if (y > waterLevel + 1) BlocksHelper.setWithoutUpdate(world, pos, state); + else if (y > waterLevel) + BlocksHelper.setWithoutUpdate( + world, + pos, + random.nextBoolean() + ? state + : EndBlocks.ENDSTONE_DUST.defaultBlockState() + ); + else + BlocksHelper.setWithoutUpdate( + world, + pos, + EndBlocks.ENDSTONE_DUST.defaultBlockState() + ); + } + } + } else { + break; + } + } + } + } + } + + double aspect = (radius / depth); + + for (int x = blockPos.getX() - dist; x <= blockPos.getX() + dist; x++) { + POS.setX(x); + int x2 = x - blockPos.getX(); + x2 *= x2; + int mx = x - maskMinX; + for (int z = blockPos.getZ() - dist; z <= blockPos.getZ() + dist; z++) { + POS.setZ(z); + int z2 = z - blockPos.getZ(); + z2 *= z2; + int mz = z - maskMinZ; + if (!mask[mx][mz]) { + for (int y = blockPos.getY() - bott; y < blockPos.getY(); y++) { + POS.setY(y); + double y2 = (double) (y - blockPos.getY()) * aspect; + y2 *= y2; + double r = radius * (NOISE.eval(x * 0.2, y * 0.2, z * 0.2) * 0.25 + 0.75); + double rb = r * 1.2; + r *= r; + rb *= rb; + if (y2 + x2 + z2 <= r) { + state = world.getBlockState(POS); + if (canReplace(state)) { + state = world.getBlockState(POS.above()); + state = canReplace(state) ? (y < waterLevel ? WATER : AIR) : state; + BlocksHelper.setWithoutUpdate(world, POS, state); + } + pos = POS.below(); + if (world.getBlockState(pos).is(CommonBlockTags.GEN_END_STONES)) { + BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.ENDSTONE_DUST.defaultBlockState()); + } + pos = POS.above(); + while (canReplace(state = world.getBlockState(pos)) && !state.isAir() && state + .getFluidState() + .isEmpty()) { + BlocksHelper.setWithoutUpdate(world, pos, pos.getY() < waterLevel ? WATER : AIR); + pos = pos.above(); + } + } + // Make border + else if (y < waterLevel && y2 + x2 + z2 <= rb) { + if (world.isEmptyBlock(POS.above())) { + state = EndBiome.findTopMaterial(world, pos); +// state = world.getBiome(POS) +// .getGenerationSettings() +// .getSurfaceBuilderConfig() +// .getTopMaterial(); + BlocksHelper.setWithoutUpdate( + world, + POS, + random.nextBoolean() ? state : EndBlocks.ENDSTONE_DUST.defaultBlockState() + ); + BlocksHelper.setWithoutUpdate(world, POS.below(), END_STONE); + } else { + BlocksHelper.setWithoutUpdate(world, POS, EndBlocks.ENDSTONE_DUST.defaultBlockState()); + BlocksHelper.setWithoutUpdate(world, POS.below(), END_STONE); + } + } + } + } + } + } + + BlockFixer.fixBlocks( + world, + new BlockPos(minX - 2, waterLevel - 2, minZ - 2), + new BlockPos(maxX + 2, blockPos.getY() + 20, maxZ + 2) + ); + + return true; + } + + private boolean canReplace(BlockState state) { + return state.getMaterial() + .isReplaceable() || state.is(CommonBlockTags.GEN_END_STONES) || state.is(EndBlocks.ENDSTONE_DUST) || state + .getMaterial() + .equals( + Material.PLANT) || state + .getMaterial() + .equals(Material.WATER_PLANT); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/FallenPillarFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/FallenPillarFeature.java new file mode 100644 index 00000000..125d7951 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/FallenPillarFeature.java @@ -0,0 +1,68 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFRotation; +import org.betterx.bclib.sdf.operator.SDFTranslate; +import org.betterx.bclib.sdf.primitive.SDFCappedCone; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +public class FallenPillarFeature extends DefaultFeature { + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + pos = getPosOnSurface( + world, + new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16)) + ); + if (!world.getBlockState(pos.below(5)).is(CommonBlockTags.GEN_END_STONES) + || !world.getBlockState(pos).isAir()) { + return false; + } + + float height = MHelper.randRange(20F, 40F, random); + float radius = MHelper.randRange(2F, 4F, random); + SDF pillar = new SDFCappedCone().setRadius1(radius) + .setRadius2(radius) + .setHeight(height * 0.5F) + .setBlock(Blocks.OBSIDIAN); + pillar = new SDFTranslate().setTranslate(0, radius * 0.5F - 2, 0).setSource(pillar); + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + pillar = new SDFDisplacement().setFunction((vec) -> { + return (float) (noise.eval(vec.x() * 0.3, vec.y() * 0.3, vec.z() * 0.3) * 0.5F); + }).setSource(pillar); + Vector3f vec = MHelper.randomHorizontal(random); + float angle = (float) random.nextGaussian() * 0.05F + (float) Math.PI; + pillar = new SDFRotation().setRotation(vec, angle).setSource(pillar); + + BlockState mossy = EndBlocks.MOSSY_OBSIDIAN.defaultBlockState(); + pillar.addPostProcess((info) -> { + if (info.getStateUp().isAir() && random.nextFloat() > 0.1F) { + return mossy; + } + return info.getState(); + }).setReplaceFunction((state) -> { + return state.getMaterial() + .isReplaceable() || state.is(CommonBlockTags.GEN_END_STONES) || state.getMaterial() + .equals(Material.PLANT); + }).fillRecursive(world, pos); + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/FloatingSpireFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/FloatingSpireFeature.java new file mode 100644 index 00000000..1abf83dd --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/FloatingSpireFeature.java @@ -0,0 +1,104 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBiomes; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.Optional; + +public class FloatingSpireFeature extends SpireFeature { + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + final ChunkGenerator chunkGenerator = featureConfig.chunkGenerator(); + int minY = getYOnSurface(world, pos.getX(), pos.getZ()); + int y = minY > 57 ? MHelper.floor(MHelper.randRange(minY, minY * 2, random) * 0.5F + 32) : MHelper.randRange( + 64, + 192, + random + ); + pos = new BlockPos(pos.getX(), y, pos.getZ()); + + SDF sdf = new SDFSphere().setRadius(MHelper.randRange(2, 3, random)).setBlock(Blocks.END_STONE); + int count = MHelper.randRange(3, 5, random); + + for (int i = 0; i < count; i++) { + float rMin = (i * 1.3F) + 2.5F; + sdf = addSegment(sdf, MHelper.randRange(rMin, rMin + 1.5F, random), random); + } + for (int i = count - 1; i > 0; i--) { + float rMin = (i * 1.3F) + 2.5F; + sdf = addSegment(sdf, MHelper.randRange(rMin, rMin + 1.5F, random), random); + } + + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + sdf = new SDFDisplacement().setFunction((vec) -> { + return (float) (Math.abs(noise.eval( + vec.x() * 0.1, + vec.y() * 0.1, + vec.z() * 0.1 + )) * 3F + Math.abs(noise.eval( + vec.x() * 0.3, + vec.y() * 0.3 + 100, + vec.z() * 0.3 + )) * 1.3F); + }).setSource(sdf); + final BlockPos center = pos; + List support = Lists.newArrayList(); + sdf.setReplaceFunction(REPLACE).addPostProcess((info) -> { + if (info.getStateUp().isAir()) { + if (random.nextInt(16) == 0) { + support.add(info.getPos().above()); + } + return EndBiome.findTopMaterial( + world, + info.getPos() + );//world.getBiome(info.getPos()).value().getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); + } else if (info.getState(Direction.UP, 3).isAir()) { + return EndBiome.findUnderMaterial(world, info.getPos()); +// return world.getBiome(info.getPos()) +// .getGenerationSettings() +// .getSurfaceBuilderConfig() +// .getUnderMaterial(); + } + return info.getState(); + }); + sdf.fillRecursive(world, center); + + support.forEach((bpos) -> { + if (BiomeAPI.getBiome(world.getBiome(bpos)) == EndBiomes.BLOSSOMING_SPIRES) { + EndFeatures.TENANEA_BUSH.getFeature() + .place(new FeaturePlaceContext( + Optional.empty(), + world, + chunkGenerator, + random, + bpos, + null + )); + } + }); + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/GeyserFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/GeyserFeature.java new file mode 100644 index 00000000..29bcb899 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/GeyserFeature.java @@ -0,0 +1,296 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.*; +import org.betterx.bclib.sdf.primitive.SDFCappedCone; +import org.betterx.bclib.sdf.primitive.SDFFlatland; +import org.betterx.bclib.sdf.primitive.SDFPrimitive; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.HydrothermalVentBlock; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.util.BlockFixer; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.HorizontalDirectionalBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import java.util.Optional; +import java.util.function.Function; + +public class GeyserFeature extends DefaultFeature { + protected static final Function REPLACE1; + protected static final Function REPLACE2; + private static final Function IGNORE; + private static final Direction[] HORIZONTAL = BlocksHelper.makeHorizontal(); + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final WorldGenLevel world = featureConfig.level(); + final BlockPos pos = getPosOnSurfaceWG(world, featureConfig.origin()); + final ChunkGenerator chunkGenerator = featureConfig.chunkGenerator(); + + if (pos.getY() < 10) { + return false; + } + + MutableBlockPos bpos = new MutableBlockPos().set(pos); + bpos.setY(bpos.getY() - 1); + BlockState state = world.getBlockState(bpos); + while (state.is(CommonBlockTags.GEN_END_STONES) || !state.getFluidState().isEmpty() && bpos.getY() > 5) { + bpos.setY(bpos.getY() - 1); + state = world.getBlockState(bpos); + } + + if (pos.getY() - bpos.getY() < 25) { + return false; + } + + int halfHeight = MHelper.randRange(10, 20, random); + float radius1 = halfHeight * 0.5F; + float radius2 = halfHeight * 0.1F + 0.5F; + SDF sdf = new SDFCappedCone().setHeight(halfHeight) + .setRadius1(radius1) + .setRadius2(radius2) + .setBlock(EndBlocks.SULPHURIC_ROCK.stone); + sdf = new SDFTranslate().setTranslate(0, halfHeight - 3, 0).setSource(sdf); + + int count = halfHeight; + for (int i = 0; i < count; i++) { + int py = i << 1; + float delta = (float) i / (float) (count - 1); + float radius = Mth.lerp(delta, radius1, radius2) * 1.3F; + + SDF bowl = new SDFCappedCone().setHeight(radius) + .setRadius1(0) + .setRadius2(radius) + .setBlock(EndBlocks.SULPHURIC_ROCK.stone); + + SDF brimstone = new SDFCappedCone().setHeight(radius) + .setRadius1(0) + .setRadius2(radius) + .setBlock(EndBlocks.BRIMSTONE); + brimstone = new SDFTranslate().setTranslate(0, 2F, 0).setSource(brimstone); + bowl = new SDFSubtraction().setSourceA(bowl).setSourceB(brimstone); + bowl = new SDFUnion().setSourceA(brimstone).setSourceB(bowl); + + SDF water = new SDFCappedCone().setHeight(radius).setRadius1(0).setRadius2(radius).setBlock(Blocks.WATER); + water = new SDFTranslate().setTranslate(0, 4, 0).setSource(water); + bowl = new SDFSubtraction().setSourceA(bowl).setSourceB(water); + bowl = new SDFUnion().setSourceA(water).setSourceB(bowl); + + final OpenSimplexNoise noise1 = new OpenSimplexNoise(random.nextLong()); + final OpenSimplexNoise noise2 = new OpenSimplexNoise(random.nextLong()); + + bowl = new SDFCoordModify().setFunction((vec) -> { + float dx = (float) noise1.eval(vec.x() * 0.1, vec.y() * 0.1, vec.z() * 0.1); + float dz = (float) noise2.eval(vec.x() * 0.1, vec.y() * 0.1, vec.z() * 0.1); + vec.set(vec.x() + dx, vec.y(), vec.z() + dz); + }).setSource(bowl); + + SDF cut = new SDFFlatland().setBlock(Blocks.AIR); + cut = new SDFInvert().setSource(cut); + cut = new SDFTranslate().setTranslate(0, radius - 2, 0).setSource(cut); + bowl = new SDFSubtraction().setSourceA(bowl).setSourceB(cut); + + bowl = new SDFTranslate().setTranslate(radius, py - radius, 0).setSource(bowl); + bowl = new SDFRotation().setRotation(Vector3f.YP, i * 4F).setSource(bowl); + sdf = new SDFUnion().setSourceA(sdf).setSourceB(bowl); + } + sdf.setReplaceFunction(REPLACE2).fillRecursive(world, pos); + + radius2 = radius2 * 0.5F; + if (radius2 < 0.7F) { + radius2 = 0.7F; + } + final OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + + SDFPrimitive obj1; + SDFPrimitive obj2; + + obj1 = new SDFCappedCone().setHeight(halfHeight + 5).setRadius1(radius1 * 0.5F).setRadius2(radius2); + sdf = new SDFTranslate().setTranslate(0, halfHeight - 13, 0).setSource(obj1); + sdf = new SDFDisplacement().setFunction((vec) -> { + return (float) noise.eval(vec.x() * 0.3F, vec.y() * 0.3F, vec.z() * 0.3F) * 0.5F; + }).setSource(sdf); + + obj2 = new SDFSphere().setRadius(radius1); + SDF cave = new SDFScale3D().setScale(1.5F, 1, 1.5F).setSource(obj2); + cave = new SDFDisplacement().setFunction((vec) -> { + return (float) noise.eval(vec.x() * 0.1F, vec.y() * 0.1F, vec.z() * 0.1F) * 2F; + }).setSource(cave); + cave = new SDFTranslate().setTranslate(0, -halfHeight - 10, 0).setSource(cave); + + sdf = new SDFSmoothUnion().setRadius(5).setSourceA(cave).setSourceB(sdf); + + obj1.setBlock(WATER); + obj2.setBlock(WATER); + sdf.setReplaceFunction(REPLACE2); + sdf.fillRecursive(world, pos); + + obj1.setBlock(EndBlocks.BRIMSTONE); + obj2.setBlock(EndBlocks.BRIMSTONE); + new SDFDisplacement().setFunction((vec) -> { + return -2F; + }).setSource(sdf).setReplaceFunction(REPLACE1).fillRecursiveIgnore(world, pos, IGNORE); + + obj1.setBlock(EndBlocks.SULPHURIC_ROCK.stone); + obj2.setBlock(EndBlocks.SULPHURIC_ROCK.stone); + new SDFDisplacement().setFunction((vec) -> { + return -4F; + }).setSource(cave).setReplaceFunction(REPLACE1).fillRecursiveIgnore(world, pos, IGNORE); + + obj1.setBlock(Blocks.END_STONE); + obj2.setBlock(Blocks.END_STONE); + new SDFDisplacement().setFunction((vec) -> { + return -6F; + }).setSource(cave).setReplaceFunction(REPLACE1).fillRecursiveIgnore(world, pos, IGNORE); + + BlocksHelper.setWithoutUpdate(world, pos, WATER); + MutableBlockPos mut = new MutableBlockPos().set(pos); + count = getYOnSurface(world, pos.getX(), pos.getZ()) - pos.getY(); + for (int i = 0; i < count; i++) { + BlocksHelper.setWithoutUpdate(world, mut, WATER); + for (Direction dir : BlocksHelper.HORIZONTAL) { + BlocksHelper.setWithoutUpdate(world, mut.relative(dir), WATER); + } + mut.setY(mut.getY() + 1); + } + + for (int i = 0; i < 150; i++) { + mut.set(pos) + .move( + MHelper.floor(random.nextGaussian() * 4 + 0.5), + -halfHeight - 10, + MHelper.floor(random.nextGaussian() * 4 + 0.5) + ); + float distRaw = MHelper.length(mut.getX() - pos.getX(), mut.getZ() - pos.getZ()); + int dist = MHelper.floor(6 - distRaw) + random.nextInt(2); + if (dist >= 0) { + state = world.getBlockState(mut); + while (!state.getFluidState().isEmpty() || state.getMaterial().equals(Material.WATER_PLANT)) { + mut.setY(mut.getY() - 1); + state = world.getBlockState(mut); + } + if (state.is(CommonBlockTags.GEN_END_STONES) && !world.getBlockState(mut.above()) + .is(EndBlocks.HYDROTHERMAL_VENT)) { + for (int j = 0; j <= dist; j++) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.SULPHURIC_ROCK.stone); + MHelper.shuffle(HORIZONTAL, random); + for (Direction dir : HORIZONTAL) { + BlockPos p = mut.relative(dir); + if (random.nextBoolean() && world.getBlockState(p).is(Blocks.WATER)) { + BlocksHelper.setWithoutUpdate( + world, + p, + EndBlocks.TUBE_WORM.defaultBlockState() + .setValue(HorizontalDirectionalBlock.FACING, dir) + ); + } + } + mut.setY(mut.getY() + 1); + } + state = EndBlocks.HYDROTHERMAL_VENT.defaultBlockState() + .setValue(HydrothermalVentBlock.ACTIVATED, distRaw < 2); + BlocksHelper.setWithoutUpdate(world, mut, state); + mut.setY(mut.getY() + 1); + state = world.getBlockState(mut); + while (state.is(Blocks.WATER)) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.VENT_BUBBLE_COLUMN.defaultBlockState()); + mut.setY(mut.getY() + 1); + state = world.getBlockState(mut); + } + } + } + } + + for (int i = 0; i < 10; i++) { + mut.set(pos) + .move( + MHelper.floor(random.nextGaussian() * 0.7 + 0.5), + -halfHeight - 10, + MHelper.floor(random.nextGaussian() * 0.7 + 0.5) + ); + float distRaw = MHelper.length(mut.getX() - pos.getX(), mut.getZ() - pos.getZ()); + int dist = MHelper.floor(6 - distRaw) + random.nextInt(2); + if (dist >= 0) { + state = world.getBlockState(mut); + while (state.is(Blocks.WATER)) { + mut.setY(mut.getY() - 1); + state = world.getBlockState(mut); + } + if (state.is(CommonBlockTags.GEN_END_STONES)) { + for (int j = 0; j <= dist; j++) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.SULPHURIC_ROCK.stone); + mut.setY(mut.getY() + 1); + } + state = EndBlocks.HYDROTHERMAL_VENT.defaultBlockState() + .setValue(HydrothermalVentBlock.ACTIVATED, distRaw < 2); + BlocksHelper.setWithoutUpdate(world, mut, state); + mut.setY(mut.getY() + 1); + state = world.getBlockState(mut); + while (state.is(Blocks.WATER)) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.VENT_BUBBLE_COLUMN.defaultBlockState()); + mut.setY(mut.getY() + 1); + state = world.getBlockState(mut); + } + } + } + } + + EndFeatures.SULPHURIC_LAKE.getFeature() + .place(new FeaturePlaceContext<>( + Optional.empty(), + world, + chunkGenerator, + random, + pos, + null + )); + + double distance = radius1 * 1.7; + BlockPos start = pos.offset(-distance, -halfHeight - 15 - distance, -distance); + BlockPos end = pos.offset(distance, -halfHeight - 5 + distance, distance); + BlockFixer.fixBlocks(world, start, end); + + return true; + } + + static { + REPLACE1 = (state) -> { + return state.isAir() || (state.is(CommonBlockTags.GEN_END_STONES)); + }; + + REPLACE2 = (state) -> { + if (state.is(CommonBlockTags.GEN_END_STONES) || state.is(EndBlocks.HYDROTHERMAL_VENT) || state.is(EndBlocks.SULPHUR_CRYSTAL)) { + return true; + } + if (state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + + IGNORE = (state) -> { + return state.is(Blocks.WATER) || state.is(Blocks.CAVE_AIR) || state.is(EndBlocks.SULPHURIC_ROCK.stone) || state + .is(EndBlocks.BRIMSTONE); + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/IceStarFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/IceStarFeature.java new file mode 100644 index 00000000..ef5ac55f --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/IceStarFeature.java @@ -0,0 +1,108 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFRotation; +import org.betterx.bclib.sdf.operator.SDFTranslate; +import org.betterx.bclib.sdf.operator.SDFUnion; +import org.betterx.bclib.sdf.primitive.SDFCappedCone; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; + +import java.util.ArrayList; +import java.util.List; + +public class IceStarFeature extends Feature { + + + public IceStarFeature() { + super(IceStarFeatureConfig.CODEC); + } + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + IceStarFeatureConfig cfg = featureConfig.config(); + float size = MHelper.randRange(cfg.minSize, cfg.maxSize, random); + int count = MHelper.randRange(cfg.minCount, cfg.maxCount, random); + List points = getFibonacciPoints(count); + SDF sdf = null; + SDF spike = new SDFCappedCone().setRadius1(3 + (size - 5) * 0.2F) + .setRadius2(0) + .setHeight(size) + .setBlock(EndBlocks.DENSE_SNOW); + spike = new SDFTranslate().setTranslate(0, size - 0.5F, 0).setSource(spike); + for (Vector3f point : points) { + SDF rotated = spike; + point = MHelper.normalize(point); + float angle = MHelper.angle(Vector3f.YP, point); + if (angle > 0.01F && angle < 3.14F) { + Vector3f axis = MHelper.normalize(MHelper.cross(Vector3f.YP, point)); + rotated = new SDFRotation().setRotation(axis, angle).setSource(spike); + } else if (angle > 1) { + rotated = new SDFRotation().setRotation(Vector3f.YP, (float) Math.PI).setSource(spike); + } + sdf = (sdf == null) ? rotated : new SDFUnion().setSourceA(sdf).setSourceB(rotated); + } + + int x1 = (pos.getX() >> 4) << 4; + int z1 = (pos.getZ() >> 4) << 4; + pos = new BlockPos(x1 + random.nextInt(16), MHelper.randRange(32, 128, random), z1 + random.nextInt(16)); + + final float ancientRadius = size * 0.7F; + final float denseRadius = size * 0.9F; + final float iceRadius = size < 7 ? size * 5 : size * 1.3F; + final float randScale = size * 0.3F; + + final BlockPos center = pos; + final BlockState ice = EndBlocks.EMERALD_ICE.defaultBlockState(); + final BlockState dense = EndBlocks.DENSE_EMERALD_ICE.defaultBlockState(); + final BlockState ancient = EndBlocks.ANCIENT_EMERALD_ICE.defaultBlockState(); + final SDF sdfCopy = sdf; + + sdf.addPostProcess((info) -> { + BlockPos bpos = info.getPos(); + float px = bpos.getX() - center.getX(); + float py = bpos.getY() - center.getY(); + float pz = bpos.getZ() - center.getZ(); + float distance = MHelper.length(px, py, pz) + sdfCopy.getDistance( + px, + py, + pz + ) * 0.4F + random.nextFloat() * randScale; + if (distance < ancientRadius) { + return ancient; + } else if (distance < denseRadius) { + return dense; + } else if (distance < iceRadius) { + return ice; + } + return info.getState(); + }).fillRecursive(world, pos); + + return true; + } + + private List getFibonacciPoints(int count) { + float max = count - 1; + List result = new ArrayList(count); + for (int i = 0; i < count; i++) { + float y = 1F - (i / max) * 2F; + float radius = (float) Math.sqrt(1F - y * y); + float theta = MHelper.PHI * i; + float x = (float) Math.cos(theta) * radius; + float z = (float) Math.sin(theta) * radius; + result.add(new Vector3f(x, y, z)); + } + return result; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/IceStarFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/terrain/IceStarFeatureConfig.java new file mode 100644 index 00000000..33e2b653 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/IceStarFeatureConfig.java @@ -0,0 +1,30 @@ +package org.betterx.betterend.world.features.terrain; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; + +public class IceStarFeatureConfig implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + Codec.FLOAT.fieldOf("min_size").forGetter(o -> o.minSize), + Codec.FLOAT.fieldOf("max_size").forGetter(o -> o.maxSize), + Codec.INT.fieldOf("min_count").forGetter(o -> o.minCount), + Codec.INT.fieldOf("max_count").forGetter(o -> o.maxCount) + ) + .apply(instance, IceStarFeatureConfig::new)); + + + public final float minSize; + public final float maxSize; + public final int minCount; + public final int maxCount; + + + public IceStarFeatureConfig(float minSize, float maxSize, int minCount, int maxCount) { + this.minSize = minSize; + this.maxSize = maxSize; + this.minCount = minCount; + this.maxCount = maxCount; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/ObsidianBoulderFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/ObsidianBoulderFeature.java new file mode 100644 index 00000000..ab273c42 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/ObsidianBoulderFeature.java @@ -0,0 +1,76 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFScale3D; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +public class ObsidianBoulderFeature extends DefaultFeature { + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + pos = getPosOnSurface( + world, + new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16)) + ); + if (!world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES)) { + return false; + } + + int count = MHelper.randRange(1, 5, random); + for (int i = 0; i < count; i++) { + BlockPos p = getPosOnSurface( + world, + new BlockPos(pos.getX() + random.nextInt(16) - 8, pos.getY(), pos.getZ() + random.nextInt(16) - 8) + ); + makeBoulder(world, p, random); + } + + return true; + } + + private void makeBoulder(WorldGenLevel world, BlockPos pos, RandomSource random) { + if (!world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES)) { + return; + } + + float radius = MHelper.randRange(1F, 5F, random); + SDF sphere = new SDFSphere().setRadius(radius).setBlock(Blocks.OBSIDIAN); + float sx = MHelper.randRange(0.7F, 1.3F, random); + float sy = MHelper.randRange(0.7F, 1.3F, random); + float sz = MHelper.randRange(0.7F, 1.3F, random); + sphere = new SDFScale3D().setScale(sx, sy, sz).setSource(sphere); + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + sphere = new SDFDisplacement().setFunction((vec) -> { + return (float) (noise.eval(vec.x() * 0.2, vec.y() * 0.2, vec.z() * 0.2) * 1.5F); + }).setSource(sphere); + + BlockState mossy = EndBlocks.MOSSY_OBSIDIAN.defaultBlockState(); + sphere.addPostProcess((info) -> { + if (info.getStateUp().isAir() && random.nextFloat() > 0.1F) { + return mossy; + } + return info.getState(); + }).setReplaceFunction((state) -> { + return state.getMaterial() + .isReplaceable() || state.is(CommonBlockTags.GEN_END_STONES) || state.getMaterial() + .equals(Material.PLANT); + }).fillRecursive(world, pos); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/ObsidianPillarBasementFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/ObsidianPillarBasementFeature.java new file mode 100644 index 00000000..855a241b --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/ObsidianPillarBasementFeature.java @@ -0,0 +1,74 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFRotation; +import org.betterx.bclib.sdf.operator.SDFSubtraction; +import org.betterx.bclib.sdf.operator.SDFTranslate; +import org.betterx.bclib.sdf.primitive.SDFCappedCone; +import org.betterx.bclib.sdf.primitive.SDFFlatland; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +public class ObsidianPillarBasementFeature extends DefaultFeature { + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + pos = getPosOnSurface( + world, + new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16)) + ); + if (!world.getBlockState(pos.below(5)).is(CommonBlockTags.GEN_END_STONES)) { + return false; + } + + float height = MHelper.randRange(10F, 35F, random); + float radius = MHelper.randRange(2F, 5F, random); + SDF pillar = new SDFCappedCone().setRadius1(radius) + .setRadius2(radius) + .setHeight(height * 0.5F) + .setBlock(Blocks.OBSIDIAN); + pillar = new SDFTranslate().setTranslate(0, height * 0.5F - 3, 0).setSource(pillar); + SDF cut = new SDFFlatland().setBlock(Blocks.OBSIDIAN); + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + cut = new SDFDisplacement().setFunction((vec) -> { + return (float) (noise.eval(vec.x() * 0.2, vec.z() * 0.2) * 3); + }).setSource(cut); + Vector3f vec = MHelper.randomHorizontal(random); + float angle = random.nextFloat() * 0.5F + (float) Math.PI; + cut = new SDFRotation().setRotation(vec, angle).setSource(cut); + cut = new SDFTranslate().setTranslate(0, height * 0.7F - 3, 0).setSource(cut); + pillar = new SDFSubtraction().setSourceA(pillar).setSourceB(cut); + vec = MHelper.randomHorizontal(random); + angle = random.nextFloat() * 0.2F; + pillar = new SDFRotation().setRotation(vec, angle).setSource(pillar); + BlockState mossy = EndBlocks.MOSSY_OBSIDIAN.defaultBlockState(); + pillar.addPostProcess((info) -> { + if (info.getStateUp().isAir() && random.nextFloat() > 0.1F) { + return mossy; + } + return info.getState(); + }).setReplaceFunction((state) -> { + return state.getMaterial() + .isReplaceable() || state.is(CommonBlockTags.GEN_END_STONES) || state.getMaterial() + .equals(Material.PLANT); + }).fillRecursive(world, pos); + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeature.java new file mode 100644 index 00000000..33ed406e --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeature.java @@ -0,0 +1,63 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFCoordModify; +import org.betterx.bclib.sdf.operator.SDFScale3D; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.MHelper; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; + +public class OreLayerFeature extends Feature { + private static final SDFSphere SPHERE; + private static final SDFCoordModify NOISE; + private static final SDF FUNCTION; + + + public OreLayerFeature() { + super(OreLayerFeatureConfig.CODEC); + } + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final OreLayerFeatureConfig cfg = featureConfig.config(); + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + float radius = cfg.radius * 0.5F; + int r = MHelper.floor(radius + 1); + int posX = MHelper.randRange(Math.max(r - 16, 0), Math.min(31 - r, 15), random) + pos.getX(); + int posZ = MHelper.randRange(Math.max(r - 16, 0), Math.min(31 - r, 15), random) + pos.getZ(); + int posY = MHelper.randRange(cfg.minY, cfg.maxY, random); + + + SPHERE.setRadius(radius).setBlock(cfg.state); + NOISE.setFunction((vec) -> { + double x = (vec.x() + pos.getX()) * 0.1; + double z = (vec.z() + pos.getZ()) * 0.1; + double offset = cfg.getNoise(world.getSeed()).eval(x, z); + vec.set(vec.x(), vec.y() + (float) offset * 8, vec.z()); + }); + FUNCTION.fillRecursive(world, new BlockPos(posX, posY, posZ)); + return true; + } + + static { + SPHERE = new SDFSphere(); + NOISE = new SDFCoordModify(); + + SDF body = SPHERE; + body = new SDFScale3D().setScale(1, 0.2F, 1).setSource(body); + body = NOISE.setSource(body); + body.setReplaceFunction((state) -> { + return state.is(Blocks.END_STONE); + }); + + FUNCTION = body; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeatureConfig.java new file mode 100644 index 00000000..87eb0015 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeatureConfig.java @@ -0,0 +1,39 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.betterend.noise.OpenSimplexNoise; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; + +public class OreLayerFeatureConfig implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockState.CODEC.fieldOf("state").forGetter(o -> o.state), + Codec.FLOAT.fieldOf("radius").forGetter(o -> o.radius), + Codec.INT.fieldOf("min_y").forGetter(o -> o.minY), + Codec.INT.fieldOf("max_y").forGetter(o -> o.maxY) + ) + .apply(instance, OreLayerFeatureConfig::new)); + + public final BlockState state; + public final float radius; + public final int minY; + public final int maxY; + private OpenSimplexNoise noise; + + public OreLayerFeatureConfig(BlockState state, float radius, int minY, int maxY) { + this.state = state; + this.radius = radius; + this.minY = minY; + this.maxY = maxY; + } + + public OpenSimplexNoise getNoise(long seed) { + if (noise == null) { + noise = new OpenSimplexNoise(seed); + } + return noise; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/SingleBlockFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/SingleBlockFeature.java new file mode 100644 index 00000000..ff0d1fc5 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/SingleBlockFeature.java @@ -0,0 +1,39 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.SimpleBlockConfiguration; + +public class SingleBlockFeature extends Feature { + public SingleBlockFeature() { + super(SimpleBlockConfiguration.CODEC); + } + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + final SimpleBlockConfiguration cfg = featureConfig.config(); + if (!world.getBlockState(pos.below()).is(CommonBlockTags.GEN_END_STONES)) { + return false; + } + + BlockState state = cfg.toPlace().getState(random, pos); + if (state.getBlock().getStateDefinition().getProperty("waterlogged") != null) { + boolean waterlogged = !world.getFluidState(pos).isEmpty(); + state = state.setValue(BlockStateProperties.WATERLOGGED, waterlogged); + } + BlocksHelper.setWithoutUpdate(world, pos, state); + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/SmaragdantCrystalFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/SmaragdantCrystalFeature.java new file mode 100644 index 00000000..0b7acfd2 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/SmaragdantCrystalFeature.java @@ -0,0 +1,63 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class SmaragdantCrystalFeature extends DefaultFeature { + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(CommonBlockTags.GEN_END_STONES)) { + return false; + } + + MutableBlockPos mut = new MutableBlockPos(); + int count = MHelper.randRange(15, 30, random); + BlockState crystal = EndBlocks.SMARAGDANT_CRYSTAL.defaultBlockState(); + BlockState shard = EndBlocks.SMARAGDANT_CRYSTAL_SHARD.defaultBlockState(); + for (int i = 0; i < count; i++) { + mut.set(pos) + .move(MHelper.floor(random.nextGaussian() * 2 + 0.5), 5, MHelper.floor(random.nextGaussian() * 2 + 0.5)); + int dist = MHelper.floor(1.5F - MHelper.length( + mut.getX() - pos.getX(), + mut.getZ() - pos.getZ() + )) + random.nextInt(3); + if (dist > 0) { + BlockState state = world.getBlockState(mut); + for (int n = 0; n < 10 && state.isAir(); n++) { + mut.setY(mut.getY() - 1); + state = world.getBlockState(mut); + } + if (state.is(CommonBlockTags.GEN_END_STONES) && !world.getBlockState(mut.above()) + .is(crystal.getBlock())) { + for (int j = 0; j <= dist; j++) { + BlocksHelper.setWithoutUpdate(world, mut, crystal); + mut.setY(mut.getY() + 1); + } + boolean waterlogged = !world.getFluidState(mut).isEmpty(); + BlocksHelper.setWithoutUpdate( + world, + mut, + shard.setValue(BlockStateProperties.WATERLOGGED, waterlogged) + ); + } + } + } + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/SpireFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/SpireFeature.java new file mode 100644 index 00000000..f24cd178 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/SpireFeature.java @@ -0,0 +1,126 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFSmoothUnion; +import org.betterx.bclib.sdf.operator.SDFTranslate; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBiomes; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +public class SpireFeature extends DefaultFeature { + protected static final Function REPLACE; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + final ChunkGenerator chunkGenerator = featureConfig.chunkGenerator(); + pos = getPosOnSurfaceWG(world, pos); + if (pos.getY() < 10 || !world.getBlockState(pos.below(3)) + .is(CommonBlockTags.GEN_END_STONES) || !world.getBlockState(pos.below(6)) + .is(CommonBlockTags.GEN_END_STONES)) { + return false; + } + + SDF sdf = new SDFSphere().setRadius(MHelper.randRange(2, 3, random)).setBlock(Blocks.END_STONE); + int count = MHelper.randRange(3, 7, random); + for (int i = 0; i < count; i++) { + float rMin = (i * 1.3F) + 2.5F; + sdf = addSegment(sdf, MHelper.randRange(rMin, rMin + 1.5F, random), random); + } + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + sdf = new SDFDisplacement().setFunction((vec) -> { + return (float) (Math.abs(noise.eval( + vec.x() * 0.1, + vec.y() * 0.1, + vec.z() * 0.1 + )) * 3F + Math.abs(noise.eval( + vec.x() * 0.3, + vec.y() * 0.3 + 100, + vec.z() * 0.3 + )) * 1.3F); + }).setSource(sdf); + final BlockPos center = pos; + List support = Lists.newArrayList(); + sdf.setReplaceFunction(REPLACE).addPostProcess((info) -> { + if (info.getStateUp().isAir()) { + if (random.nextInt(16) == 0) { + support.add(info.getPos().above()); + } + return EndBiome.findTopMaterial(world, info.getPos()); + //return world.getBiome(info.getPos()).getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); + } else if (info.getState(Direction.UP, 3).isAir()) { + return EndBiome.findUnderMaterial(world, info.getPos()); +// return world.getBiome(info.getPos()) +// .getGenerationSettings() +// .getSurfaceBuilderConfig() +// .getUnderMaterial(); + } + return info.getState(); + }).fillRecursive(world, center); + + support.forEach((bpos) -> { + if (BiomeAPI.getBiome(world.getBiome(bpos)) == EndBiomes.BLOSSOMING_SPIRES) { + EndFeatures.TENANEA_BUSH.getFeature() + .place(new FeaturePlaceContext( + Optional.empty(), + world, + chunkGenerator, + random, + bpos, + null + )); + } + }); + + return true; + } + + protected SDF addSegment(SDF sdf, float radius, RandomSource random) { + SDF sphere = new SDFSphere().setRadius(radius).setBlock(Blocks.END_STONE); + SDF offseted = new SDFTranslate().setTranslate(0, radius + random.nextFloat() * 0.25F * radius, 0) + .setSource(sdf); + return new SDFSmoothUnion().setRadius(radius * 0.5F).setSourceA(sphere).setSourceB(offseted); + } + + static { + REPLACE = (state) -> { + if (state.is(CommonBlockTags.END_STONES)) { + return true; + } + if (state.getBlock() instanceof LeavesBlock) { + return true; + } + if (state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/StalactiteFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/StalactiteFeature.java new file mode 100644 index 00000000..819fb0ce --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/StalactiteFeature.java @@ -0,0 +1,69 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.blocks.StalactiteBlock; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; + +public class StalactiteFeature extends Feature { + + public StalactiteFeature() { + super(StalactiteFeatureConfig.CODEC); + } + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + final StalactiteFeatureConfig cfg = featureConfig.config(); + if (!cfg.allowedGround.test(world, cfg.ceiling ? pos.above() : pos.below())) { + return false; + } + + MutableBlockPos mut = new MutableBlockPos().set(pos); + int height = random.nextInt(16); + int dir = cfg.ceiling ? -1 : 1; + boolean stalagnate = false; + + for (int i = 1; i <= height; i++) { + mut.setY(pos.getY() + i * dir); + BlockState state = world.getBlockState(mut); + if (!state.getMaterial().isReplaceable()) { + stalagnate = state.is(CommonBlockTags.GEN_END_STONES); + height = i; + break; + } + } + + if (!stalagnate && height > 7) { + height = random.nextInt(8); + } + + float center = height * 0.5F; + for (int i = 0; i < height; i++) { + mut.setY(pos.getY() + i * dir); + int size = stalagnate ? Mth.clamp((int) (Mth.abs(i - center) + 1), 1, 7) : height - i - 1; + boolean waterlogged = !world.getFluidState(mut).isEmpty(); + BlockState base = cfg.block.getState(random, mut) + .setValue(StalactiteBlock.SIZE, size) + .setValue(BlockStateProperties.WATERLOGGED, waterlogged); + BlockState state = stalagnate ? base.setValue( + StalactiteBlock.IS_FLOOR, + dir > 0 ? i < center : i > center + ) : base.setValue(StalactiteBlock.IS_FLOOR, dir > 0); + BlocksHelper.setWithoutUpdate(world, mut, state); + } + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/StalactiteFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/terrain/StalactiteFeatureConfig.java new file mode 100644 index 00000000..f68f7d12 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/StalactiteFeatureConfig.java @@ -0,0 +1,39 @@ +package org.betterx.betterend.world.features.terrain; + + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +public class StalactiteFeatureConfig implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + Codec.BOOL.fieldOf("ceiling").forGetter(o -> o.ceiling), + BlockStateProvider.CODEC.fieldOf("states").forGetter(o -> o.block), + BlockPredicate.CODEC.fieldOf("allowed_ground").forGetter(o -> o.allowedGround) + ) + .apply(instance, StalactiteFeatureConfig::new)); + + + public final boolean ceiling; + public final BlockStateProvider block; + public final BlockPredicate allowedGround; + + public StalactiteFeatureConfig(boolean ceiling, Block block, Block... ground) { + this( + ceiling, + SimpleStateProvider.simple(block), + net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate.matchesBlocks(ground) + ); + } + + public StalactiteFeatureConfig(boolean ceiling, BlockStateProvider block, BlockPredicate allowedGround) { + this.ceiling = ceiling; + this.block = block; + this.allowedGround = allowedGround; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/SulphurHillFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/SulphurHillFeature.java new file mode 100644 index 00000000..25ea87d0 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/SulphurHillFeature.java @@ -0,0 +1,96 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class SulphurHillFeature extends DefaultFeature { + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + pos = getPosOnSurfaceWG(world, pos); + if (pos.getY() < 57 || pos.getY() > 70) { + return false; + } + + int count = MHelper.randRange(5, 13, random); + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + for (int i = 0; i < count; i++) { + int dist = count - i; + int px = pos.getX() + MHelper.floor(random.nextGaussian() * dist * 0.6 + 0.5); + int pz = pos.getZ() + MHelper.floor(random.nextGaussian() * dist * 0.6 + 0.5); + int py = getYOnSurface(world, px, pz); + if (py > 56 && py - pos.getY() <= count) { + makeCircle(world, new BlockPos(px, py, pz), noise, random); + } + } + return true; + } + + private void makeCircle(WorldGenLevel world, BlockPos pos, OpenSimplexNoise noise, RandomSource random) { + int radius = MHelper.randRange(5, 9, random); + int min = -radius - 3; + int max = radius + 4; + MutableBlockPos mut = new MutableBlockPos(); + BlockState rock = EndBlocks.SULPHURIC_ROCK.stone.defaultBlockState(); + BlockState brimstone = EndBlocks.BRIMSTONE.defaultBlockState().setValue(BlockProperties.ACTIVE, true); + for (int x = min; x < max; x++) { + int x2 = x * x; + int px = pos.getX() + x; + mut.setX(px); + for (int z = min; z < max; z++) { + int z2 = z * z; + int pz = pos.getZ() + z; + mut.setZ(pz); + double r1 = radius * (noise.eval(px * 0.1, pz * 0.1) * 0.2 + 0.8); + double r2 = r1 - 1.5; + double r3 = r1 - 3; + int d = x2 + z2; + mut.setY(pos.getY()); + BlockState state = world.getBlockState(mut); + if (state.getMaterial().isReplaceable() || state.is(EndBlocks.HYDROTHERMAL_VENT)) { + if (d < r2 * r2) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.WATER); + mut.move(Direction.DOWN); + if (d < r3 * r3) { + BlocksHelper.setWithoutUpdate(world, mut, Blocks.WATER); + mut.move(Direction.DOWN); + } + BlocksHelper.setWithoutUpdate(world, mut, brimstone); + mut.move(Direction.DOWN); + state = world.getBlockState(mut); + int maxIt = MHelper.floor(10 - Math.sqrt(d)) + random.nextInt(1); + for (int i = 0; i < maxIt && state.getMaterial().isReplaceable(); i++) { + BlocksHelper.setWithoutUpdate(world, mut, rock); + mut.move(Direction.DOWN); + } + } else if (d < r1 * r1) { + BlocksHelper.setWithoutUpdate(world, mut, brimstone); + mut.move(Direction.DOWN); + state = world.getBlockState(mut); + int maxIt = MHelper.floor(10 - Math.sqrt(d)) + random.nextInt(1); + for (int i = 0; i < maxIt && state.getMaterial().isReplaceable(); i++) { + BlocksHelper.setWithoutUpdate(world, mut, rock); + mut.move(Direction.DOWN); + } + } + } + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/SulphuricCaveFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/SulphuricCaveFeature.java new file mode 100644 index 00000000..4f4da432 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/SulphuricCaveFeature.java @@ -0,0 +1,226 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.EndBlockProperties; +import org.betterx.betterend.blocks.SulphurCrystalBlock; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.util.BlockFixer; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.HorizontalDirectionalBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import com.google.common.collect.Sets; + +import java.util.Set; + +public class SulphuricCaveFeature extends DefaultFeature { + private static final BlockState CAVE_AIR = Blocks.CAVE_AIR.defaultBlockState(); + private static final BlockState WATER = Blocks.WATER.defaultBlockState(); + private static final Direction[] HORIZONTAL = BlocksHelper.makeHorizontal(); + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + int radius = MHelper.randRange(10, 30, random); + + int top = world.getHeight(Heightmap.Types.WORLD_SURFACE_WG, pos.getX(), pos.getZ()); + MutableBlockPos bpos = new MutableBlockPos(); + bpos.setX(pos.getX()); + bpos.setZ(pos.getZ()); + bpos.setY(top - 1); + + BlockState state = world.getBlockState(bpos); + while (!state.is(CommonBlockTags.GEN_END_STONES) && bpos.getY() > 5) { + bpos.setY(bpos.getY() - 1); + state = world.getBlockState(bpos); + } + if (bpos.getY() < 10) { + return false; + } + top = (int) (bpos.getY() - (radius * 1.3F + 5)); + + while (state.is(CommonBlockTags.GEN_END_STONES) || !state.getFluidState().isEmpty() && bpos.getY() > 5) { + bpos.setY(bpos.getY() - 1); + state = world.getBlockState(bpos); + } + int bottom = (int) (bpos.getY() + radius * 1.3F + 5); + + if (top <= bottom) { + return false; + } + + MutableBlockPos mut = new MutableBlockPos(); + pos = new BlockPos(pos.getX(), MHelper.randRange(bottom, top, random), pos.getZ()); + + OpenSimplexNoise noise = new OpenSimplexNoise(MHelper.getSeed(534, pos.getX(), pos.getZ())); + + int x1 = pos.getX() - radius - 5; + int z1 = pos.getZ() - radius - 5; + int x2 = pos.getX() + radius + 5; + int z2 = pos.getZ() + radius + 5; + int y1 = MHelper.floor(pos.getY() - (radius + 5) / 1.6); + int y2 = MHelper.floor(pos.getY() + (radius + 5) / 1.6); + + double hr = radius * 0.75; + double nr = radius * 0.25; + + Set brimstone = Sets.newHashSet(); + BlockState rock = EndBlocks.SULPHURIC_ROCK.stone.defaultBlockState(); + int waterLevel = pos.getY() + MHelper.randRange(MHelper.floor(radius * 0.8), radius, random); + for (int x = x1; x <= x2; x++) { + int xsq = x - pos.getX(); + xsq *= xsq; + mut.setX(x); + for (int z = z1; z <= z2; z++) { + int zsq = z - pos.getZ(); + zsq *= zsq; + mut.setZ(z); + for (int y = y1; y <= y2; y++) { + int ysq = y - pos.getY(); + ysq *= 1.6; + ysq *= ysq; + mut.setY(y); + double r = noise.eval(x * 0.1, y * 0.1, z * 0.1) * nr + hr; + double r2 = r + 5; + double dist = xsq + ysq + zsq; + if (dist < r * r) { + state = world.getBlockState(mut); + if (isReplaceable(state)) { + BlocksHelper.setWithoutUpdate(world, mut, y < waterLevel ? WATER : CAVE_AIR); + } + } else if (dist < r2 * r2) { + state = world.getBlockState(mut); + if (state.is(CommonBlockTags.GEN_END_STONES) || state.is(Blocks.AIR)) { + double v = noise.eval(x * 0.1, y * 0.1, z * 0.1) + noise.eval( + x * 0.03, + y * 0.03, + z * 0.03 + ) * 0.5; + if (v > 0.4) { + brimstone.add(mut.immutable()); + } else { + BlocksHelper.setWithoutUpdate(world, mut, rock); + } + } + } + } + } + } + brimstone.forEach((blockPos) -> { + placeBrimstone(world, blockPos, random); + }); + + if (random.nextInt(4) == 0) { + int count = MHelper.randRange(5, 20, random); + for (int i = 0; i < count; i++) { + mut.set(pos) + .move( + MHelper.floor(random.nextGaussian() * 2 + 0.5), + 0, + MHelper.floor(random.nextGaussian() * 2 + 0.5) + ); + int dist = MHelper.floor(3 - MHelper.length( + mut.getX() - pos.getX(), + mut.getZ() - pos.getZ() + )) + random.nextInt(2); + if (dist > 0) { + state = world.getBlockState(mut); + while (!state.getFluidState().isEmpty() || state.getMaterial().equals(Material.WATER_PLANT)) { + mut.setY(mut.getY() - 1); + state = world.getBlockState(mut); + } + if (state.is(CommonBlockTags.GEN_END_STONES) && !world.getBlockState(mut.above()) + .is(EndBlocks.HYDROTHERMAL_VENT)) { + for (int j = 0; j <= dist; j++) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.SULPHURIC_ROCK.stone); + MHelper.shuffle(HORIZONTAL, random); + for (Direction dir : HORIZONTAL) { + BlockPos p = mut.relative(dir); + if (random.nextBoolean() && world.getBlockState(p).is(Blocks.WATER)) { + BlocksHelper.setWithoutUpdate( + world, + p, + EndBlocks.TUBE_WORM.defaultBlockState() + .setValue(HorizontalDirectionalBlock.FACING, dir) + ); + } + } + mut.setY(mut.getY() + 1); + } + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.HYDROTHERMAL_VENT); + mut.setY(mut.getY() + 1); + state = world.getBlockState(mut); + while (state.is(Blocks.WATER)) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.VENT_BUBBLE_COLUMN.defaultBlockState()); + world.scheduleTick( + mut.immutable(), + EndBlocks.VENT_BUBBLE_COLUMN, + MHelper.randRange(8, 32, random) + ); + mut.setY(mut.getY() + 1); + state = world.getBlockState(mut); + } + } + } + } + } + + BlockFixer.fixBlocks(world, new BlockPos(x1, y1, z1), new BlockPos(x2, y2, z2)); + + return true; + } + + private boolean isReplaceable(BlockState state) { + return state.is(CommonBlockTags.GEN_END_STONES) || state.is(EndBlocks.HYDROTHERMAL_VENT) || state.is(EndBlocks.VENT_BUBBLE_COLUMN) || state + .is(EndBlocks.SULPHUR_CRYSTAL) || state.getMaterial().isReplaceable() || state.getMaterial() + .equals(Material.PLANT) || state + .getMaterial() + .equals(Material.WATER_PLANT) || state.getMaterial().equals(Material.LEAVES); + } + + private void placeBrimstone(WorldGenLevel world, BlockPos pos, RandomSource random) { + BlockState state = getBrimstone(world, pos); + BlocksHelper.setWithoutUpdate(world, pos, state); + if (state.getValue(EndBlockProperties.ACTIVE)) { + makeShards(world, pos, random); + } + } + + private BlockState getBrimstone(WorldGenLevel world, BlockPos pos) { + for (Direction dir : BlocksHelper.DIRECTIONS) { + if (world.getBlockState(pos.relative(dir)).is(Blocks.WATER)) { + return EndBlocks.BRIMSTONE.defaultBlockState().setValue(EndBlockProperties.ACTIVE, true); + } + } + return EndBlocks.BRIMSTONE.defaultBlockState(); + } + + private void makeShards(WorldGenLevel world, BlockPos pos, RandomSource random) { + for (Direction dir : BlocksHelper.DIRECTIONS) { + BlockPos side; + if (random.nextInt(16) == 0 && world.getBlockState((side = pos.relative(dir))).is(Blocks.WATER)) { + BlockState state = EndBlocks.SULPHUR_CRYSTAL.defaultBlockState() + .setValue(SulphurCrystalBlock.WATERLOGGED, true) + .setValue(SulphurCrystalBlock.FACING, dir) + .setValue(SulphurCrystalBlock.AGE, random.nextInt(3)); + BlocksHelper.setWithoutUpdate(world, side, state); + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/SulphuricLakeFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/SulphuricLakeFeature.java new file mode 100644 index 00000000..0bb99d72 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/SulphuricLakeFeature.java @@ -0,0 +1,213 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.EndBlockProperties; +import org.betterx.betterend.blocks.SulphurCrystalBlock; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.util.GlobalState; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Fluids; + +import com.google.common.collect.Sets; + +import java.util.Set; + +public class SulphuricLakeFeature extends DefaultFeature { + private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(15152); + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + BlockPos blockPos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + blockPos = getPosOnSurfaceWG(world, blockPos); + + if (blockPos.getY() < 57) { + return false; + } + + final RandomSource random = featureConfig.random(); + final MutableBlockPos POS = GlobalState.stateForThread().POS; + double radius = MHelper.randRange(10.0, 20.0, random); + int dist2 = MHelper.floor(radius * 1.5); + + int minX = blockPos.getX() - dist2; + int maxX = blockPos.getX() + dist2; + int minZ = blockPos.getZ() - dist2; + int maxZ = blockPos.getZ() + dist2; + + Set brimstone = Sets.newHashSet(); + for (int x = minX; x <= maxX; x++) { + POS.setX(x); + int x2 = x - blockPos.getX(); + x2 *= x2; + for (int z = minZ; z <= maxZ; z++) { + POS.setZ(z); + int z2 = z - blockPos.getZ(); + z2 *= z2; + double r = radius * (NOISE.eval(x * 0.2, z * 0.2) * 0.25 + 0.75); + double r2 = r * 1.5; + r *= r; + r2 *= r2; + int dist = x2 + z2; + if (dist <= r) { + POS.setY(getYOnSurface(world, x, z) - 1); + if (world.getBlockState(POS).is(CommonBlockTags.GEN_END_STONES)) { + if (isBorder(world, POS)) { + if (random.nextInt(8) > 0) { + brimstone.add(POS.immutable()); + if (random.nextBoolean()) { + brimstone.add(POS.below()); + if (random.nextBoolean()) { + brimstone.add(POS.below(2)); + } + } + } else { + if (!isAbsoluteBorder(world, POS)) { + BlocksHelper.setWithoutUpdate(world, POS, Blocks.WATER); + //world.setBlock(blockPos, Blocks.WATER.defaultBlockState(), 2); + world.scheduleTick(POS, Fluids.WATER, 0); + brimstone.add(POS.below()); + if (random.nextBoolean()) { + brimstone.add(POS.below(2)); + if (random.nextBoolean()) { + brimstone.add(POS.below(3)); + } + } + } else { + brimstone.add(POS.immutable()); + if (random.nextBoolean()) { + brimstone.add(POS.below()); + } + } + } + } else { + BlocksHelper.setWithoutUpdate(world, POS, Blocks.WATER); + brimstone.remove(POS); + for (Direction dir : BlocksHelper.HORIZONTAL) { + BlockPos offseted = POS.relative(dir); + if (world.getBlockState(offseted).is(CommonBlockTags.GEN_END_STONES)) { + brimstone.add(offseted); + } + } + if (isDeepWater(world, POS)) { + BlocksHelper.setWithoutUpdate(world, POS.move(Direction.DOWN), Blocks.WATER); + brimstone.remove(POS); + for (Direction dir : BlocksHelper.HORIZONTAL) { + BlockPos offseted = POS.relative(dir); + if (world.getBlockState(offseted).is(CommonBlockTags.GEN_END_STONES)) { + brimstone.add(offseted); + } + } + } + brimstone.add(POS.below()); + if (random.nextBoolean()) { + brimstone.add(POS.below(2)); + if (random.nextBoolean()) { + brimstone.add(POS.below(3)); + } + } + } + } + } else if (dist < r2) { + POS.setY(getYOnSurface(world, x, z) - 1); + if (world.getBlockState(POS).is(CommonBlockTags.GEN_END_STONES)) { + brimstone.add(POS.immutable()); + if (random.nextBoolean()) { + brimstone.add(POS.below()); + if (random.nextBoolean()) { + brimstone.add(POS.below(2)); + } + } + } + } + } + } + + brimstone.forEach((bpos) -> { + placeBrimstone(world, bpos, random); + }); + + return true; + } + + private boolean isBorder(WorldGenLevel world, BlockPos pos) { + int y = pos.getY() + 1; + for (Direction dir : BlocksHelper.DIRECTIONS) { + if (getYOnSurface(world, pos.getX() + dir.getStepX(), pos.getZ() + dir.getStepZ()) < y) { + return true; + } + } + return false; + } + + private boolean isAbsoluteBorder(WorldGenLevel world, BlockPos pos) { + int y = pos.getY() - 2; + for (Direction dir : BlocksHelper.DIRECTIONS) { + if (getYOnSurface(world, pos.getX() + dir.getStepX() * 3, pos.getZ() + dir.getStepZ() * 3) < y) { + return true; + } + } + return false; + } + + private boolean isDeepWater(WorldGenLevel world, BlockPos pos) { + int y = pos.getY() + 1; + for (Direction dir : BlocksHelper.DIRECTIONS) { + if (getYOnSurface(world, pos.getX() + dir.getStepX(), pos.getZ() + dir.getStepZ()) < y || getYOnSurface( + world, + pos.getX() + dir.getStepX() * 2, + pos.getZ() + dir.getStepZ() * 2 + ) < y || getYOnSurface( + world, + pos.getX() + dir.getStepX() * 3, + pos.getZ() + dir.getStepZ() * 3 + ) < y) { + return false; + } + } + return true; + } + + private void placeBrimstone(WorldGenLevel world, BlockPos pos, RandomSource random) { + BlockState state = getBrimstone(world, pos); + BlocksHelper.setWithoutUpdate(world, pos, state); + if (state.getValue(EndBlockProperties.ACTIVE)) { + makeShards(world, pos, random); + } + } + + private BlockState getBrimstone(WorldGenLevel world, BlockPos pos) { + for (Direction dir : BlocksHelper.DIRECTIONS) { + if (world.getBlockState(pos.relative(dir)).is(Blocks.WATER)) { + return EndBlocks.BRIMSTONE.defaultBlockState().setValue(EndBlockProperties.ACTIVE, true); + } + } + return EndBlocks.BRIMSTONE.defaultBlockState(); + } + + private void makeShards(WorldGenLevel world, BlockPos pos, RandomSource random) { + for (Direction dir : BlocksHelper.DIRECTIONS) { + BlockPos side; + if (random.nextInt(16) == 0 && world.getBlockState((side = pos.relative(dir))).is(Blocks.WATER)) { + BlockState state = EndBlocks.SULPHUR_CRYSTAL.defaultBlockState() + .setValue(SulphurCrystalBlock.WATERLOGGED, true) + .setValue(SulphurCrystalBlock.FACING, dir) + .setValue(SulphurCrystalBlock.AGE, random.nextInt(3)); + BlocksHelper.setWithoutUpdate(world, side, state); + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/SurfaceVentFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/SurfaceVentFeature.java new file mode 100644 index 00000000..bdb0b566 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/SurfaceVentFeature.java @@ -0,0 +1,62 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.HydrothermalVentBlock; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class SurfaceVentFeature extends DefaultFeature { + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + pos = getPosOnSurface( + world, + new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16)) + ); + if (!world.getBlockState(pos.below(3)).is(CommonBlockTags.GEN_END_STONES)) { + return false; + } + + MutableBlockPos mut = new MutableBlockPos(); + int count = MHelper.randRange(15, 30, random); + BlockState vent = EndBlocks.HYDROTHERMAL_VENT.defaultBlockState() + .setValue(HydrothermalVentBlock.WATERLOGGED, false); + for (int i = 0; i < count; i++) { + mut.set(pos) + .move(MHelper.floor(random.nextGaussian() * 2 + 0.5), 5, MHelper.floor(random.nextGaussian() * 2 + 0.5)); + int dist = MHelper.floor(2 - MHelper.length( + mut.getX() - pos.getX(), + mut.getZ() - pos.getZ() + )) + random.nextInt(2); + if (dist > 0) { + BlockState state = world.getBlockState(mut); + for (int n = 0; n < 10 && state.isAir(); n++) { + mut.setY(mut.getY() - 1); + state = world.getBlockState(mut); + } + if (state.is(CommonBlockTags.GEN_END_STONES) && !world.getBlockState(mut.above()) + .is(EndBlocks.HYDROTHERMAL_VENT)) { + for (int j = 0; j <= dist; j++) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.SULPHURIC_ROCK.stone); + mut.setY(mut.getY() + 1); + } + BlocksHelper.setWithoutUpdate(world, mut, vent); + } + } + } + + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeature.java new file mode 100644 index 00000000..9324b963 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeature.java @@ -0,0 +1,90 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFCoordModify; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFRotation; +import org.betterx.bclib.sdf.operator.SDFUnion; +import org.betterx.bclib.sdf.primitive.SDFTorus; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; + +public class ThinArchFeature extends Feature { + + public ThinArchFeature() { + super(ThinArchFeatureConfig.CODEC); + } + + @Override + public boolean place(FeaturePlaceContext featurePlaceContext) { + final ThinArchFeatureConfig cfg = featurePlaceContext.config(); + final WorldGenLevel world = featurePlaceContext.level(); + BlockPos origin = featurePlaceContext.origin(); + RandomSource random = featurePlaceContext.random(); + BlockState state = cfg.block.getState(random, origin); + Block block = state.getBlock(); + + BlockPos pos = DefaultFeature.getPosOnSurfaceWG( + world, + new BlockPos( + (origin.getX() & 0xFFFFFFF0) | 7, + 0, + (origin.getZ() & 0xFFFFFFF0) | 7 + ) + ); + if (!world.getBlockState(pos.below(5)).is(CommonBlockTags.GEN_END_STONES)) { + return false; + } + + SDF sdf = null; + float bigRadius = MHelper.randRange(15F, 20F, random); + float variation = bigRadius * 0.3F; + int count = MHelper.randRange(2, 4, random); + + for (int i = 0; i < count; i++) { + float smallRadius = MHelper.randRange(0.6F, 1.3F, random); + SDF arch = new SDFTorus().setBigRadius(bigRadius - random.nextFloat() * variation) + .setSmallRadius(smallRadius) + .setBlock(block); + float angle = (i - count * 0.5F) * 0.3F + random.nextFloat() * 0.05F + (float) Math.PI * 0.5F; + arch = new SDFRotation().setRotation(Vector3f.XP, angle).setSource(arch); + sdf = sdf == null ? arch : new SDFUnion().setSourceA(sdf).setSourceB(arch); + } + + sdf = new SDFRotation().setRotation(MHelper.randomHorizontal(random), random.nextFloat() * MHelper.PI2) + .setSource(sdf); + + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + sdf = new SDFCoordModify().setFunction(vec -> { + float dx = (float) noise.eval(vec.y() * 0.02, vec.z() * 0.02); + float dy = (float) noise.eval(vec.x() * 0.02, vec.z() * 0.02); + float dz = (float) noise.eval(vec.x() * 0.02, vec.y() * 0.02); + vec.add(dx * 10, dy * 10, dz * 10); + }).setSource(sdf); + sdf = new SDFDisplacement().setFunction(vec -> { + float offset = vec.y() / bigRadius - 0.5F; + return Mth.clamp(offset * 3, -10F, 0F); + }).setSource(sdf); + + float side = (bigRadius + 2.5F) * 2; + if (side > 47) { + side = 47; + } + sdf.fillArea(world, pos, AABB.ofSize(Vec3.atCenterOf(pos), side, side, side)); + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeatureConfig.java new file mode 100644 index 00000000..e0531836 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeatureConfig.java @@ -0,0 +1,28 @@ +package org.betterx.betterend.world.features.terrain; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +public class ThinArchFeatureConfig implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("states").forGetter(o -> o.block) + ) + .apply(instance, ThinArchFeatureConfig::new)); + + + public final BlockStateProvider block; + + public ThinArchFeatureConfig(Block block) { + this(SimpleStateProvider.simple(block)); + } + + public ThinArchFeatureConfig(BlockStateProvider block) { + this.block = block; + } +} + diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java new file mode 100644 index 00000000..0f2a41e4 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java @@ -0,0 +1,157 @@ +package org.betterx.betterend.world.features.terrain.caves; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.util.BlockFixer; +import org.betterx.betterend.world.biome.cave.EndCaveBiome; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; + +import com.google.common.collect.Sets; + +import java.util.Set; + +public class CaveChunkPopulatorFeature extends Feature { + + public CaveChunkPopulatorFeature() { + super(CaveChunkPopulatorFeatureConfig.CODEC); + } + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + CaveChunkPopulatorFeatureConfig cfg = featureConfig.config(); + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + final ChunkGenerator chunkGenerator = featureConfig.chunkGenerator(); + Set floorPositions = Sets.newHashSet(); + Set ceilPositions = Sets.newHashSet(); + int sx = (pos.getX() >> 4) << 4; + int sz = (pos.getZ() >> 4) << 4; + MutableBlockPos min = new MutableBlockPos().set(pos); + MutableBlockPos max = new MutableBlockPos().set(pos); + fillSets(sx, sz, world.getChunk(pos), floorPositions, ceilPositions, min, max); + EndCaveBiome biome = cfg.getCaveBiome(); + BlockState surfaceBlock = Blocks.END_STONE.defaultBlockState(); //biome.getBiome().getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); + placeFloor(world, chunkGenerator, biome, floorPositions, random, surfaceBlock); + placeCeil(world, chunkGenerator, biome, ceilPositions, random); + BlockFixer.fixBlocks(world, min, max); + return true; + } + + protected void fillSets( + int sx, + int sz, + ChunkAccess chunk, + Set floorPositions, + Set ceilPositions, + MutableBlockPos min, + MutableBlockPos max + ) { + MutableBlockPos mut = new MutableBlockPos(); + MutableBlockPos mut2 = new MutableBlockPos(); + MutableBlockPos mut3 = new MutableBlockPos(); + for (int x = 0; x < 16; x++) { + mut.setX(x); + mut2.setX(x); + for (int z = 0; z < 16; z++) { + mut.setZ(z); + mut2.setZ(z); + mut2.setY(0); + for (int y = 1; y < chunk.getMaxBuildHeight(); y++) { + mut.setY(y); + BlockState top = chunk.getBlockState(mut); + BlockState bottom = chunk.getBlockState(mut2); + if (top.isAir() && (bottom.is(CommonBlockTags.GEN_END_STONES) || bottom.is(Blocks.STONE))) { + mut3.set(mut2).move(sx, 0, sz); + floorPositions.add(mut3.immutable()); + updateMin(mut3, min); + updateMax(mut3, max); + } else if (bottom.isAir() && (top.is(CommonBlockTags.GEN_END_STONES) || top.is(Blocks.STONE))) { + mut3.set(mut).move(sx, 0, sz); + ceilPositions.add(mut3.immutable()); + updateMin(mut3, min); + updateMax(mut3, max); + } + mut2.setY(y); + } + } + } + } + + private void updateMin(BlockPos pos, MutableBlockPos min) { + if (pos.getX() < min.getX()) { + min.setX(pos.getX()); + } + if (pos.getY() < min.getY()) { + min.setY(pos.getY()); + } + if (pos.getZ() < min.getZ()) { + min.setZ(pos.getZ()); + } + } + + private void updateMax(BlockPos pos, MutableBlockPos max) { + if (pos.getX() > max.getX()) { + max.setX(pos.getX()); + } + if (pos.getY() > max.getY()) { + max.setY(pos.getY()); + } + if (pos.getZ() > max.getZ()) { + max.setZ(pos.getZ()); + } + } + + protected void placeFloor( + WorldGenLevel world, + ChunkGenerator generator, + EndCaveBiome biome, + Set floorPositions, + RandomSource random, + BlockState surfaceBlock + ) { + float density = biome.getFloorDensity(); + floorPositions.forEach((pos) -> { + BlocksHelper.setWithoutUpdate(world, pos, surfaceBlock); + if (density > 0 && random.nextFloat() <= density) { + ConfiguredFeature feature = biome.getFloorFeature(random).value(); + if (feature != null) { + feature.place(world, generator, random, pos.above()); + } + } + }); + } + + protected void placeCeil( + WorldGenLevel world, + ChunkGenerator generator, + EndCaveBiome biome, + Set ceilPositions, + RandomSource random + ) { + float density = biome.getCeilDensity(); + ceilPositions.forEach((pos) -> { + BlockState ceilBlock = biome.getCeil(pos); + if (ceilBlock != null) { + BlocksHelper.setWithoutUpdate(world, pos, ceilBlock); + } + if (density > 0 && random.nextFloat() <= density) { + ConfiguredFeature feature = biome.getCeilFeature(random).value(); + if (feature != null) { + feature.place(world, generator, random, pos.below()); + } + } + }); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeatureConfig.java new file mode 100644 index 00000000..a272dc9a --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeatureConfig.java @@ -0,0 +1,19 @@ +package org.betterx.betterend.world.features.terrain.caves; + +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.betterend.world.biome.cave.EndCaveBiome; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; + +public record CaveChunkPopulatorFeatureConfig(ResourceLocation biomeID) implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group(ResourceLocation.CODEC.fieldOf("biome").forGetter(o -> o.biomeID)) + .apply(instance, CaveChunkPopulatorFeatureConfig::new)); + + public EndCaveBiome getCaveBiome() { + return (EndCaveBiome) BiomeAPI.getBiome(biomeID); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/caves/EndCaveFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/caves/EndCaveFeature.java new file mode 100644 index 00000000..0029a26f --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/caves/EndCaveFeature.java @@ -0,0 +1,287 @@ +package org.betterx.betterend.world.features.terrain.caves; + +import org.betterx.bclib.api.v2.generator.BiomePicker; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBiomes; +import org.betterx.betterend.util.BlockFixer; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.betterend.world.biome.cave.EndCaveBiome; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.core.Vec3i; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +import java.util.List; +import java.util.Set; + +public abstract class EndCaveFeature extends DefaultFeature { + protected static final BlockState CAVE_AIR = Blocks.CAVE_AIR.defaultBlockState(); + protected static final BlockState END_STONE = Blocks.END_STONE.defaultBlockState(); + protected static final BlockState WATER = Blocks.WATER.defaultBlockState(); + private static final Vec3i[] SPHERE; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (pos.getX() * pos.getX() + pos.getZ() * pos.getZ() <= 2500) { + return false; + } + + if (biomeMissingCaves(world, pos)) { + return false; + } + + int radius = MHelper.randRange(10, 30, random); + BlockPos center = findPos(world, pos, radius, random); + + if (center == null) { + return false; + } + + BiomePicker.ActualBiome biome = EndBiomes.getCaveBiome(pos.getX(), pos.getZ()); + Set caveBlocks = generate(world, center, radius, random); + if (!caveBlocks.isEmpty()) { + if (biome != null) { + ChunkGenerator generator = featureConfig.chunkGenerator(); + setBiomes(world, biome, caveBlocks); + Set floorPositions = Sets.newConcurrentHashSet(); + Set ceilPositions = Sets.newConcurrentHashSet(); + caveBlocks.parallelStream().forEach((bpos) -> { + if (world.getBlockState(bpos).getMaterial().isReplaceable()) { + BlockPos side = bpos.below(); + if (world.getBlockState(side).is(CommonBlockTags.GEN_END_STONES)) { + floorPositions.add(side); + } + side = bpos.above(); + if (world.getBlockState(side).is(CommonBlockTags.GEN_END_STONES)) { + ceilPositions.add(side); + } + } + }); + + BlockState surfaceBlock = EndBiome.findTopMaterial(biome.bclBiome); + placeFloor(world, generator, (EndCaveBiome) biome.bclBiome, floorPositions, random, surfaceBlock); + placeCeil(world, generator, (EndCaveBiome) biome.bclBiome, ceilPositions, random); + placeWalls(world, generator, (EndCaveBiome) biome.bclBiome, caveBlocks, random); + } + fixBlocks(world, caveBlocks); + } + + return true; + } + + protected abstract Set generate(WorldGenLevel world, BlockPos center, int radius, RandomSource random); + + protected void placeFloor( + WorldGenLevel world, + ChunkGenerator generator, + EndCaveBiome biome, + Set floorPositions, + RandomSource random, + BlockState surfaceBlock + ) { + float density = biome.getFloorDensity(); + floorPositions.forEach((pos) -> { + if (!surfaceBlock.is(Blocks.END_STONE)) { + BlocksHelper.setWithoutUpdate(world, pos, surfaceBlock); + } + if (density > 0 && random.nextFloat() <= density) { + Holder> feature = biome.getFloorFeature(random); + if (feature != null && feature.isBound()) { + feature.value().place(world, generator, random, pos.above()); + } + } + }); + } + + protected void placeCeil( + WorldGenLevel world, + ChunkGenerator generator, + EndCaveBiome biome, + Set ceilPositions, + RandomSource random + ) { + float density = biome.getCeilDensity(); + ceilPositions.forEach((pos) -> { + BlockState ceilBlock = biome.getCeil(pos); + if (ceilBlock != null) { + BlocksHelper.setWithoutUpdate(world, pos, ceilBlock); + } + if (density > 0 && random.nextFloat() <= density) { + Holder> feature = biome.getCeilFeature(random); + if (feature != null && feature.isBound()) { + feature.value().place(world, generator, random, pos.below()); + } + } + }); + } + + protected void placeWalls( + WorldGenLevel world, + ChunkGenerator generator, + EndCaveBiome biome, + Set positions, + RandomSource random + ) { + Set placed = Sets.newHashSet(); + positions.forEach(pos -> { + if (random.nextInt(4) == 0 && hasOpenSide(pos, positions)) { + BlockState wallBlock = biome.getWall(pos); + if (wallBlock != null) { + for (Vec3i offset : SPHERE) { + BlockPos wallPos = pos.offset(offset); + if (!positions.contains(wallPos) && !placed.contains(wallPos) && world.getBlockState(wallPos) + .is(CommonBlockTags.GEN_END_STONES)) { + wallBlock = biome.getWall(wallPos); + BlocksHelper.setWithoutUpdate(world, wallPos, wallBlock); + placed.add(wallPos); + } + } + } + } + }); + } + + private boolean hasOpenSide(BlockPos pos, Set positions) { + for (Direction dir : BlocksHelper.DIRECTIONS) { + if (!positions.contains(pos.relative(dir))) { + return true; + } + } + return false; + } + + protected void setBiomes(WorldGenLevel world, BiomePicker.ActualBiome biome, Set blocks) { + blocks.forEach((pos) -> setBiome(world, pos, biome)); + } + + protected void setBiome(WorldGenLevel world, BlockPos pos, BiomePicker.ActualBiome biome) { + BiomeAPI.setBiome(world, pos, biome.biome); + } + + private BlockPos findPos(WorldGenLevel world, BlockPos pos, int radius, RandomSource random) { + int top = world.getHeight(Heightmap.Types.WORLD_SURFACE_WG, pos.getX(), pos.getZ()); + MutableBlockPos bpos = new MutableBlockPos(); + bpos.setX(pos.getX()); + bpos.setZ(pos.getZ()); + bpos.setY(top - 1); + + BlockState state = world.getBlockState(bpos); + while (!state.is(CommonBlockTags.GEN_END_STONES) && bpos.getY() > 5) { + bpos.setY(bpos.getY() - 1); + state = world.getBlockState(bpos); + } + if (bpos.getY() < 10) { + return null; + } + top = (int) (bpos.getY() - (radius * 1.3F + 5)); + + while (state.is(CommonBlockTags.GEN_END_STONES) || !state.getFluidState().isEmpty() && bpos.getY() > 5) { + bpos.setY(bpos.getY() - 1); + state = world.getBlockState(bpos); + } + int bottom = (int) (bpos.getY() + radius * 1.3F + 5); + + if (top <= bottom) { + return null; + } + + return new BlockPos(pos.getX(), MHelper.randRange(bottom, top, random), pos.getZ()); + } + + protected void fixBlocks(WorldGenLevel world, Set caveBlocks) { + BlockPos pos = caveBlocks.iterator().next(); + MutableBlockPos start = new MutableBlockPos().set(pos); + MutableBlockPos end = new MutableBlockPos().set(pos); + caveBlocks.forEach((bpos) -> { + if (bpos.getX() < start.getX()) { + start.setX(bpos.getX()); + } + if (bpos.getX() > end.getX()) { + end.setX(bpos.getX()); + } + + if (bpos.getY() < start.getY()) { + start.setY(bpos.getY()); + } + if (bpos.getY() > end.getY()) { + end.setY(bpos.getY()); + } + + if (bpos.getZ() < start.getZ()) { + start.setZ(bpos.getZ()); + } + if (bpos.getZ() > end.getZ()) { + end.setZ(bpos.getZ()); + } + }); + BlockFixer.fixBlocks(world, start.offset(-2, -2, -2), end.offset(2, 2, 2)); + } + + protected boolean isWaterNear(WorldGenLevel world, BlockPos pos) { + for (Direction dir : BlocksHelper.DIRECTIONS) { + if (!world.getFluidState(pos.relative(dir, 5)).isEmpty()) { + return true; + } + } + return false; + } + + protected boolean biomeMissingCaves(WorldGenLevel world, BlockPos pos) { + for (int x = -2; x < 3; x++) { + for (int z = -2; z < 3; z++) { + Holder biome = world.getBiome(pos.offset(x << 4, 0, z << 4)); + BCLBiome bclBiome = BiomeAPI.getBiome(biome); + boolean hasCaves = true; + if (bclBiome instanceof EndBiome endBiome) + hasCaves = endBiome.hasCaves(); + + if (!hasCaves && BiomeAPI.wasRegisteredAsEndLandBiome(bclBiome.getID())) { + return true; + } + } + } + return false; + } + + static { + List prePos = Lists.newArrayList(); + int radius = 5; + int r2 = radius * radius; + for (int x = -radius; x <= radius; x++) { + int x2 = x * x; + for (int y = -radius; y <= radius; y++) { + int y2 = y * y; + for (int z = -radius; z <= radius; z++) { + int z2 = z * z; + if (x2 + y2 + z2 < r2) { + prePos.add(new Vec3i(x, y, z)); + } + } + } + } + SPHERE = prePos.toArray(new Vec3i[]{}); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/caves/RoundCaveFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/caves/RoundCaveFeature.java new file mode 100644 index 00000000..9e334e3b --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/caves/RoundCaveFeature.java @@ -0,0 +1,84 @@ +package org.betterx.betterend.world.features.terrain.caves; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Material; + +import com.google.common.collect.Sets; + +import java.util.Set; +import java.util.stream.IntStream; + +public class RoundCaveFeature extends EndCaveFeature { + @Override + protected Set generate(WorldGenLevel world, BlockPos center, int radius, RandomSource random) { + OpenSimplexNoise noise = new OpenSimplexNoise(MHelper.getSeed(534, center.getX(), center.getZ())); + + int x1 = center.getX() - radius - 5; + int z1 = center.getZ() - radius - 5; + int x2 = center.getX() + radius + 5; + int z2 = center.getZ() + radius + 5; + int y1 = MHelper.floor(center.getY() - (radius + 5) / 1.6); + int y2 = MHelper.floor(center.getY() + (radius + 5) / 1.6); + + double hr = radius * 0.75; + double nr = radius * 0.25; + + int dx = x2 - x1 + 1; + int dz = z2 - z1 + 1; + int count = dx * dz; + Set blocks = Sets.newConcurrentHashSet(); + IntStream.range(0, count).parallel().forEach(index -> { + MutableBlockPos bpos = new MutableBlockPos(); + int x = (index % dx) + x1; + int z = (index / dx) + z1; + bpos.setX(x); + bpos.setZ(z); + int xsq = MHelper.sqr(x - center.getX()); + int zsq = MHelper.sqr(z - center.getZ()); + int dxz = xsq + zsq; + BlockState state; + for (int y = y1; y <= y2; y++) { + int ysq = (int) MHelper.sqr((y - center.getY()) * 1.6); + double r = noise.eval(x * 0.1, y * 0.1, z * 0.1) * nr + hr; + double dist = dxz + ysq; + if (dist < r * r) { + bpos.setY(y); + state = world.getBlockState(bpos); + if (isReplaceable(state) && !isWaterNear(world, bpos)) { + blocks.add(bpos.immutable()); + + while (state.getMaterial().equals(Material.LEAVES)) { + bpos.setY(bpos.getY() + 1); + state = world.getBlockState(bpos); + } + + bpos.setY(y - 1); + while (state.getMaterial().equals(Material.LEAVES)) { + bpos.setY(bpos.getY() - 1); + state = world.getBlockState(bpos); + } + } + } + } + }); + blocks.forEach(bpos -> BlocksHelper.setWithoutUpdate(world, bpos, CAVE_AIR)); + + return blocks; + } + + private boolean isReplaceable(BlockState state) { + return state.is(CommonBlockTags.GEN_END_STONES) || + state.getMaterial().isReplaceable() || + state.getMaterial().equals(Material.PLANT) || + state.getMaterial().equals(Material.LEAVES); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/caves/TunelCaveFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/caves/TunelCaveFeature.java new file mode 100644 index 00000000..6a7d98f6 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/caves/TunelCaveFeature.java @@ -0,0 +1,267 @@ +package org.betterx.betterend.world.features.terrain.caves; + +import org.betterx.bclib.api.v2.generator.BiomePicker; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBiomes; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.betterend.world.biome.cave.EndCaveBiome; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.level.levelgen.LegacyRandomSource; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import java.util.Map; +import java.util.Set; +import java.util.stream.IntStream; + +public class TunelCaveFeature extends EndCaveFeature { + private Set generate(WorldGenLevel world, BlockPos center, RandomSource random) { + int cx = center.getX() >> 4; + int cz = center.getZ() >> 4; + if ((long) cx * (long) cx + (long) cz + (long) cz < 256) { + return Sets.newHashSet(); + } + + int x1 = cx << 4; + int z1 = cz << 4; + int x2 = x1 + 16; + int z2 = z1 + 16; + + RandomSource rand = new LegacyRandomSource(world.getSeed()); + OpenSimplexNoise noiseH = new OpenSimplexNoise(rand.nextInt()); + OpenSimplexNoise noiseV = new OpenSimplexNoise(rand.nextInt()); + OpenSimplexNoise noiseD = new OpenSimplexNoise(rand.nextInt()); + + Set positions = Sets.newConcurrentHashSet(); + + float a = hasCaves(world, new BlockPos(x1, 0, z1)) ? 1F : 0F; + float b = hasCaves(world, new BlockPos(x2, 0, z1)) ? 1F : 0F; + float c = hasCaves(world, new BlockPos(x1, 0, z2)) ? 1F : 0F; + float d = hasCaves(world, new BlockPos(x2, 0, z2)) ? 1F : 0F; + + ChunkAccess chunk = world.getChunk(cx, cz); + IntStream.range(0, 256).parallel().forEach(index -> { + MutableBlockPos pos = new MutableBlockPos(); + int x = index & 15; + int z = index >> 4; + int wheight = chunk.getHeight(Types.WORLD_SURFACE_WG, x, z); + float dx = x / 16F; + float dz = z / 16F; + pos.setX(x + x1); + pos.setZ(z + z1); + float da = Mth.lerp(dx, a, b); + float db = Mth.lerp(dx, c, d); + float density = 1 - Mth.lerp(dz, da, db); + if (density < 0.5) { + for (int y = 0; y < wheight; y++) { + pos.setY(y); + float gradient = 1 - Mth.clamp((wheight - y) * 0.1F, 0F, 1F); + if (gradient > 0.5) { + break; + } + float val = Mth.abs((float) noiseH.eval(pos.getX() * 0.02, y * 0.01, pos.getZ() * 0.02)); + float vert = Mth.sin((y + (float) noiseV.eval( + pos.getX() * 0.01, + pos.getZ() * 0.01 + ) * 20) * 0.1F) * 0.9F; + float dist = (float) noiseD.eval(pos.getX() * 0.1, y * 0.1, pos.getZ() * 0.1) * 0.12F; + val = (val + vert * vert + dist) + density + gradient; + if (val < 0.15 && world.getBlockState(pos).is(CommonBlockTags.GEN_END_STONES) && noWaterNear( + world, + pos + )) { + positions.add(pos.immutable()); + } + } + } + }); + positions.forEach(bpos -> BlocksHelper.setWithoutUpdate(world, bpos, CAVE_AIR)); + + return positions; + } + + private boolean noWaterNear(WorldGenLevel world, BlockPos pos) { + BlockPos above1 = pos.above(); + BlockPos above2 = pos.above(2); + if (!world.getFluidState(above1).isEmpty() || !world.getFluidState(above2).isEmpty()) { + return false; + } + for (Direction dir : BlocksHelper.HORIZONTAL) { + if (!world.getFluidState(above1.relative(dir)).isEmpty()) { + return false; + } + if (!world.getFluidState(above2.relative(dir)).isEmpty()) { + return false; + } + } + return true; + } + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (pos.getX() * pos.getX() + pos.getZ() * pos.getZ() <= 2500) { + return false; + } + + if (biomeMissingCaves(world, pos)) { + return false; + } + + Set caveBlocks = generate(world, pos, random); + if (caveBlocks.isEmpty()) { + return false; + } + + final ChunkGenerator generator = featureConfig.chunkGenerator(); + Map> floorSets = Maps.newHashMap(); + Map> ceilSets = Maps.newHashMap(); + MutableBlockPos mut = new MutableBlockPos(); + Set remove = Sets.newHashSet(); + caveBlocks.forEach((bpos) -> { + mut.set(bpos); + BiomePicker.ActualBiome bio = EndBiomes.getCaveBiome(bpos.getX(), bpos.getZ()); + int height = world.getHeight(Types.WORLD_SURFACE, bpos.getX(), bpos.getZ()); + if (mut.getY() >= height) { + remove.add(bpos); + } else if (world.getBlockState(mut).getMaterial().isReplaceable()) { + mut.setY(bpos.getY() - 1); + if (world.getBlockState(mut).is(CommonBlockTags.GEN_END_STONES)) { + Set floorPositions = floorSets.get(bio); + if (floorPositions == null) { + floorPositions = Sets.newHashSet(); + floorSets.put(bio, floorPositions); + } + floorPositions.add(mut.immutable()); + } + mut.setY(bpos.getY() + 1); + if (world.getBlockState(mut).is(CommonBlockTags.GEN_END_STONES)) { + Set ceilPositions = ceilSets.get(bio); + if (ceilPositions == null) { + ceilPositions = Sets.newHashSet(); + ceilSets.put(bio, ceilPositions); + } + ceilPositions.add(mut.immutable()); + } + setBiome(world, bpos, bio); + } + }); + caveBlocks.removeAll(remove); + + if (caveBlocks.isEmpty()) { + return true; + } + + floorSets.forEach((biome, floorPositions) -> { + BlockState surfaceBlock = EndBiome.findTopMaterial(biome.bclBiome); + placeFloor(world, generator, (EndCaveBiome) biome.bclBiome, floorPositions, random, surfaceBlock); + }); + ceilSets.forEach((biome, ceilPositions) -> { + placeCeil(world, generator, (EndCaveBiome) biome.bclBiome, ceilPositions, random); + }); + BiomePicker.ActualBiome biome = EndBiomes.getCaveBiome(pos.getX(), pos.getZ()); + placeWalls(world, generator, (EndCaveBiome) biome.bclBiome, caveBlocks, random); + fixBlocks(world, caveBlocks); + + return true; + } + + @Override + protected Set generate(WorldGenLevel world, BlockPos center, int radius, RandomSource random) { + return null; + } + + @Override + protected void placeFloor( + WorldGenLevel world, + ChunkGenerator generator, + EndCaveBiome biome, + Set floorPositions, + RandomSource random, + BlockState surfaceBlock + ) { + float density = biome.getFloorDensity() * 0.2F; + floorPositions.forEach((pos) -> { + if (!surfaceBlock.is(Blocks.END_STONE)) { + BlocksHelper.setWithoutUpdate(world, pos, surfaceBlock); + } + if (density > 0 && random.nextFloat() <= density) { + Holder> feature = biome.getFloorFeature(random); + if (feature != null && feature.isBound()) { + feature.value().place(world, generator, random, pos.above()); + } + } + }); + } + + @Override + protected void placeCeil( + WorldGenLevel world, + ChunkGenerator generator, + EndCaveBiome biome, + Set ceilPositions, + RandomSource random + ) { + float density = biome.getCeilDensity() * 0.2F; + ceilPositions.forEach((pos) -> { + BlockState ceilBlock = biome.getCeil(pos); + if (ceilBlock != null) { + BlocksHelper.setWithoutUpdate(world, pos, ceilBlock); + } + if (density > 0 && random.nextFloat() <= density) { + Holder> feature = biome.getCeilFeature(random); + if (feature != null && feature.isBound()) { + feature.value().place(world, generator, random, pos.below()); + } + } + }); + } + + protected boolean hasCaves(WorldGenLevel world, BlockPos pos) { + return hasCavesInBiome(world, pos.offset(-8, 0, -8)) && hasCavesInBiome( + world, + pos.offset(8, 0, -8) + ) && hasCavesInBiome( + world, + pos.offset( + -8, + 0, + 8 + ) + ) && hasCavesInBiome( + world, + pos.offset(8, 0, 8) + ); + } + + protected boolean hasCavesInBiome(WorldGenLevel world, BlockPos pos) { + Holder biome = world.getBiome(pos); + BCLBiome bclBiome = BiomeAPI.getBiome(biome); + if (bclBiome instanceof EndBiome endBiome) + return endBiome.hasCaves(); + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/trees/DragonTreeFeature.java b/src/main/java/org/betterx/betterend/world/features/trees/DragonTreeFeature.java new file mode 100644 index 00000000..9718655b --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/trees/DragonTreeFeature.java @@ -0,0 +1,261 @@ +package org.betterx.betterend.world.features.trees; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.PosInfo; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.*; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.function.Function; + +public class DragonTreeFeature extends DefaultFeature { + private static final Function REPLACE; + private static final Function IGNORE; + private static final Function POST; + private static final List BRANCH; + private static final List SIDE1; + private static final List SIDE2; + private static final List ROOT; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(BlockTags.NYLIUM)) return false; + + float size = MHelper.randRange(10, 25, random); + List spline = SplineHelper.makeSpline(0, 0, 0, 0, size, 0, 6); + SplineHelper.offsetParts(spline, random, 1F, 0, 1F); + + if (!SplineHelper.canGenerate(spline, pos, world, REPLACE)) { + return false; + } + BlocksHelper.setWithoutUpdate(world, pos, AIR); + + Vector3f last = SplineHelper.getPos(spline, 3.5F); + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + float radius = size * MHelper.randRange(0.5F, 0.7F, random); + makeCap(world, pos.offset(last.x(), last.y(), last.z()), radius, random, noise); + + last = spline.get(0); + makeRoots(world, pos.offset(last.x(), last.y(), last.z()), radius, random); + + radius = MHelper.randRange(1.2F, 2.3F, random); + SDF function = SplineHelper.buildSDF(spline, radius, 1.2F, (bpos) -> { + return EndBlocks.DRAGON_TREE.getBark().defaultBlockState(); + }); + + function.setReplaceFunction(REPLACE); + function.addPostProcess(POST); + function.fillRecursiveIgnore(world, pos, IGNORE); + + return true; + } + + private void makeCap(WorldGenLevel world, BlockPos pos, float radius, RandomSource random, OpenSimplexNoise noise) { + int count = (int) radius; + int offset = (int) (BRANCH.get(BRANCH.size() - 1).y() * radius); + for (int i = 0; i < count; i++) { + float angle = (float) i / (float) count * MHelper.PI2; + float scale = radius * MHelper.randRange(0.85F, 1.15F, random); + + List branch = SplineHelper.copySpline(BRANCH); + SplineHelper.rotateSpline(branch, angle); + SplineHelper.scale(branch, scale); + SplineHelper.fillSpline(branch, world, EndBlocks.DRAGON_TREE.getBark().defaultBlockState(), pos, REPLACE); + + branch = SplineHelper.copySpline(SIDE1); + SplineHelper.rotateSpline(branch, angle); + SplineHelper.scale(branch, scale); + SplineHelper.fillSpline(branch, world, EndBlocks.DRAGON_TREE.getBark().defaultBlockState(), pos, REPLACE); + + branch = SplineHelper.copySpline(SIDE2); + SplineHelper.rotateSpline(branch, angle); + SplineHelper.scale(branch, scale); + SplineHelper.fillSpline(branch, world, EndBlocks.DRAGON_TREE.getBark().defaultBlockState(), pos, REPLACE); + } + leavesBall(world, pos.above(offset), radius * 1.15F + 2, random, noise); + } + + private void makeRoots(WorldGenLevel world, BlockPos pos, float radius, RandomSource random) { + int count = (int) (radius * 1.5F); + for (int i = 0; i < count; i++) { + float angle = (float) i / (float) count * MHelper.PI2; + float scale = radius * MHelper.randRange(0.85F, 1.15F, random); + + List branch = SplineHelper.copySpline(ROOT); + SplineHelper.rotateSpline(branch, angle); + SplineHelper.scale(branch, scale); + Vector3f last = branch.get(branch.size() - 1); + if (world.getBlockState(pos.offset(last.x(), last.y(), last.z())).is(CommonBlockTags.GEN_END_STONES)) { + SplineHelper.fillSpline( + branch, + world, + EndBlocks.DRAGON_TREE.getBark().defaultBlockState(), + pos, + REPLACE + ); + } + } + } + + private void leavesBall( + WorldGenLevel world, + BlockPos pos, + float radius, + RandomSource random, + OpenSimplexNoise noise + ) { + SDF sphere = new SDFSphere().setRadius(radius) + .setBlock(EndBlocks.DRAGON_TREE_LEAVES.defaultBlockState() + .setValue(LeavesBlock.DISTANCE, 6)); + SDF sub = new SDFScale().setScale(5).setSource(sphere); + sub = new SDFTranslate().setTranslate(0, -radius * 5, 0).setSource(sub); + sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sub); + sphere = new SDFScale3D().setScale(1, 0.5F, 1).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> { + return (float) noise.eval(vec.x() * 0.2, vec.y() * 0.2, vec.z() * 0.2) * 1.5F; + }).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> { + return random.nextFloat() * 3F - 1.5F; + }).setSource(sphere); + MutableBlockPos mut = new MutableBlockPos(); + sphere.addPostProcess((info) -> { + if (random.nextInt(5) == 0) { + for (Direction dir : Direction.values()) { + BlockState state = info.getState(dir, 2); + if (state.isAir()) { + return info.getState(); + } + } + info.setState(EndBlocks.DRAGON_TREE.getBark().defaultBlockState()); + for (int x = -6; x < 7; x++) { + int ax = Math.abs(x); + mut.setX(x + info.getPos().getX()); + for (int z = -6; z < 7; z++) { + int az = Math.abs(z); + mut.setZ(z + info.getPos().getZ()); + for (int y = -6; y < 7; y++) { + int ay = Math.abs(y); + int d = ax + ay + az; + if (d < 7) { + mut.setY(y + info.getPos().getY()); + BlockState state = info.getState(mut); + if (state.getBlock() instanceof LeavesBlock) { + int distance = state.getValue(LeavesBlock.DISTANCE); + if (d < distance) { + info.setState(mut, state.setValue(LeavesBlock.DISTANCE, d)); + } + } + } + } + } + } + } + return info.getState(); + }); + sphere.fillRecursiveIgnore(world, pos, IGNORE); + + if (radius > 5) { + int count = (int) (radius * 2.5F); + for (int i = 0; i < count; i++) { + BlockPos p = pos.offset( + random.nextGaussian() * 1, + random.nextGaussian() * 1, + random.nextGaussian() * 1 + ); + boolean place = true; + for (Direction d : Direction.values()) { + BlockState state = world.getBlockState(p.relative(d)); + if (!EndBlocks.DRAGON_TREE.isTreeLog(state) && !state.is(EndBlocks.DRAGON_TREE_LEAVES)) { + place = false; + break; + } + } + if (place) { + BlocksHelper.setWithoutUpdate(world, p, EndBlocks.DRAGON_TREE.getBark()); + } + } + } + + BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.DRAGON_TREE.getBark()); + } + + static { + REPLACE = (state) -> { + /*if (state.is(CommonBlockTags.END_STONES)) { + return true; + }*/ + if (state.getBlock() == EndBlocks.DRAGON_TREE_LEAVES) { + return true; + } + if (state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + + IGNORE = (state) -> { + return EndBlocks.DRAGON_TREE.isTreeLog(state); + }; + + POST = (info) -> { + if (EndBlocks.DRAGON_TREE.isTreeLog(info.getStateUp()) && EndBlocks.DRAGON_TREE.isTreeLog(info.getStateDown())) { + return EndBlocks.DRAGON_TREE.getLog().defaultBlockState(); + } + return info.getState(); + }; + + BRANCH = Lists.newArrayList( + new Vector3f(0, 0, 0), + new Vector3f(0.1F, 0.3F, 0), + new Vector3f(0.4F, 0.6F, 0), + new Vector3f(0.8F, 0.8F, 0), + new Vector3f(1, 1, 0) + ); + SIDE1 = Lists.newArrayList(new Vector3f(0.4F, 0.6F, 0), new Vector3f(0.8F, 0.8F, 0), new Vector3f(1, 1, 0)); + SIDE2 = SplineHelper.copySpline(SIDE1); + + Vector3f offset1 = new Vector3f(-0.4F, -0.6F, 0); + Vector3f offset2 = new Vector3f(0.4F, 0.6F, 0); + + SplineHelper.offset(SIDE1, offset1); + SplineHelper.offset(SIDE2, offset1); + SplineHelper.rotateSpline(SIDE1, 0.5F); + SplineHelper.rotateSpline(SIDE2, -0.5F); + SplineHelper.offset(SIDE1, offset2); + SplineHelper.offset(SIDE2, offset2); + + ROOT = Lists.newArrayList( + new Vector3f(0F, 1F, 0), + new Vector3f(0.1F, 0.7F, 0), + new Vector3f(0.3F, 0.3F, 0), + new Vector3f(0.7F, 0.05F, 0), + new Vector3f(0.8F, -0.2F, 0) + ); + SplineHelper.offset(ROOT, new Vector3f(0, -0.45F, 0)); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/trees/GiganticAmaranitaFeature.java b/src/main/java/org/betterx/betterend/world/features/trees/GiganticAmaranitaFeature.java new file mode 100644 index 00000000..ed0831de --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/trees/GiganticAmaranitaFeature.java @@ -0,0 +1,379 @@ +package org.betterx.betterend.world.features.trees; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.blocks.BaseAttachedBlock; +import org.betterx.bclib.sdf.PosInfo; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.registry.EndBlocks; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.core.Direction.AxisDirection; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import java.util.List; +import java.util.function.Function; + +public class GiganticAmaranitaFeature extends DefaultFeature { + private static final Function REPLACE; + private static final Function IGNORE; + private static final Function POST; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(BlockTags.NYLIUM)) return false; + + float size = MHelper.randRange(5, 10, random); + List spline = SplineHelper.makeSpline(0, 0, 0, 0, size, 0, 5); + SplineHelper.offsetParts(spline, random, 0.7F, 0, 0.7F); + + if (!SplineHelper.canGenerate(spline, pos, world, REPLACE)) { + return false; + } + BlocksHelper.setWithoutUpdate(world, pos, AIR); + + float radius = size * 0.17F;// MHelper.randRange(0.8F, 1.2F, random); + SDF function = SplineHelper.buildSDF( + spline, + radius, + 0.2F, + (bpos) -> EndBlocks.AMARANITA_STEM.defaultBlockState() + ); + + Vector3f capPos = spline.get(spline.size() - 1); + makeHead(world, pos.offset(capPos.x() + 0.5F, capPos.y() + 1.5F, capPos.z() + 0.5F), Mth.floor(size / 1.6F)); + + function.setReplaceFunction(REPLACE); + function.addPostProcess(POST); + function.fillRecursiveIgnore(world, pos, IGNORE); + + for (int i = 0; i < 3; i++) { + List copy = SplineHelper.copySpline(spline); + SplineHelper.offsetParts(copy, random, 0.2F, 0, 0.2F); + SplineHelper.fillSplineForce(copy, world, EndBlocks.AMARANITA_HYPHAE.defaultBlockState(), pos, REPLACE); + } + + return true; + } + + private void makeHead(WorldGenLevel world, BlockPos pos, int radius) { + MutableBlockPos mut = new MutableBlockPos(); + if (radius < 2) { + for (int i = -1; i < 2; i++) { + mut.set(pos).move(Direction.NORTH, 2).move(Direction.EAST, i); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.set(pos).move(Direction.SOUTH, 2).move(Direction.EAST, i); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.set(pos).move(Direction.EAST, 2).move(Direction.NORTH, i); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.set(pos).move(Direction.WEST, 2).move(Direction.NORTH, i); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + } + for (int x = -1; x < 2; x++) { + for (int z = -1; z < 2; z++) { + mut.set(pos).move(x, 0, z); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN); + mut.move(Direction.DOWN); + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN); + mut.move(Direction.DOWN); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate( + world, + mut, + EndBlocks.AMARANITA_FUR.defaultBlockState() + .setValue(BaseAttachedBlock.FACING, Direction.DOWN) + ); + } + } + } + } + + int h = radius + 1; + for (int y = 0; y < h; y++) { + mut.setY(pos.getY() + y + 1); + for (int x = -1; x < 2; x++) { + mut.setX(pos.getX() + x); + for (int z = -1; z < 2; z++) { + mut.setZ(pos.getZ() + z); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); + } + } + } + } + + mut.setY(pos.getY() + h + 1); + for (int x = -1; x < 2; x++) { + mut.setX(pos.getX() + x); + for (int z = -1; z < 2; z++) { + mut.setZ(pos.getZ() + z); + if ((x == 0 || z == 0) && world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); + } + } + } + } else if (radius < 4) { + pos = pos.offset(-1, 0, -1); + for (int i = -2; i < 2; i++) { + mut.set(pos).move(Direction.NORTH, 2).move(Direction.WEST, i); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.set(pos).move(Direction.SOUTH, 3).move(Direction.WEST, i); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.set(pos).move(Direction.EAST, 3).move(Direction.NORTH, i); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.set(pos).move(Direction.WEST, 2).move(Direction.NORTH, i); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + } + for (int x = -1; x < 3; x++) { + for (int z = -1; z < 3; z++) { + mut.set(pos).move(x, 0, z); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN); + mut.move(Direction.DOWN); + if ((x >> 1) == 0 || (z >> 1) == 0) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN); + Axis axis = x < 0 || x > 1 ? Axis.X : Axis.Z; + int distance = axis == Axis.X ? x < 0 ? -1 : 1 : z < 0 ? -1 : 1; + BlockPos offseted = mut.relative(axis, distance); + if (world.getBlockState(offseted).getMaterial().isReplaceable()) { + Direction dir = Direction.fromAxisAndDirection( + axis, + distance < 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE + ); + BlocksHelper.setWithoutUpdate( + world, + offseted, + EndBlocks.AMARANITA_FUR.defaultBlockState() + .setValue(BaseAttachedBlock.FACING, dir) + ); + } + mut.move(Direction.DOWN); + } + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate( + world, + mut, + EndBlocks.AMARANITA_FUR.defaultBlockState() + .setValue(BaseAttachedBlock.FACING, Direction.DOWN) + ); + } + } + } + } + + int h = radius - 1; + for (int y = 0; y < h; y++) { + mut.setY(pos.getY() + y + 1); + for (int x = -1; x < 3; x++) { + mut.setX(pos.getX() + x); + for (int z = -1; z < 3; z++) { + mut.setZ(pos.getZ() + z); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); + } + } + } + } + + mut.setY(pos.getY() + h + 1); + for (int x = -1; x < 3; x++) { + mut.setX(pos.getX() + x); + for (int z = -1; z < 3; z++) { + mut.setZ(pos.getZ() + z); + if (((x >> 1) == 0 || (z >> 1) == 0) && world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); + } + } + } + } else { + for (int i = -2; i < 3; i++) { + mut.set(pos).move(Direction.NORTH, 3).move(Direction.EAST, i); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.move(Direction.UP); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.move(Direction.NORTH); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + + mut.set(pos).move(Direction.SOUTH, 3).move(Direction.EAST, i); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.move(Direction.UP); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.move(Direction.SOUTH); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + + mut.set(pos).move(Direction.EAST, 3).move(Direction.NORTH, i); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.move(Direction.UP); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.move(Direction.EAST); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + + mut.set(pos).move(Direction.WEST, 3).move(Direction.NORTH, i); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.move(Direction.UP); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + mut.move(Direction.WEST); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + } + + for (int i = 0; i < 4; i++) { + mut.set(pos) + .move(Direction.UP) + .move(BlocksHelper.HORIZONTAL[i], 3) + .move(BlocksHelper.HORIZONTAL[(i + 1) & 3], 3); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); + } + } + + for (int x = -2; x < 3; x++) { + for (int z = -2; z < 3; z++) { + mut.set(pos).move(x, 0, z); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN); + mut.move(Direction.DOWN); + if ((x / 2) == 0 || (z / 2) == 0) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN); + Axis axis = x < 0 || x > 1 ? Axis.X : Axis.Z; + int distance = axis == Axis.X ? x < 0 ? -1 : 1 : z < 0 ? -1 : 1; + BlockPos offseted = mut.relative(axis, distance); + if (world.getBlockState(offseted).getMaterial().isReplaceable()) { + Direction dir = Direction.fromAxisAndDirection( + axis, + distance < 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE + ); + BlocksHelper.setWithoutUpdate( + world, + offseted, + EndBlocks.AMARANITA_FUR.defaultBlockState() + .setValue(BaseAttachedBlock.FACING, dir) + ); + } + mut.move(Direction.DOWN); + } + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate( + world, + mut, + EndBlocks.AMARANITA_FUR.defaultBlockState() + .setValue(BaseAttachedBlock.FACING, Direction.DOWN) + ); + } + } + } + } + + for (int y = 0; y < 3; y++) { + mut.setY(pos.getY() + y + 1); + for (int x = -2; x < 3; x++) { + mut.setX(pos.getX() + x); + for (int z = -2; z < 3; z++) { + mut.setZ(pos.getZ() + z); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); + } + } + } + } + + int h = radius + 1; + for (int y = 4; y < h; y++) { + mut.setY(pos.getY() + y); + for (int x = -2; x < 3; x++) { + mut.setX(pos.getX() + x); + for (int z = -2; z < 3; z++) { + mut.setZ(pos.getZ() + z); + if (y < 6) { + if (((x / 2) == 0 || (z / 2) == 0) && world.getBlockState(mut) + .getMaterial() + .isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); + } + } else { + if ((x == 0 || z == 0) && (Math.abs(x) < 2 && Math.abs(z) < 2) && world.getBlockState(mut) + .getMaterial() + .isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); + } + } + } + } + } + } + } + + static { + REPLACE = (state) -> { + if (/*state.is(CommonBlockTags.END_STONES) || */state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + + IGNORE = EndBlocks.DRAGON_TREE::isTreeLog; + + POST = (info) -> { + if (!info.getStateUp().is(EndBlocks.AMARANITA_STEM) || !info.getStateDown().is(EndBlocks.AMARANITA_STEM)) { + return EndBlocks.AMARANITA_HYPHAE.defaultBlockState(); + } + return info.getState(); + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/trees/HelixTreeFeature.java b/src/main/java/org/betterx/betterend/world/features/trees/HelixTreeFeature.java new file mode 100644 index 00000000..1503ad0f --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/trees/HelixTreeFeature.java @@ -0,0 +1,212 @@ +package org.betterx.betterend.world.features.trees; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.PosInfo; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.*; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.blocks.HelixTreeLeavesBlock; +import org.betterx.betterend.registry.EndBlocks; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.phys.AABB; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +public class HelixTreeFeature extends DefaultFeature { + private static final Function POST; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(BlockTags.NYLIUM)) return false; + BlocksHelper.setWithoutUpdate(world, pos, AIR); + + float angle = random.nextFloat() * MHelper.PI2; + float radiusRange = MHelper.randRange(4.5F, 6F, random); + float scale = MHelper.randRange(0.5F, 1F, random); + + float dx; + float dz; + List spline = new ArrayList(10); + for (int i = 0; i < 10; i++) { + float radius = (0.9F - i * 0.1F) * radiusRange; + dx = (float) Math.sin(i + angle) * radius; + dz = (float) Math.cos(i + angle) * radius; + spline.add(new Vector3f(dx, i * 2, dz)); + } + SDF sdf = SplineHelper.buildSDF(spline, 1.7F, 0.5F, (p) -> { + return EndBlocks.HELIX_TREE.getBark().defaultBlockState(); + }); + SDF rotated = new SDFRotation().setRotation(Vector3f.YP, (float) Math.PI).setSource(sdf); + sdf = new SDFUnion().setSourceA(rotated).setSourceB(sdf); + + Vector3f lastPoint = spline.get(spline.size() - 1); + List spline2 = SplineHelper.makeSpline(0, 0, 0, 0, 20, 0, 5); + SDF stem = SplineHelper.buildSDF(spline2, 1.0F, 0.5F, (p) -> { + return EndBlocks.HELIX_TREE.getBark().defaultBlockState(); + }); + stem = new SDFTranslate().setTranslate(lastPoint.x(), lastPoint.y(), lastPoint.z()).setSource(stem); + sdf = new SDFSmoothUnion().setRadius(3).setSourceA(sdf).setSourceB(stem); + + sdf = new SDFScale().setScale(scale).setSource(sdf); + dx = 30 * scale; + float dy1 = -20 * scale; + float dy2 = 100 * scale; + sdf.addPostProcess(POST).fillArea(world, pos, new AABB(pos.offset(-dx, dy1, -dx), pos.offset(dx, dy2, dx))); + SplineHelper.scale(spline, scale); + SplineHelper.fillSplineForce( + spline, + world, + EndBlocks.HELIX_TREE.getBark().defaultBlockState(), + pos, + (state) -> { + return state.getMaterial().isReplaceable(); + } + ); + SplineHelper.rotateSpline(spline, (float) Math.PI); + SplineHelper.fillSplineForce( + spline, + world, + EndBlocks.HELIX_TREE.getBark().defaultBlockState(), + pos, + (state) -> { + return state.getMaterial().isReplaceable(); + } + ); + SplineHelper.scale(spline2, scale); + BlockPos leafStart = pos.offset(lastPoint.x() + 0.5, lastPoint.y() + 0.5, lastPoint.z() + 0.5); + SplineHelper.fillSplineForce( + spline2, + world, + EndBlocks.HELIX_TREE.getLog().defaultBlockState(), + leafStart, + (state) -> { + return state.getMaterial().isReplaceable(); + } + ); + + spline.clear(); + float rad = MHelper.randRange(8F, 11F, random); + int count = MHelper.randRange(20, 30, random); + float scaleM = 20F / (float) count * scale * 1.75F; + float hscale = 20F / (float) count * 0.05F; + for (int i = 0; i <= count; i++) { + float radius = 1 - i * hscale; + radius = radius * radius * 2 - 1; + radius *= radius; + radius = (1 - radius) * rad * scale; + dx = (float) Math.sin(i * 0.45F + angle) * radius; + dz = (float) Math.cos(i * 0.45F + angle) * radius; + spline.add(new Vector3f(dx, i * scaleM, dz)); + } + + Vector3f start = new Vector3f(); + Vector3f end = new Vector3f(); + lastPoint = spline.get(0); + BlockState leaf = EndBlocks.HELIX_TREE_LEAVES.defaultBlockState(); + for (int i = 1; i < spline.size(); i++) { + Vector3f point = spline.get(i); + int minY = MHelper.floor(lastPoint.y()); + int maxY = MHelper.floor(point.y()); + float div = point.y() - lastPoint.y(); + for (float py = minY; py <= maxY; py += 0.2F) { + start.set(0, py, 0); + float delta = (py - minY) / div; + float px = Mth.lerp(delta, lastPoint.x(), point.x()); + float pz = Mth.lerp(delta, lastPoint.z(), point.z()); + end.set(px, py, pz); + fillLine(start, end, world, leaf, leafStart, i / 2 - 1); + float ax = Math.abs(px); + float az = Math.abs(pz); + if (ax > az) { + start.set(start.x(), start.y(), start.z() + az > 0 ? 1 : -1); + end.set(end.x(), end.y(), end.z() + az > 0 ? 1 : -1); + } else { + start.set(start.x() + ax > 0 ? 1 : -1, start.y(), start.z()); + end.set(end.x() + ax > 0 ? 1 : -1, end.y(), end.z()); + } + fillLine(start, end, world, leaf, leafStart, i / 2 - 1); + } + lastPoint = point; + } + + leaf = leaf.setValue(HelixTreeLeavesBlock.COLOR, 7); + leafStart = leafStart.offset(0, lastPoint.y(), 0); + if (world.getBlockState(leafStart).isAir()) { + BlocksHelper.setWithoutUpdate(world, leafStart, leaf); + leafStart = leafStart.above(); + if (world.getBlockState(leafStart).isAir()) { + BlocksHelper.setWithoutUpdate(world, leafStart, leaf); + leafStart = leafStart.above(); + if (world.getBlockState(leafStart).isAir()) { + BlocksHelper.setWithoutUpdate(world, leafStart, leaf); + } + } + } + + return true; + } + + private void fillLine( + Vector3f start, + Vector3f end, + WorldGenLevel world, + BlockState state, + BlockPos pos, + int offset + ) { + float dx = end.x() - start.x(); + float dy = end.y() - start.y(); + float dz = end.z() - start.z(); + float max = MHelper.max(Math.abs(dx), Math.abs(dy), Math.abs(dz)); + int count = MHelper.floor(max + 1); + dx /= max; + dy /= max; + dz /= max; + float x = start.x(); + float y = start.y(); + float z = start.z(); + + MutableBlockPos bPos = new MutableBlockPos(); + for (int i = 0; i < count; i++) { + bPos.set(x + pos.getX(), y + pos.getY(), z + pos.getZ()); + int color = MHelper.floor((float) i / (float) count * 7F + 0.5F) + offset; + color = Mth.clamp(color, 0, 7); + if (world.getBlockState(bPos).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, bPos, state.setValue(HelixTreeLeavesBlock.COLOR, color)); + } + x += dx; + y += dy; + z += dz; + } + bPos.set(end.x() + pos.getX(), end.y() + pos.getY(), end.z() + pos.getZ()); + if (world.getBlockState(bPos).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, bPos, state.setValue(HelixTreeLeavesBlock.COLOR, 7)); + } + } + + static { + POST = (info) -> { + if (EndBlocks.HELIX_TREE.isTreeLog(info.getStateUp()) && EndBlocks.HELIX_TREE.isTreeLog(info.getStateDown())) { + return EndBlocks.HELIX_TREE.getLog().defaultBlockState(); + } + return info.getState(); + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/trees/JellyshroomFeature.java b/src/main/java/org/betterx/betterend/world/features/trees/JellyshroomFeature.java new file mode 100644 index 00000000..99682a14 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/trees/JellyshroomFeature.java @@ -0,0 +1,129 @@ +package org.betterx.betterend.world.features.trees; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.*; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.blocks.JellyshroomCapBlock; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.function.Function; + +public class JellyshroomFeature extends DefaultFeature { + private static final Function REPLACE; + private static final List ROOT; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(BlockTags.NYLIUM)) return false; + + BlockState bark = EndBlocks.JELLYSHROOM.getBark().defaultBlockState(); + BlockState membrane = EndBlocks.JELLYSHROOM_CAP_PURPLE.defaultBlockState(); + + int height = MHelper.randRange(5, 8, random); + float radius = height * MHelper.randRange(0.15F, 0.25F, random); + List spline = SplineHelper.makeSpline(0, -1, 0, 0, height, 0, 3); + SplineHelper.offsetParts(spline, random, 0.5F, 0, 0.5F); + SDF sdf = SplineHelper.buildSDF(spline, radius, 0.8F, (bpos) -> { + return bark; + }); + + radius = height * MHelper.randRange(0.7F, 0.9F, random); + if (radius < 1.5F) { + radius = 1.5F; + } + final float membraneRadius = radius; + SDF cap = makeCap(membraneRadius, random, membrane); + final Vector3f last = spline.get(spline.size() - 1); + cap = new SDFTranslate().setTranslate(last.x(), last.y(), last.z()).setSource(cap); + sdf = new SDFSmoothUnion().setRadius(3F).setSourceA(sdf).setSourceB(cap); + sdf.setReplaceFunction(REPLACE).addPostProcess((info) -> { + if (EndBlocks.JELLYSHROOM.isTreeLog(info.getState())) { + if (EndBlocks.JELLYSHROOM.isTreeLog(info.getStateUp()) && EndBlocks.JELLYSHROOM.isTreeLog(info.getStateDown())) { + return EndBlocks.JELLYSHROOM.getLog().defaultBlockState(); + } + } else if (info.getState().is(EndBlocks.JELLYSHROOM_CAP_PURPLE)) { + float dx = info.getPos().getX() - pos.getX() - last.x(); + float dz = info.getPos().getZ() - pos.getZ() - last.z(); + float distance = MHelper.length(dx, dz) / membraneRadius * 7F; + int color = Mth.clamp(MHelper.floor(distance), 0, 7); + return info.getState().setValue(JellyshroomCapBlock.COLOR, color); + } + return info.getState(); + }).fillRecursive(world, pos); + radius = height * 0.5F; + makeRoots(world, pos.offset(0, 2, 0), radius, random, bark); + + return true; + } + + private void makeRoots(WorldGenLevel world, BlockPos pos, float radius, RandomSource random, BlockState wood) { + int count = (int) (radius * 3.5F); + for (int i = 0; i < count; i++) { + float angle = (float) i / (float) count * MHelper.PI2; + float scale = radius * MHelper.randRange(0.85F, 1.15F, random); + + List branch = SplineHelper.copySpline(ROOT); + SplineHelper.rotateSpline(branch, angle); + SplineHelper.scale(branch, scale); + Vector3f last = branch.get(branch.size() - 1); + if (world.getBlockState(pos.offset(last.x(), last.y(), last.z())).is(CommonBlockTags.GEN_END_STONES)) { + SplineHelper.fillSpline(branch, world, wood, pos, REPLACE); + } + } + } + + private SDF makeCap(float radius, RandomSource random, BlockState cap) { + SDF sphere = new SDFSphere().setRadius(radius).setBlock(cap); + SDF sub = new SDFTranslate().setTranslate(0, -4, 0).setSource(sphere); + sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sub); + sphere = new SDFScale3D().setScale(1, 0.5F, 1).setSource(sphere); + sphere = new SDFTranslate().setTranslate(0, 1 - radius * 0.5F, 0).setSource(sphere); + + float angle = random.nextFloat() * MHelper.PI2; + int count = (int) MHelper.randRange(radius * 0.5F, radius, random); + if (count < 3) { + count = 3; + } + sphere = new SDFFlatWave().setAngle(angle).setRaysCount(count).setIntensity(0.2F).setSource(sphere); + + return sphere; + } + + static { + ROOT = Lists.newArrayList( + new Vector3f(0.1F, 0.70F, 0), + new Vector3f(0.3F, 0.30F, 0), + new Vector3f(0.7F, 0.05F, 0), + new Vector3f(0.8F, -0.20F, 0) + ); + SplineHelper.offset(ROOT, new Vector3f(0, -0.45F, 0)); + + REPLACE = (state) -> { + if (/*state.is(CommonBlockTags.END_STONES) || */state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/trees/LacugroveFeature.java b/src/main/java/org/betterx/betterend/world/features/trees/LacugroveFeature.java new file mode 100644 index 00000000..f4b43cd7 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/trees/LacugroveFeature.java @@ -0,0 +1,225 @@ +package org.betterx.betterend.world.features.trees; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.PosInfo; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFSubtraction; +import org.betterx.bclib.sdf.operator.SDFTranslate; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import java.util.List; +import java.util.function.Function; + +public class LacugroveFeature extends DefaultFeature { + private static final Function REPLACE; + private static final Function IGNORE; + private static final Function POST; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(BlockTags.NYLIUM)) return false; + + float size = MHelper.randRange(15, 25, random); + List spline = SplineHelper.makeSpline(0, 0, 0, 0, size, 0, 6); + SplineHelper.offsetParts(spline, random, 1F, 0, 1F); + + if (!SplineHelper.canGenerate(spline, pos, world, REPLACE)) { + return false; + } + + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + + float radius = MHelper.randRange(6F, 8F, random); + radius *= (size - 15F) / 20F + 1F; + Vector3f center = spline.get(4); + leavesBall(world, pos.offset(center.x(), center.y(), center.z()), radius, random, noise); + + radius = MHelper.randRange(1.2F, 1.8F, random); + SDF function = SplineHelper.buildSDF(spline, radius, 0.7F, (bpos) -> { + return EndBlocks.LACUGROVE.getBark().defaultBlockState(); + }); + + function.setReplaceFunction(REPLACE); + function.addPostProcess(POST); + function.fillRecursive(world, pos); + + spline = spline.subList(4, 6); + SplineHelper.fillSpline(spline, world, EndBlocks.LACUGROVE.getBark().defaultBlockState(), pos, REPLACE); + + MutableBlockPos mut = new MutableBlockPos(); + int offset = random.nextInt(2); + for (int i = 0; i < 100; i++) { + double px = pos.getX() + MHelper.randRange(-5, 5, random); + double pz = pos.getZ() + MHelper.randRange(-5, 5, random); + mut.setX(MHelper.floor(px + 0.5)); + mut.setZ(MHelper.floor(pz + 0.5)); + if (((mut.getX() + mut.getZ() + offset) & 1) == 0) { + double distance = 3.5 - MHelper.length(px - pos.getX(), pz - pos.getZ()) * 0.5; + if (distance > 0) { + int minY = MHelper.floor(pos.getY() - distance * 0.5); + int maxY = MHelper.floor(pos.getY() + distance + random.nextDouble()); + boolean generate = false; + for (int y = minY; y < maxY; y++) { + mut.setY(y); + if (world.getBlockState(mut).is(CommonBlockTags.END_STONES)) { + generate = true; + break; + } + } + if (generate) { + int top = maxY - 1; + for (int y = top; y >= minY; y--) { + mut.setY(y); + BlockState state = world.getBlockState(mut); + if (state.getMaterial().isReplaceable() || state.getMaterial() + .equals(Material.PLANT) || state.is( + CommonBlockTags.END_STONES)) { + BlocksHelper.setWithoutUpdate( + world, + mut, + y == top ? EndBlocks.LACUGROVE.getBark() : EndBlocks.LACUGROVE.getLog() + ); + } else { + break; + } + } + } + } + } + } + + return true; + } + + private void leavesBall( + WorldGenLevel world, + BlockPos pos, + float radius, + RandomSource random, + OpenSimplexNoise noise + ) { + SDF sphere = new SDFSphere().setRadius(radius) + .setBlock(EndBlocks.LACUGROVE_LEAVES.defaultBlockState() + .setValue(LeavesBlock.DISTANCE, 6)); + sphere = new SDFDisplacement().setFunction((vec) -> { + return (float) noise.eval(vec.x() * 0.2, vec.y() * 0.2, vec.z() * 0.2) * 3; + }).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> { + return random.nextFloat() * 3F - 1.5F; + }).setSource(sphere); + sphere = new SDFSubtraction().setSourceA(sphere) + .setSourceB(new SDFTranslate().setTranslate(0, -radius - 2, 0).setSource(sphere)); + MutableBlockPos mut = new MutableBlockPos(); + sphere.addPostProcess((info) -> { + if (random.nextInt(5) == 0) { + for (Direction dir : Direction.values()) { + BlockState state = info.getState(dir, 2); + if (state.isAir()) { + return info.getState(); + } + } + info.setState(EndBlocks.LACUGROVE.getBark().defaultBlockState()); + for (int x = -6; x < 7; x++) { + int ax = Math.abs(x); + mut.setX(x + info.getPos().getX()); + for (int z = -6; z < 7; z++) { + int az = Math.abs(z); + mut.setZ(z + info.getPos().getZ()); + for (int y = -6; y < 7; y++) { + int ay = Math.abs(y); + int d = ax + ay + az; + if (d < 7) { + mut.setY(y + info.getPos().getY()); + BlockState state = info.getState(mut); + if (state.getBlock() instanceof LeavesBlock) { + int distance = state.getValue(LeavesBlock.DISTANCE); + if (d < distance) { + info.setState(mut, state.setValue(LeavesBlock.DISTANCE, d)); + } + } + } + } + } + } + } + return info.getState(); + }); + sphere.fillRecursiveIgnore(world, pos, IGNORE); + + if (radius > 5) { + int count = (int) (radius * 2.5F); + for (int i = 0; i < count; i++) { + BlockPos p = pos.offset( + random.nextGaussian() * 1, + random.nextGaussian() * 1, + random.nextGaussian() * 1 + ); + boolean place = true; + for (Direction d : Direction.values()) { + BlockState state = world.getBlockState(p.relative(d)); + if (!EndBlocks.LACUGROVE.isTreeLog(state) && !state.is(EndBlocks.LACUGROVE_LEAVES)) { + place = false; + break; + } + } + if (place) { + BlocksHelper.setWithoutUpdate(world, p, EndBlocks.LACUGROVE.getBark()); + } + } + } + + BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.LACUGROVE.getBark()); + } + + static { + REPLACE = (state) -> { + /*if (state.is(CommonBlockTags.END_STONES)) { + return true; + }*/ + if (EndBlocks.LACUGROVE.isTreeLog(state)) { + return true; + } + if (state.getBlock() == EndBlocks.LACUGROVE_LEAVES) { + return true; + } + if (state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + + IGNORE = (state) -> { + return EndBlocks.LACUGROVE.isTreeLog(state); + }; + + POST = (info) -> { + if (EndBlocks.LACUGROVE.isTreeLog(info.getStateUp()) && EndBlocks.LACUGROVE.isTreeLog(info.getStateDown())) { + return EndBlocks.LACUGROVE.getLog().defaultBlockState(); + } + return info.getState(); + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/trees/LucerniaFeature.java b/src/main/java/org/betterx/betterend/world/features/trees/LucerniaFeature.java new file mode 100644 index 00000000..a495278c --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/trees/LucerniaFeature.java @@ -0,0 +1,239 @@ +package org.betterx.betterend.world.features.trees; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.*; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.blocks.basis.FurBlock; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.function.Function; + +public class LucerniaFeature extends DefaultFeature { + private static final Direction[] DIRECTIONS = Direction.values(); + private static final Function REPLACE; + private static final Function IGNORE; + private static final List SPLINE; + private static final List ROOT; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + final NoneFeatureConfiguration config = featureConfig.config(); + if (!world.getBlockState(pos.below()).is(BlockTags.NYLIUM)) return false; + + float size = MHelper.randRange(12, 20, random); + int count = (int) (size * 0.3F); + float var = MHelper.PI2 / (float) (count * 3); + float start = MHelper.randRange(0, MHelper.PI2, random); + for (int i = 0; i < count; i++) { + float angle = (float) i / (float) count * MHelper.PI2 + MHelper.randRange(0, var, random) + start; + List spline = SplineHelper.copySpline(SPLINE); + SplineHelper.rotateSpline(spline, angle); + SplineHelper.scale(spline, size * MHelper.randRange(0.5F, 1F, random)); + SplineHelper.offsetParts(spline, random, 1F, 0, 1F); + SplineHelper.fillSpline(spline, world, EndBlocks.LUCERNIA.getBark().defaultBlockState(), pos, REPLACE); + Vector3f last = spline.get(spline.size() - 1); + float leavesRadius = (size * 0.13F + MHelper.randRange(0.8F, 1.5F, random)) * 1.4F; + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + leavesBall(world, pos.offset(last.x(), last.y(), last.z()), leavesRadius, random, noise, config != null); + } + + makeRoots(world, pos.offset(0, MHelper.randRange(3, 5, random), 0), size * 0.35F, random); + + return true; + } + + private void leavesBall( + WorldGenLevel world, + BlockPos pos, + float radius, + RandomSource random, + OpenSimplexNoise noise, + boolean natural + ) { + SDF sphere = new SDFSphere().setRadius(radius) + .setBlock(EndBlocks.LUCERNIA_LEAVES.defaultBlockState() + .setValue(LeavesBlock.DISTANCE, 6)); + SDF sub = new SDFScale().setScale(5).setSource(sphere); + sub = new SDFTranslate().setTranslate(0, -radius * 5, 0).setSource(sub); + sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sub); + sphere = new SDFScale3D().setScale(1, 0.75F, 1).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> (float) noise.eval( + vec.x() * 0.2, + vec.y() * 0.2, + vec.z() * 0.2 + ) * 2F).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> MHelper.randRange(-1.5F, 1.5F, random)).setSource(sphere); + + MutableBlockPos mut = new MutableBlockPos(); + for (Direction d1 : BlocksHelper.HORIZONTAL) { + BlockPos p = mut.set(pos).move(Direction.UP).move(d1).immutable(); + BlocksHelper.setWithoutUpdate(world, p, EndBlocks.LUCERNIA.getBark().defaultBlockState()); + for (Direction d2 : BlocksHelper.HORIZONTAL) { + mut.set(p).move(Direction.UP).move(d2); + BlocksHelper.setWithoutUpdate(world, p, EndBlocks.LUCERNIA.getBark().defaultBlockState()); + } + } + + BlockState top = EndBlocks.FILALUX.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP); + BlockState middle = EndBlocks.FILALUX.defaultBlockState() + .setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE); + BlockState bottom = EndBlocks.FILALUX.defaultBlockState() + .setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM); + BlockState outer = EndBlocks.LUCERNIA_OUTER_LEAVES.defaultBlockState(); + + List support = Lists.newArrayList(); + sphere.addPostProcess((info) -> { + if (natural && random.nextInt(6) == 0 && info.getStateDown().isAir()) { + BlockPos d = info.getPos().below(); + support.add(d); + } + if (random.nextInt(15) == 0) { + for (Direction dir : Direction.values()) { + BlockState state = info.getState(dir, 2); + if (state.isAir()) { + return info.getState(); + } + } + info.setState(EndBlocks.LUCERNIA.getBark().defaultBlockState()); + } + + MHelper.shuffle(DIRECTIONS, random); + for (Direction d : DIRECTIONS) { + if (info.getState(d).isAir()) { + info.setBlockPos(info.getPos().relative(d), outer.setValue(FurBlock.FACING, d)); + } + } + + if (EndBlocks.LUCERNIA.isTreeLog(info.getState())) { + for (int x = -6; x < 7; x++) { + int ax = Math.abs(x); + mut.setX(x + info.getPos().getX()); + for (int z = -6; z < 7; z++) { + int az = Math.abs(z); + mut.setZ(z + info.getPos().getZ()); + for (int y = -6; y < 7; y++) { + int ay = Math.abs(y); + int d = ax + ay + az; + if (d < 7) { + mut.setY(y + info.getPos().getY()); + BlockState state = info.getState(mut); + if (state.getBlock() instanceof LeavesBlock) { + int distance = state.getValue(LeavesBlock.DISTANCE); + if (d < distance) { + info.setState(mut, state.setValue(LeavesBlock.DISTANCE, d)); + } + } + } + } + } + } + } + return info.getState(); + }); + sphere.fillRecursiveIgnore(world, pos, IGNORE); + BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.LUCERNIA.getBark()); + + support.forEach((bpos) -> { + BlockState state = world.getBlockState(bpos); + if (state.isAir() || state.is(EndBlocks.LUCERNIA_OUTER_LEAVES)) { + int count = MHelper.randRange(3, 8, random); + mut.set(bpos); + if (world.getBlockState(mut.above()).is(EndBlocks.LUCERNIA_LEAVES)) { + BlocksHelper.setWithoutUpdate(world, mut, top); + for (int i = 1; i < count; i++) { + mut.setY(mut.getY() - 1); + if (world.isEmptyBlock(mut.below())) { + BlocksHelper.setWithoutUpdate(world, mut, middle); + } else { + break; + } + } + BlocksHelper.setWithoutUpdate(world, mut, bottom); + } + } + }); + } + + private void makeRoots(WorldGenLevel world, BlockPos pos, float radius, RandomSource random) { + int count = (int) (radius * 1.5F); + for (int i = 0; i < count; i++) { + float angle = (float) i / (float) count * MHelper.PI2; + float scale = radius * MHelper.randRange(0.85F, 1.15F, random); + + List branch = SplineHelper.copySpline(ROOT); + SplineHelper.rotateSpline(branch, angle); + SplineHelper.scale(branch, scale); + Vector3f last = branch.get(branch.size() - 1); + if (world.getBlockState(pos.offset(last.x(), last.y(), last.z())).is(CommonBlockTags.GEN_END_STONES)) { + SplineHelper.fillSplineForce( + branch, + world, + EndBlocks.LUCERNIA.getBark().defaultBlockState(), + pos, + REPLACE + ); + } + } + } + + static { + REPLACE = (state) -> { + /*if (state.is(CommonBlockTags.END_STONES)) { + return true; + }*/ + if (state.getBlock() == EndBlocks.LUCERNIA_LEAVES) { + return true; + } + if (state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + + IGNORE = EndBlocks.LUCERNIA::isTreeLog; + + SPLINE = Lists.newArrayList( + new Vector3f(0.00F, 0.00F, 0.00F), + new Vector3f(0.10F, 0.35F, 0.00F), + new Vector3f(0.20F, 0.50F, 0.00F), + new Vector3f(0.30F, 0.55F, 0.00F), + new Vector3f(0.42F, 0.70F, 0.00F), + new Vector3f(0.50F, 1.00F, 0.00F) + ); + + ROOT = Lists.newArrayList( + new Vector3f(0.1F, 0.70F, 0), + new Vector3f(0.3F, 0.30F, 0), + new Vector3f(0.7F, 0.05F, 0), + new Vector3f(0.8F, -0.20F, 0) + ); + SplineHelper.offset(ROOT, new Vector3f(0, -0.45F, 0)); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/trees/MossyGlowshroomFeature.java b/src/main/java/org/betterx/betterend/world/features/trees/MossyGlowshroomFeature.java new file mode 100644 index 00000000..eee93985 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/trees/MossyGlowshroomFeature.java @@ -0,0 +1,173 @@ +package org.betterx.betterend.world.features.trees; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.*; +import org.betterx.bclib.sdf.primitive.SDFCappedCone; +import org.betterx.bclib.sdf.primitive.SDFPrimitive; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.blocks.MossyGlowshroomCapBlock; +import org.betterx.betterend.blocks.basis.FurBlock; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import java.util.List; +import java.util.function.Function; + +public class MossyGlowshroomFeature extends DefaultFeature { + private static final Function REPLACE; + private static final Vector3f CENTER = new Vector3f(); + private static final SDFBinary FUNCTION; + private static final SDFTranslate HEAD_POS; + private static final SDFFlatWave ROOTS_ROT; + + private static final SDFPrimitive CONE1; + private static final SDFPrimitive CONE2; + private static final SDFPrimitive CONE_GLOW; + private static final SDFPrimitive ROOTS; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos blockPos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + BlockState down = world.getBlockState(blockPos.below()); + if (!down.is(EndBlocks.END_MYCELIUM) && !down.is(EndBlocks.END_MOSS)) return false; + + CONE1.setBlock(EndBlocks.MOSSY_GLOWSHROOM_CAP); + CONE2.setBlock(EndBlocks.MOSSY_GLOWSHROOM_CAP); + CONE_GLOW.setBlock(EndBlocks.MOSSY_GLOWSHROOM_HYMENOPHORE); + ROOTS.setBlock(EndBlocks.MOSSY_GLOWSHROOM.getBark()); + + float height = MHelper.randRange(10F, 25F, random); + int count = MHelper.floor(height / 4); + List spline = SplineHelper.makeSpline(0, 0, 0, 0, height, 0, count); + SplineHelper.offsetParts(spline, random, 1F, 0, 1F); + SDF sdf = SplineHelper.buildSDF(spline, 2.1F, 1.5F, (pos) -> { + return EndBlocks.MOSSY_GLOWSHROOM.getLog().defaultBlockState(); + }); + Vector3f pos = spline.get(spline.size() - 1); + float scale = MHelper.randRange(0.75F, 1.1F, random); + + if (!SplineHelper.canGenerate(spline, scale, blockPos, world, REPLACE)) { + return false; + } + BlocksHelper.setWithoutUpdate(world, blockPos, AIR); + + CENTER.set(blockPos.getX(), 0, blockPos.getZ()); + HEAD_POS.setTranslate(pos.x(), pos.y(), pos.z()); + ROOTS_ROT.setAngle(random.nextFloat() * MHelper.PI2); + FUNCTION.setSourceA(sdf); + + new SDFScale().setScale(scale).setSource(FUNCTION).setReplaceFunction(REPLACE).addPostProcess((info) -> { + if (EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getState())) { + if (random.nextBoolean() && info.getStateUp().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_CAP) { + info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.defaultBlockState() + .setValue(MossyGlowshroomCapBlock.TRANSITION, true)); + return info.getState(); + } else if (!EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getStateUp()) || !EndBlocks.MOSSY_GLOWSHROOM.isTreeLog( + info.getStateDown())) { + info.setState(EndBlocks.MOSSY_GLOWSHROOM.getBark().defaultBlockState()); + return info.getState(); + } + } else if (info.getState().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_CAP) { + if (EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown().getBlock())) { + info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.defaultBlockState() + .setValue(MossyGlowshroomCapBlock.TRANSITION, true)); + return info.getState(); + } + + info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.defaultBlockState()); + return info.getState(); + } else if (info.getState().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_HYMENOPHORE) { + for (Direction dir : BlocksHelper.HORIZONTAL) { + if (info.getState(dir) == AIR) { + info.setBlockPos( + info.getPos().relative(dir), + EndBlocks.MOSSY_GLOWSHROOM_FUR.defaultBlockState().setValue(FurBlock.FACING, dir) + ); + } + } + + if (info.getStateDown().getBlock() != EndBlocks.MOSSY_GLOWSHROOM_HYMENOPHORE) { + info.setBlockPos( + info.getPos().below(), + EndBlocks.MOSSY_GLOWSHROOM_FUR.defaultBlockState().setValue(FurBlock.FACING, Direction.DOWN) + ); + } + } + return info.getState(); + }).fillRecursive(world, blockPos); + + return true; + } + + static { + SDFCappedCone cone1 = new SDFCappedCone().setHeight(2.5F).setRadius1(1.5F).setRadius2(2.5F); + SDFCappedCone cone2 = new SDFCappedCone().setHeight(3F).setRadius1(2.5F).setRadius2(13F); + SDF posedCone2 = new SDFTranslate().setTranslate(0, 5, 0).setSource(cone2); + SDF posedCone3 = new SDFTranslate().setTranslate(0, 12F, 0) + .setSource(new SDFScale().setScale(2).setSource(cone2)); + SDF upCone = new SDFSubtraction().setSourceA(posedCone2).setSourceB(posedCone3); + SDF wave = new SDFFlatWave().setRaysCount(12).setIntensity(1.3F).setSource(upCone); + SDF cones = new SDFSmoothUnion().setRadius(3).setSourceA(cone1).setSourceB(wave); + + CONE1 = cone1; + CONE2 = cone2; + + SDF innerCone = new SDFTranslate().setTranslate(0, 1.25F, 0).setSource(upCone); + innerCone = new SDFScale3D().setScale(1.2F, 1F, 1.2F).setSource(innerCone); + cones = new SDFUnion().setSourceA(cones).setSourceB(innerCone); + + SDF glowCone = new SDFCappedCone().setHeight(3F).setRadius1(2F).setRadius2(12.5F); + CONE_GLOW = (SDFPrimitive) glowCone; + glowCone = new SDFTranslate().setTranslate(0, 4.25F, 0).setSource(glowCone); + glowCone = new SDFSubtraction().setSourceA(glowCone).setSourceB(posedCone3); + + cones = new SDFUnion().setSourceA(cones).setSourceB(glowCone); + + OpenSimplexNoise noise = new OpenSimplexNoise(1234); + cones = new SDFCoordModify().setFunction((pos) -> { + float dist = MHelper.length(pos.x(), pos.z()); + float y = pos.y() + (float) noise.eval( + pos.x() * 0.1 + CENTER.x(), + pos.z() * 0.1 + CENTER.z() + ) * dist * 0.3F - dist * 0.15F; + pos.set(pos.x(), y, pos.z()); + }).setSource(cones); + + HEAD_POS = (SDFTranslate) new SDFTranslate().setSource(new SDFTranslate().setTranslate(0, 2.5F, 0) + .setSource(cones)); + + SDF roots = new SDFSphere().setRadius(4F); + ROOTS = (SDFPrimitive) roots; + roots = new SDFScale3D().setScale(1, 0.7F, 1).setSource(roots); + ROOTS_ROT = (SDFFlatWave) new SDFFlatWave().setRaysCount(5).setIntensity(1.5F).setSource(roots); + + FUNCTION = new SDFSmoothUnion().setRadius(4) + .setSourceB(new SDFUnion().setSourceA(HEAD_POS).setSourceB(ROOTS_ROT)); + + REPLACE = (state) -> { + /*if (state.is(CommonBlockTags.END_STONES)) { + return true; + }*/ + if (state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/trees/PythadendronTreeFeature.java b/src/main/java/org/betterx/betterend/world/features/trees/PythadendronTreeFeature.java new file mode 100644 index 00000000..26d0c0b6 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/trees/PythadendronTreeFeature.java @@ -0,0 +1,224 @@ +package org.betterx.betterend.world.features.trees; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.PosInfo; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFDisplacement; +import org.betterx.bclib.sdf.operator.SDFScale3D; +import org.betterx.bclib.sdf.operator.SDFSubtraction; +import org.betterx.bclib.sdf.operator.SDFTranslate; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import java.util.List; +import java.util.function.Function; + +public class PythadendronTreeFeature extends DefaultFeature { + private static final Function REPLACE; + private static final Function IGNORE; + private static final Function POST; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (world.getBlockState(pos.below()).getBlock() != EndBlocks.CHORUS_NYLIUM) { + return false; + } + BlocksHelper.setWithoutUpdate(world, pos, AIR); + + float size = MHelper.randRange(10, 20, random); + List spline = SplineHelper.makeSpline(0, 0, 0, 0, size, 0, 4); + SplineHelper.offsetParts(spline, random, 0.7F, 0, 0.7F); + Vector3f last = spline.get(spline.size() - 1); + + int depth = MHelper.floor((size - 10F) * 3F / 10F + 1F); + float bsize = (10F - (size - 10F)) / 10F + 1.5F; + branch( + last.x(), + last.y(), + last.z(), + size * bsize, + MHelper.randRange(0, MHelper.PI2, random), + random, + depth, + world, + pos + ); + + SDF function = SplineHelper.buildSDF(spline, 1.7F, 1.1F, (bpos) -> { + return EndBlocks.PYTHADENDRON.getBark().defaultBlockState(); + }); + function.setReplaceFunction(REPLACE); + function.addPostProcess(POST); + function.fillRecursive(world, pos); + + return true; + } + + private void branch( + float x, + float y, + float z, + float size, + float angle, + RandomSource random, + int depth, + WorldGenLevel world, + BlockPos pos + ) { + if (depth == 0) return; + + float dx = (float) Math.cos(angle) * size * 0.15F; + float dz = (float) Math.sin(angle) * size * 0.15F; + + float x1 = x + dx; + float z1 = z + dz; + float x2 = x - dx; + float z2 = z - dz; + + List spline = SplineHelper.makeSpline(x, y, z, x1, y, z1, 5); + SplineHelper.powerOffset(spline, size * MHelper.randRange(1.0F, 2.0F, random), 4); + SplineHelper.offsetParts(spline, random, 0.3F, 0, 0.3F); + Vector3f pos1 = spline.get(spline.size() - 1); + + boolean s1 = SplineHelper.fillSpline( + spline, + world, + EndBlocks.PYTHADENDRON.getBark().defaultBlockState(), + pos, + REPLACE + ); + + spline = SplineHelper.makeSpline(x, y, z, x2, y, z2, 5); + SplineHelper.powerOffset(spline, size * MHelper.randRange(1.0F, 2.0F, random), 4); + SplineHelper.offsetParts(spline, random, 0.3F, 0, 0.3F); + Vector3f pos2 = spline.get(spline.size() - 1); + + boolean s2 = SplineHelper.fillSpline( + spline, + world, + EndBlocks.PYTHADENDRON.getBark().defaultBlockState(), + pos, + REPLACE + ); + + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextInt()); + if (depth < 3) { + if (s1) { + leavesBall(world, pos.offset(pos1.x(), pos1.y(), pos1.z()), random, noise); + } + if (s2) { + leavesBall(world, pos.offset(pos2.x(), pos2.y(), pos2.z()), random, noise); + } + } + + float size1 = size * MHelper.randRange(0.75F, 0.95F, random); + float size2 = size * MHelper.randRange(0.75F, 0.95F, random); + float angle1 = angle + (float) Math.PI * 0.5F + MHelper.randRange(-0.1F, 0.1F, random); + float angle2 = angle + (float) Math.PI * 0.5F + MHelper.randRange(-0.1F, 0.1F, random); + + if (s1) { + branch(pos1.x(), pos1.y(), pos1.z(), size1, angle1, random, depth - 1, world, pos); + } + if (s2) { + branch(pos2.x(), pos2.y(), pos2.z(), size2, angle2, random, depth - 1, world, pos); + } + } + + private void leavesBall(WorldGenLevel world, BlockPos pos, RandomSource random, OpenSimplexNoise noise) { + float radius = MHelper.randRange(4.5F, 6.5F, random); + + SDF sphere = new SDFSphere().setRadius(radius) + .setBlock(EndBlocks.PYTHADENDRON_LEAVES.defaultBlockState() + .setValue(LeavesBlock.DISTANCE, 6)); + sphere = new SDFScale3D().setScale(1, 0.6F, 1).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> { + return (float) noise.eval(vec.x() * 0.2, vec.y() * 0.2, vec.z() * 0.2) * 3; + }).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> { + return random.nextFloat() * 3F - 1.5F; + }).setSource(sphere); + sphere = new SDFSubtraction().setSourceA(sphere) + .setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere)); + MutableBlockPos mut = new MutableBlockPos(); + sphere.addPostProcess((info) -> { + if (random.nextInt(5) == 0) { + for (Direction dir : Direction.values()) { + BlockState state = info.getState(dir, 2); + if (state.isAir()) { + return info.getState(); + } + } + info.setState(EndBlocks.PYTHADENDRON.getBark().defaultBlockState()); + for (int x = -6; x < 7; x++) { + int ax = Math.abs(x); + mut.setX(x + info.getPos().getX()); + for (int z = -6; z < 7; z++) { + int az = Math.abs(z); + mut.setZ(z + info.getPos().getZ()); + for (int y = -6; y < 7; y++) { + int ay = Math.abs(y); + int d = ax + ay + az; + if (d < 7) { + mut.setY(y + info.getPos().getY()); + BlockState state = info.getState(mut); + if (state.getBlock() instanceof LeavesBlock) { + int distance = state.getValue(LeavesBlock.DISTANCE); + if (d < distance) { + info.setState(mut, state.setValue(LeavesBlock.DISTANCE, d)); + } + } + } + } + } + } + } + return info.getState(); + }); + sphere.fillRecursiveIgnore(world, pos, IGNORE); + } + + static { + REPLACE = (state) -> { + /*if (state.is(CommonBlockTags.END_STONES)) { + return true; + }*/ + if (state.getBlock() == EndBlocks.PYTHADENDRON_LEAVES) { + return true; + } + if (state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + + IGNORE = (state) -> { + return EndBlocks.PYTHADENDRON.isTreeLog(state); + }; + + POST = (info) -> { + if (EndBlocks.PYTHADENDRON.isTreeLog(info.getStateUp()) && EndBlocks.PYTHADENDRON.isTreeLog(info.getStateDown())) { + return EndBlocks.PYTHADENDRON.getLog().defaultBlockState(); + } + return info.getState(); + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/trees/TenaneaFeature.java b/src/main/java/org/betterx/betterend/world/features/trees/TenaneaFeature.java new file mode 100644 index 00000000..4b4f5495 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/trees/TenaneaFeature.java @@ -0,0 +1,204 @@ +package org.betterx.betterend.world.features.trees; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.blocks.BlockProperties; +import org.betterx.bclib.blocks.BlockProperties.TripleShape; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.*; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.blocks.basis.FurBlock; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.function.Function; + +public class TenaneaFeature extends DefaultFeature { + private static final Direction[] DIRECTIONS = Direction.values(); + private static final Function REPLACE; + private static final Function IGNORE; + private static final List SPLINE; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + if (!world.getBlockState(pos.below()).is(BlockTags.NYLIUM)) return false; + + float size = MHelper.randRange(7, 10, random); + int count = (int) (size * 0.45F); + float var = MHelper.PI2 / (float) (count * 3); + float start = MHelper.randRange(0, MHelper.PI2, random); + for (int i = 0; i < count; i++) { + float angle = (float) i / (float) count * MHelper.PI2 + MHelper.randRange(0, var, random) + start; + List spline = SplineHelper.copySpline(SPLINE); + SplineHelper.rotateSpline(spline, angle); + SplineHelper.scale(spline, size + MHelper.randRange(0, size * 0.5F, random)); + SplineHelper.offsetParts(spline, random, 1F, 0, 1F); + SplineHelper.fillSpline(spline, world, EndBlocks.TENANEA.getBark().defaultBlockState(), pos, REPLACE); + Vector3f last = spline.get(spline.size() - 1); + float leavesRadius = (size * 0.3F + MHelper.randRange(0.8F, 1.5F, random)) * 1.4F; + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + leavesBall(world, pos.offset(last.x(), last.y(), last.z()), leavesRadius, random, noise); + } + + return true; + } + + private void leavesBall( + WorldGenLevel world, + BlockPos pos, + float radius, + RandomSource random, + OpenSimplexNoise noise + ) { + SDF sphere = new SDFSphere().setRadius(radius) + .setBlock(EndBlocks.TENANEA_LEAVES.defaultBlockState() + .setValue(LeavesBlock.DISTANCE, 6)); + SDF sub = new SDFScale().setScale(5).setSource(sphere); + sub = new SDFTranslate().setTranslate(0, -radius * 5, 0).setSource(sub); + sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sub); + sphere = new SDFScale3D().setScale(1, 0.75F, 1).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> (float) noise.eval( + vec.x() * 0.2, + vec.y() * 0.2, + vec.z() * 0.2 + ) * 2F).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> MHelper.randRange(-1.5F, 1.5F, random)).setSource(sphere); + + MutableBlockPos mut = new MutableBlockPos(); + for (Direction d1 : BlocksHelper.HORIZONTAL) { + BlockPos p = mut.set(pos).move(Direction.UP).move(d1).immutable(); + BlocksHelper.setWithoutUpdate(world, p, EndBlocks.TENANEA.getBark().defaultBlockState()); + for (Direction d2 : BlocksHelper.HORIZONTAL) { + mut.set(p).move(Direction.UP).move(d2); + BlocksHelper.setWithoutUpdate(world, p, EndBlocks.TENANEA.getBark().defaultBlockState()); + } + } + + BlockState top = EndBlocks.TENANEA_FLOWERS.defaultBlockState() + .setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP); + BlockState middle = EndBlocks.TENANEA_FLOWERS.defaultBlockState() + .setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE); + BlockState bottom = EndBlocks.TENANEA_FLOWERS.defaultBlockState() + .setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM); + BlockState outer = EndBlocks.TENANEA_OUTER_LEAVES.defaultBlockState(); + + List support = Lists.newArrayList(); + sphere.addPostProcess((info) -> { + if (random.nextInt(6) == 0 && info.getStateDown().isAir()) { + BlockPos d = info.getPos().below(); + support.add(d); + } + if (random.nextInt(5) == 0) { + for (Direction dir : Direction.values()) { + BlockState state = info.getState(dir, 2); + if (state.isAir()) { + return info.getState(); + } + } + info.setState(EndBlocks.TENANEA.getBark().defaultBlockState()); + } + + MHelper.shuffle(DIRECTIONS, random); + for (Direction d : DIRECTIONS) { + if (info.getState(d).isAir()) { + info.setBlockPos(info.getPos().relative(d), outer.setValue(FurBlock.FACING, d)); + } + } + + if (EndBlocks.TENANEA.isTreeLog(info.getState())) { + for (int x = -6; x < 7; x++) { + int ax = Math.abs(x); + mut.setX(x + info.getPos().getX()); + for (int z = -6; z < 7; z++) { + int az = Math.abs(z); + mut.setZ(z + info.getPos().getZ()); + for (int y = -6; y < 7; y++) { + int ay = Math.abs(y); + int d = ax + ay + az; + if (d < 7) { + mut.setY(y + info.getPos().getY()); + BlockState state = info.getState(mut); + if (state.getBlock() instanceof LeavesBlock) { + int distance = state.getValue(LeavesBlock.DISTANCE); + if (d < distance) { + info.setState(mut, state.setValue(LeavesBlock.DISTANCE, d)); + } + } + } + } + } + } + } + return info.getState(); + }); + sphere.fillRecursiveIgnore(world, pos, IGNORE); + BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.TENANEA.getBark()); + + support.forEach((bpos) -> { + BlockState state = world.getBlockState(bpos); + if (state.isAir() || state.is(EndBlocks.TENANEA_OUTER_LEAVES)) { + int count = MHelper.randRange(3, 8, random); + mut.set(bpos); + if (world.getBlockState(mut.above()).is(EndBlocks.TENANEA_LEAVES)) { + BlocksHelper.setWithoutUpdate(world, mut, top); + for (int i = 1; i < count; i++) { + mut.setY(mut.getY() - 1); + if (world.isEmptyBlock(mut.below())) { + BlocksHelper.setWithoutUpdate(world, mut, middle); + } else { + break; + } + } + BlocksHelper.setWithoutUpdate(world, mut, bottom); + } + } + }); + } + + static { + REPLACE = (state) -> { + /*if (state.is(CommonBlockTags.END_STONES)) { + return true; + }*/ + if (state.getBlock() == EndBlocks.TENANEA_LEAVES) { + return true; + } + if (state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + + IGNORE = EndBlocks.TENANEA::isTreeLog; + + SPLINE = Lists.newArrayList( + new Vector3f(0.00F, 0.00F, 0.00F), + new Vector3f(0.10F, 0.35F, 0.00F), + new Vector3f(0.20F, 0.50F, 0.00F), + new Vector3f(0.30F, 0.55F, 0.00F), + new Vector3f(0.42F, 0.70F, 0.00F), + new Vector3f(0.50F, 1.00F, 0.00F) + ); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/trees/UmbrellaTreeFeature.java b/src/main/java/org/betterx/betterend/world/features/trees/UmbrellaTreeFeature.java new file mode 100644 index 00000000..c39fb2e2 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/trees/UmbrellaTreeFeature.java @@ -0,0 +1,250 @@ +package org.betterx.betterend.world.features.trees; + +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.*; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.blocks.UmbrellaTreeClusterBlock; +import org.betterx.betterend.blocks.UmbrellaTreeMembraneBlock; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.material.Material; + +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.function.Function; + +public class UmbrellaTreeFeature extends DefaultFeature { + private static final Function REPLACE; + private static final List SPLINE; + private static final List ROOT; + + @Override + public boolean place(FeaturePlaceContext featureConfig) { + final RandomSource random = featureConfig.random(); + final BlockPos pos = featureConfig.origin(); + final WorldGenLevel world = featureConfig.level(); + final NoneFeatureConfiguration config = featureConfig.config(); + if (!world.getBlockState(pos.below()).is(BlockTags.NYLIUM)) return false; + + BlockState wood = EndBlocks.UMBRELLA_TREE.getBark().defaultBlockState(); + BlockState membrane = EndBlocks.UMBRELLA_TREE_MEMBRANE.defaultBlockState() + .setValue(UmbrellaTreeMembraneBlock.COLOR, 1); + BlockState center = EndBlocks.UMBRELLA_TREE_MEMBRANE.defaultBlockState() + .setValue(UmbrellaTreeMembraneBlock.COLOR, 0); + BlockState fruit = EndBlocks.UMBRELLA_TREE_CLUSTER.defaultBlockState() + .setValue(UmbrellaTreeClusterBlock.NATURAL, true); + + float size = MHelper.randRange(10, 20, random); + int count = (int) (size * 0.15F); + float var = MHelper.PI2 / (float) (count * 3); + float start = MHelper.randRange(0, MHelper.PI2, random); + SDF sdf = null; + List
centers = Lists.newArrayList(); + + float scale = 1; + if (config != null) { + scale = MHelper.randRange(1F, 1.7F, random); + } + + for (int i = 0; i < count; i++) { + float angle = (float) i / (float) count * MHelper.PI2 + MHelper.randRange(0, var, random) + start; + List spline = SplineHelper.copySpline(SPLINE); + float sizeXZ = (size + MHelper.randRange(0, size * 0.5F, random)) * 0.7F; + SplineHelper.scale(spline, sizeXZ, sizeXZ * MHelper.randRange(1F, 2F, random), sizeXZ); + // SplineHelper.offset(spline, new Vector3f((20 - size) * 0.2F, 0, 0)); + SplineHelper.rotateSpline(spline, angle); + SplineHelper.offsetParts(spline, random, 0.5F, 0, 0.5F); + + if (SplineHelper.canGenerate(spline, pos, world, REPLACE)) { + float rScale = (scale - 1) * 0.4F + 1; + SDF branch = SplineHelper.buildSDF(spline, 1.2F * rScale, 0.8F * rScale, (bpos) -> { + return wood; + }); + + Vector3f vec = spline.get(spline.size() - 1); + float radius = (size + MHelper.randRange(0, size * 0.5F, random)) * 0.4F; + + sdf = (sdf == null) ? branch : new SDFUnion().setSourceA(sdf).setSourceB(branch); + SDF mem = makeMembrane(world, radius, random, membrane, center); + + float px = MHelper.floor(vec.x()) + 0.5F; + float py = MHelper.floor(vec.y()) + 0.5F; + float pz = MHelper.floor(vec.z()) + 0.5F; + mem = new SDFTranslate().setTranslate(px, py, pz).setSource(mem); + sdf = new SDFSmoothUnion().setRadius(2).setSourceA(sdf).setSourceB(mem); + centers.add(new Center( + pos.getX() + (double) (px * scale), + pos.getY() + (double) (py * scale), + pos.getZ() + (double) (pz * scale), + radius * scale + )); + + vec = spline.get(0); + } + } + + if (sdf == null) { + return false; + } + + if (scale > 1) { + sdf = new SDFScale().setScale(scale).setSource(sdf); + } + + sdf.setReplaceFunction(REPLACE).addPostProcess((info) -> { + if (EndBlocks.UMBRELLA_TREE.isTreeLog(info.getStateUp()) && EndBlocks.UMBRELLA_TREE.isTreeLog(info.getStateDown())) { + return EndBlocks.UMBRELLA_TREE.getLog().defaultBlockState(); + } else if (info.getState().equals(membrane)) { + Center min = centers.get(0); + double d = Double.MAX_VALUE; + BlockPos bpos = info.getPos(); + for (Center c : centers) { + double d2 = c.distance(bpos.getX(), bpos.getZ()); + if (d2 < d) { + d = d2; + min = c; + } + } + int color = MHelper.floor(d / min.radius * 7); + color = Mth.clamp(color, 1, 7); + return info.getState().setValue(UmbrellaTreeMembraneBlock.COLOR, color); + } + return info.getState(); + }).fillRecursive(world, pos); + makeRoots(world, pos, (size * 0.5F + 3) * scale, random, wood); + + for (Center c : centers) { + if (!world.getBlockState(new BlockPos(c.px, c.py, c.pz)).isAir()) { + count = MHelper.floor(MHelper.randRange(5F, 10F, random) * scale); + float startAngle = random.nextFloat() * MHelper.PI2; + for (int i = 0; i < count; i++) { + float angle = (float) i / count * MHelper.PI2 + startAngle; + float dist = MHelper.randRange(1.5F, 2.5F, random) * scale; + double px = c.px + Math.sin(angle) * dist; + double pz = c.pz + Math.cos(angle) * dist; + makeFruits(world, px, c.py - 1, pz, fruit, scale); + } + } + } + + return true; + } + + private void makeRoots(WorldGenLevel world, BlockPos pos, float radius, RandomSource random, BlockState wood) { + int count = (int) (radius * 1.5F); + for (int i = 0; i < count; i++) { + float angle = (float) i / (float) count * MHelper.PI2; + float scale = radius * MHelper.randRange(0.85F, 1.15F, random); + + List branch = SplineHelper.copySpline(ROOT); + SplineHelper.rotateSpline(branch, angle); + SplineHelper.scale(branch, scale); + Vector3f last = branch.get(branch.size() - 1); + if (world.getBlockState(pos.offset(last.x(), last.y(), last.z())).is(CommonBlockTags.GEN_END_STONES)) { + SplineHelper.fillSplineForce(branch, world, wood, pos, REPLACE); + } + } + } + + private SDF makeMembrane( + WorldGenLevel world, + float radius, + RandomSource random, + BlockState membrane, + BlockState center + ) { + SDF sphere = new SDFSphere().setRadius(radius).setBlock(membrane); + SDF sub = new SDFTranslate().setTranslate(0, -4, 0).setSource(sphere); + sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sub); + sphere = new SDFScale3D().setScale(1, 0.5F, 1).setSource(sphere); + sphere = new SDFTranslate().setTranslate(0, 1 - radius * 0.5F, 0).setSource(sphere); + + float angle = random.nextFloat() * MHelper.PI2; + int count = (int) MHelper.randRange(radius, radius * 2, random); + if (count < 5) { + count = 5; + } + sphere = new SDFFlatWave().setAngle(angle).setRaysCount(count).setIntensity(0.6F).setSource(sphere); + + SDF cent = new SDFSphere().setRadius(2.5F).setBlock(center); + sphere = new SDFUnion().setSourceA(sphere).setSourceB(cent); + + return sphere; + } + + private void makeFruits(WorldGenLevel world, double px, double py, double pz, BlockState fruit, float scale) { + MutableBlockPos mut = new MutableBlockPos().set(px, py, pz); + for (int i = 0; i < 8; i++) { + mut.move(Direction.DOWN); + if (world.isEmptyBlock(mut)) { + BlockState state = world.getBlockState(mut.above()); + if (state.is(EndBlocks.UMBRELLA_TREE_MEMBRANE) && state.getValue(UmbrellaTreeMembraneBlock.COLOR) < 2) { + BlocksHelper.setWithoutUpdate(world, mut, fruit); + } + break; + } + } + } + + static { + SPLINE = Lists.newArrayList( + new Vector3f(0.00F, 0.00F, 0.00F), + new Vector3f(0.10F, 0.35F, 0.00F), + new Vector3f(0.20F, 0.50F, 0.00F), + new Vector3f(0.30F, 0.55F, 0.00F), + new Vector3f(0.42F, 0.70F, 0.00F), + new Vector3f(0.50F, 1.00F, 0.00F) + ); + + ROOT = Lists.newArrayList( + new Vector3f(0.1F, 0.70F, 0), + new Vector3f(0.3F, 0.30F, 0), + new Vector3f(0.7F, 0.05F, 0), + new Vector3f(0.8F, -0.20F, 0) + ); + SplineHelper.offset(ROOT, new Vector3f(0, -0.45F, 0)); + + REPLACE = (state) -> { + if (/*state.is(CommonBlockTags.END_STONES) || */state.getMaterial().equals(Material.PLANT) || state.is( + EndBlocks.UMBRELLA_TREE_MEMBRANE)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + } + + private class Center { + final double px; + final double py; + final double pz; + final float radius; + + Center(double x, double y, double z, float radius) { + this.px = x; + this.py = y; + this.pz = z; + this.radius = radius; + } + + double distance(float x, float z) { + return MHelper.length(px - x, pz - z); + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/generator/BiomeType.java b/src/main/java/org/betterx/betterend/world/generator/BiomeType.java new file mode 100644 index 00000000..c6a3ded5 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/generator/BiomeType.java @@ -0,0 +1,5 @@ +package org.betterx.betterend.world.generator; + +public enum BiomeType { + LAND, VOID +} diff --git a/src/main/java/org/betterx/betterend/world/generator/EndLandBiomeDecider.java b/src/main/java/org/betterx/betterend/world/generator/EndLandBiomeDecider.java new file mode 100644 index 00000000..c5758d16 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/generator/EndLandBiomeDecider.java @@ -0,0 +1,63 @@ +package org.betterx.betterend.world.generator; + +import org.betterx.bclib.api.v2.generator.BCLBiomeSource; +import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource; +import org.betterx.bclib.api.v2.generator.BiomeDecider; +import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; + +import net.minecraft.core.Registry; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeSource; + +public class EndLandBiomeDecider extends BiomeDecider { + public EndLandBiomeDecider() { + this(null); + } + + protected EndLandBiomeDecider(Registry biomeRegistry) { + super(biomeRegistry, (biome) -> false); + } + + @Override + public boolean canProvideFor(BiomeSource source) { + if (source instanceof BCLibEndBiomeSource endSource) { + return endSource.getTogetherConfig().generatorVersion == BCLEndBiomeSourceConfig.EndBiomeGeneratorType.PAULEVS; + } + return false; + } + + @Override + public BiomeDecider createInstance(BCLBiomeSource biomeSource) { + return new EndLandBiomeDecider(biomeSource.getBiomeRegistry()); + } + + @Override + public BiomeAPI.BiomeType suggestType( + BiomeAPI.BiomeType originalType, + BiomeAPI.BiomeType suggestedType, + double density, + int maxHeight, + int blockX, + int blockY, + int blockZ, + int quarterX, + int quarterY, + int quarterZ + ) { + if (TerrainGenerator.isLand(quarterX, quarterZ, maxHeight)) { + return suggestedType.equals(BiomeAPI.BiomeType.END_CENTER) + ? suggestedType + : BiomeAPI.BiomeType.END_LAND; + } else { + return suggestedType.equals(BiomeAPI.BiomeType.END_CENTER) + ? BiomeAPI.BiomeType.END_BARRENS + : BiomeAPI.BiomeType.END_VOID; + } + } + + @Override + public boolean canProvideBiome(BiomeAPI.BiomeType suggestedType) { + return false; + } +} diff --git a/src/main/java/org/betterx/betterend/world/generator/GeneratorOptions.java b/src/main/java/org/betterx/betterend/world/generator/GeneratorOptions.java new file mode 100644 index 00000000..30e54306 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/generator/GeneratorOptions.java @@ -0,0 +1,153 @@ +package org.betterx.betterend.world.generator; + +import org.betterx.betterend.config.Configs; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.Mth; + +public class GeneratorOptions { + private static int biomeSizeCaves; + private static boolean hasPortal; + private static boolean hasPillars; + private static boolean hasDragonFights; + private static boolean changeChorusPlant; + private static boolean newGenerator; + private static boolean generateCentralIsland; + private static boolean generateObsidianPlatform; + private static int endCityFailChance; + public static LayerOptions bigOptions; + public static LayerOptions mediumOptions; + public static LayerOptions smallOptions; + private static boolean changeSpawn; + private static BlockPos spawn; + private static boolean replacePortal; + private static boolean replacePillars; + private static int islandDistChunk; + private static boolean directSpikeHeight; + private static int circleRadius = 1000; + private static int circleRadiusSqr; + + public static void init() { + biomeSizeCaves = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeCaves", 32); + hasPortal = Configs.GENERATOR_CONFIG.getBoolean("portal", "hasPortal", true); + hasPillars = Configs.GENERATOR_CONFIG.getBoolean("spikes", "hasSpikes", true); + hasDragonFights = Configs.GENERATOR_CONFIG.getBooleanRoot("hasDragonFights", true); + changeChorusPlant = Configs.GENERATOR_CONFIG.getBoolean("chorusPlant", "changeChorusPlant", true); + newGenerator = Configs.GENERATOR_CONFIG.getBoolean("customGenerator", "useNewGenerator", true); + generateCentralIsland = Configs.GENERATOR_CONFIG.getBoolean("customGenerator", "generateCentralIsland", true); + endCityFailChance = Configs.GENERATOR_CONFIG.getInt("customGenerator", "endCityFailChance", 5); + generateObsidianPlatform = Configs.GENERATOR_CONFIG.getBooleanRoot("generateObsidianPlatform", true); + bigOptions = new LayerOptions( + "customGenerator.layers.bigIslands", + Configs.GENERATOR_CONFIG, + 300, + 200, + 70f / 128, + 10f / 128, + false + ); + mediumOptions = new LayerOptions( + "customGenerator.layers.mediumIslands", + Configs.GENERATOR_CONFIG, + 150, + 100, + 70f / 128, + 20f / 128, + true + ); + smallOptions = new LayerOptions( + "customGenerator.layers.smallIslands", + Configs.GENERATOR_CONFIG, + 60, + 50, + 70f / 128, + 30f / 128, + false + ); + changeSpawn = Configs.GENERATOR_CONFIG.getBoolean("spawn", "changeSpawn", false); + spawn = new BlockPos( + Configs.GENERATOR_CONFIG.getInt("spawn.point", "x", 20), + Configs.GENERATOR_CONFIG.getInt("spawn.point", "y", 65), + Configs.GENERATOR_CONFIG.getInt("spawn.point", "z", 0) + ); + replacePortal = Configs.GENERATOR_CONFIG.getBoolean("portal", "customEndPortal", true); + replacePillars = Configs.GENERATOR_CONFIG.getBoolean("spikes", "customObsidianSpikes", true); + circleRadius = Configs.GENERATOR_CONFIG.getInt("customGenerator", "voidRingSize", 1000); + circleRadiusSqr = circleRadius * circleRadius; + islandDistChunk = (circleRadius >> 3); // Twice bigger than normal + } + + public static int getBiomeSizeCaves() { + return Mth.clamp(biomeSizeCaves, 1, 8192); + } + + public static boolean hasPortal() { + return hasPortal; + } + + public static boolean hasPillars() { + return hasPillars; + } + + public static boolean hasDragonFights() { + return hasDragonFights; + } + + public static boolean changeChorusPlant() { + return changeChorusPlant; + } + + public static boolean useNewGenerator() { + return newGenerator; + } + + public static boolean hasCentralIsland() { + return generateCentralIsland; + } + + public static boolean generateObsidianPlatform() { + return generateObsidianPlatform; + } + + public static int getEndCityFailChance() { + return endCityFailChance; + } + + public static boolean changeSpawn() { + return changeSpawn; + } + + public static BlockPos getSpawn() { + return spawn; + } + + public static boolean replacePortal() { + return replacePortal; + } + + public static boolean replacePillars() { + return replacePillars; + } + + public static int getIslandDistBlock() { + return circleRadius; + } + + public static int getIslandDistBlockSqr() { + return circleRadiusSqr; + } + + public static int getIslandDistChunk() { + return islandDistChunk; + } + + public static void setDirectSpikeHeight() { + directSpikeHeight = true; + } + + public static boolean isDirectSpikeHeight() { + boolean height = directSpikeHeight; + directSpikeHeight = false; + return height; + } +} diff --git a/src/main/java/org/betterx/betterend/world/generator/IslandLayer.java b/src/main/java/org/betterx/betterend/world/generator/IslandLayer.java new file mode 100644 index 00000000..86b9fdb9 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/generator/IslandLayer.java @@ -0,0 +1,193 @@ +package org.betterx.betterend.world.generator; + +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFRadialNoiseMap; +import org.betterx.bclib.sdf.operator.SDFScale; +import org.betterx.bclib.sdf.operator.SDFSmoothUnion; +import org.betterx.bclib.sdf.operator.SDFTranslate; +import org.betterx.bclib.sdf.primitive.SDFCappedCone; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.levelgen.LegacyRandomSource; + +import com.google.common.collect.Maps; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class IslandLayer { + private static final RandomSource RANDOM = new LegacyRandomSource(MHelper.RANDOM.nextLong()); + private final SDFRadialNoiseMap noise; + private final SDF island; + + private final List positions = new ArrayList(9); + private final Map islands = Maps.newHashMap(); + private final OpenSimplexNoise density; + private final int seed; + private int lastX = Integer.MIN_VALUE; + private int lastZ = Integer.MIN_VALUE; + private final LayerOptions options; + + public IslandLayer(int seed, LayerOptions options) { + this.density = new OpenSimplexNoise(seed); + this.options = options; + this.seed = seed; + + SDF cone1 = makeCone(0, 0.4F, 0.2F, -0.3F); + SDF cone2 = makeCone(0.4F, 0.5F, 0.1F, -0.1F); + SDF cone3 = makeCone(0.5F, 0.45F, 0.03F, 0.0F); + SDF cone4 = makeCone(0.45F, 0, 0.02F, 0.03F); + + SDF coneBottom = new SDFSmoothUnion().setRadius(0.02F).setSourceA(cone1).setSourceB(cone2); + SDF coneTop = new SDFSmoothUnion().setRadius(0.02F).setSourceA(cone3).setSourceB(cone4); + noise = (SDFRadialNoiseMap) new SDFRadialNoiseMap().setSeed(seed) + .setRadius(0.5F) + .setIntensity(0.2F) + .setSource(coneTop); + island = new SDFSmoothUnion().setRadius(0.01F).setSourceA(noise).setSourceB(coneBottom); + } + + private int getSeed(int x, int z) { + int h = seed + x * 374761393 + z * 668265263; + h = (h ^ (h >> 13)) * 1274126177; + return h ^ (h >> 16); + } + + public void updatePositions(double x, double z, int maxHeight) { + int ix = MHelper.floor(x / options.distance); + int iz = MHelper.floor(z / options.distance); + + if (lastX != ix || lastZ != iz) { + lastX = ix; + lastZ = iz; + positions.clear(); + for (int pox = -1; pox < 2; pox++) { + int px = pox + ix; + long px2 = px; + for (int poz = -1; poz < 2; poz++) { + int pz = poz + iz; + long pz2 = pz; + if (px2 * px2 + pz2 * pz2 > options.centerDist) { + RANDOM.setSeed(getSeed(px, pz)); + double posX = (px + RANDOM.nextFloat()) * options.distance; + double posY = MHelper.randRange(options.minY, options.maxY, RANDOM) * maxHeight; + double posZ = (pz + RANDOM.nextFloat()) * options.distance; + if (density.eval(posX * 0.01, posZ * 0.01) > options.coverage) { + positions.add(new BlockPos(posX, posY, posZ)); + } + } + } + } + } + + if (GeneratorOptions.hasCentralIsland() && Math.abs(ix) < GeneratorOptions.getIslandDistChunk() && Math.abs(iz) < GeneratorOptions + .getIslandDistChunk()) { + int count = positions.size(); + for (int n = 0; n < count; n++) { + BlockPos pos = positions.get(n); + long d = (long) pos.getX() * (long) pos.getX() + (long) pos.getZ() * (long) pos.getZ(); + if (d < GeneratorOptions.getIslandDistBlockSqr()) { + positions.remove(n); + count--; + n--; + } + } + if (options.hasCentralIsland) { + positions.add(new BlockPos(0, 64, 0)); + } + } + } + + private SDF getIsland(BlockPos pos) { + SDF island = islands.get(pos); + if (island == null) { + if (pos.getX() == 0 && pos.getZ() == 0) { + island = new SDFScale().setScale(1.3F).setSource(this.island); + } else { + RANDOM.setSeed(getSeed(pos.getX(), pos.getZ())); + island = new SDFScale().setScale(RANDOM.nextFloat() + 0.5F).setSource(this.island); + } + islands.put(pos, island); + } + noise.setOffset(pos.getX(), pos.getZ()); + return island; + } + + private float getRelativeDistance(SDF sdf, BlockPos center, double px, double py, double pz) { + float x = (float) (px - center.getX()) / options.scale; + float y = (float) (py - center.getY()) / options.scale; + float z = (float) (pz - center.getZ()) / options.scale; + return sdf.getDistance(x, y, z); + } + + private float calculateSDF(double x, double y, double z) { + float distance = 10; + for (BlockPos pos : positions) { + SDF island = getIsland(pos); + float dist = getRelativeDistance(island, pos, x, y, z); + distance = MHelper.min(distance, dist); + } + return distance; + } + + public float getDensity(double x, double y, double z) { + return -calculateSDF(x, y, z); + } + + public float getDensity(double x, double y, double z, float height) { + noise.setIntensity(height); + noise.setRadius(0.5F / (1 + height)); + return -calculateSDF(x, y, z); + } + + public void clearCache() { + if (islands.size() > 128) { + islands.clear(); + } + } + + private static SDF makeCone(float radiusBottom, float radiusTop, float height, float minY) { + float hh = height * 0.5F; + SDF sdf = new SDFCappedCone().setHeight(hh).setRadius1(radiusBottom).setRadius2(radiusTop); + return new SDFTranslate().setTranslate(0, minY + hh, 0).setSource(sdf); + } + + /*private static NativeImage loadMap(String path) { + InputStream stream = IslandLayer.class.getResourceAsStream(path); + if (stream != null) { + try { + NativeImage map = NativeImage.read(stream); + stream.close(); + return map; + } + catch (IOException e) { + BetterEnd.LOGGER.warning(e.getMessage()); + } + } + return null; + }*/ + + /*static { + NativeImage map = loadMap("/assets/" + BetterEnd.MOD_ID + "/textures/heightmaps/mountain_1.png"); + + SDF cone1 = makeCone(0, 0.4F, 0.2F, -0.3F); + SDF cone2 = makeCone(0.4F, 0.5F, 0.1F, -0.1F); + SDF cone3 = makeCone(0.5F, 0.45F, 0.03F, 0.0F); + SDF cone4 = makeCone(0.45F, 0, 0.02F, 0.03F); + + SDF coneBottom = new SDFSmoothUnion().setRadius(0.02F).setSourceA(cone1).setSourceB(cone2); + SDF coneTop = new SDFSmoothUnion().setRadius(0.02F).setSourceA(cone3).setSourceB(cone4); + + SDF map1 = new SDFHeightmap().setMap(map).setIntensity(0.3F).setSource(coneTop); + NOISE = (SDFRadialNoiseMap) new SDFRadialNoiseMap().setSource(coneTop); + + ISLAND = new SDF[] { + new SDFSmoothUnion().setRadius(0.01F).setSourceA(coneTop).setSourceB(coneBottom), + new SDFSmoothUnion().setRadius(0.01F).setSourceA(map1).setSourceB(coneBottom) + }; + }*/ +} diff --git a/src/main/java/org/betterx/betterend/world/generator/LayerOptions.java b/src/main/java/org/betterx/betterend/world/generator/LayerOptions.java new file mode 100644 index 00000000..a8f644a4 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/generator/LayerOptions.java @@ -0,0 +1,57 @@ +package org.betterx.betterend.world.generator; + +import org.betterx.bclib.config.PathConfig; + +import net.minecraft.util.Mth; + +public class LayerOptions { + public final float distance; + public final float scale; + public final float coverage; + public final float center; + public final float heightVariation; + public final float minY; + public final float maxY; + public final long centerDist; + public final boolean hasCentralIsland; + + public LayerOptions( + String name, + PathConfig config, + float distance, + float scale, + float center, + float heightVariation, + boolean hasCentral + ) { + this.distance = clampDistance(config.getFloat(name, "distance[1-8192]", distance)); + this.scale = clampScale(config.getFloat(name, "scale[0.1-1024]", scale)); + this.center = clampCenter(config.getFloat(name, "averageHeight[0-1]", center)); + this.heightVariation = clampVariation(config.getFloat(name, "heightVariation[0-1]", heightVariation)); + this.coverage = clampCoverage(config.getFloat(name, "coverage[0-1]", 0.5F)); + this.minY = this.center - this.heightVariation; + this.maxY = this.center + this.heightVariation; + this.centerDist = Mth.floor(1000 / this.distance); + this.hasCentralIsland = config.getBoolean(name, "hasCentralIsland", hasCentral); + } + + private float clampDistance(float value) { + return Mth.clamp(value, 1, 8192); + } + + private float clampScale(float value) { + return Mth.clamp(value, 0.1F, 1024); + } + + private float clampCoverage(float value) { + return 0.9999F - Mth.clamp(value, 0, 1) * 2; + } + + private float clampCenter(float value) { + return Mth.clamp(value, 0, 1.0f); + } + + private float clampVariation(float value) { + return Mth.clamp(value, 0, 1.0f); + } +} diff --git a/src/main/java/org/betterx/betterend/world/generator/TerrainBoolCache.java b/src/main/java/org/betterx/betterend/world/generator/TerrainBoolCache.java new file mode 100644 index 00000000..d9407e12 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/generator/TerrainBoolCache.java @@ -0,0 +1,21 @@ +package org.betterx.betterend.world.generator; + +public class TerrainBoolCache { + private final byte[] data = new byte[16384]; + + public static int scaleCoordinate(int value) { + return value >> 7; + } + + private int getIndex(int x, int z) { + return x << 7 | z; + } + + public void setData(int x, int z, byte value) { + data[getIndex(x & 127, z & 127)] = value; + } + + public byte getData(int x, int z) { + return data[getIndex(x & 127, z & 127)]; + } +} diff --git a/src/main/java/org/betterx/betterend/world/generator/TerrainGenerator.java b/src/main/java/org/betterx/betterend/world/generator/TerrainGenerator.java new file mode 100644 index 00000000..30dbaaab --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/generator/TerrainGenerator.java @@ -0,0 +1,284 @@ +package org.betterx.betterend.world.generator; + +import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource; +import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.interfaces.BETargetChecker; +import org.betterx.betterend.mixin.common.NoiseBasedChunkGeneratorAccessor; +import org.betterx.betterend.mixin.common.NoiseChunkAccessor; +import org.betterx.betterend.mixin.common.NoiseInterpolatorAccessor; +import org.betterx.betterend.noise.OpenSimplexNoise; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.biome.Climate.Sampler; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.*; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.awt.*; +import java.util.List; +import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; + +public class TerrainGenerator { + private static final Map TERRAIN_BOOL_CACHE_MAP = Maps.newHashMap(); + private static final ReentrantLock LOCKER = new ReentrantLock(); + private static final Point POS = new Point(); + private static final double SCALE_XZ = 8.0; + private static final double SCALE_Y = 4.0; + private static final float[] COEF; + private static final Point[] OFFS; + + private static IslandLayer largeIslands; + private static IslandLayer mediumIslands; + private static IslandLayer smallIslands; + private static OpenSimplexNoise noise1; + private static OpenSimplexNoise noise2; + private static BiomeSource biomeSource; + private static Sampler sampler; + + public static void initNoise(long seed, BiomeSource biomeSource, Sampler sampler) { + RandomSource random = new LegacyRandomSource(seed); + largeIslands = new IslandLayer(random.nextInt(), GeneratorOptions.bigOptions); + mediumIslands = new IslandLayer(random.nextInt(), GeneratorOptions.mediumOptions); + smallIslands = new IslandLayer(random.nextInt(), GeneratorOptions.smallOptions); + noise1 = new OpenSimplexNoise(random.nextInt()); + noise2 = new OpenSimplexNoise(random.nextInt()); + TERRAIN_BOOL_CACHE_MAP.clear(); + TerrainGenerator.biomeSource = biomeSource; + TerrainGenerator.sampler = sampler; + } + + public static void fillTerrainDensity(double[] buffer, int posX, int posZ, int scaleXZ, int scaleY, int maxHeight) { + LOCKER.lock(); + final float fadeOutDist = 27.0f; + final float fadOutStart = maxHeight - (fadeOutDist + 1); + largeIslands.clearCache(); + mediumIslands.clearCache(); + smallIslands.clearCache(); + + int x = Mth.floor(posX / scaleXZ); + int z = Mth.floor(posZ / scaleXZ); + double distortion1 = noise1.eval(x * 0.1, z * 0.1) * 20 + noise2.eval( + x * 0.2, + z * 0.2 + ) * 10 + noise1.eval(x * 0.4, z * 0.4) * 5; + double distortion2 = noise2.eval(x * 0.1, z * 0.1) * 20 + noise1.eval( + x * 0.2, + z * 0.2 + ) * 10 + noise2.eval(x * 0.4, z * 0.4) * 5; + double px = (double) x * scaleXZ + distortion1; + double pz = (double) z * scaleXZ + distortion2; + + largeIslands.updatePositions(px, pz, maxHeight); + mediumIslands.updatePositions(px, pz, maxHeight); + smallIslands.updatePositions(px, pz, maxHeight); + + float height = getAverageDepth(x << 1, z << 1) * 0.5F; + + for (int y = 0; y < buffer.length; y++) { + double py = (double) y * scaleY; + float dist = largeIslands.getDensity(px, py, pz, height); + dist = dist > 1 ? dist : MHelper.max(dist, mediumIslands.getDensity(px, py, pz, height)); + dist = dist > 1 ? dist : MHelper.max(dist, smallIslands.getDensity(px, py, pz, height)); + if (dist > -0.5F) { + dist += noise1.eval(px * 0.01, py * 0.01, pz * 0.01) * 0.02 + 0.02; + dist += noise2.eval(px * 0.05, py * 0.05, pz * 0.05) * 0.01 + 0.01; + dist += noise1.eval(px * 0.1, py * 0.1, pz * 0.1) * 0.005 + 0.005; + } + + if (py >= maxHeight) dist = -1; + else if (py > fadOutStart) { + dist = (float) Mth.lerp((py - fadOutStart) / fadeOutDist, dist, -1); + } + buffer[y] = dist; + } + + LOCKER.unlock(); + } + + private static float getAverageDepth(int x, int z) { + if (biomeSource == null) { + return 0; + } + if (getBiome(biomeSource, x, z).getTerrainHeight() < 0.1F) { + return 0F; + } + float depth = 0F; + for (int i = 0; i < OFFS.length; i++) { + int px = x + OFFS[i].x; + int pz = z + OFFS[i].y; + depth += getBiome(biomeSource, px, pz).getTerrainHeight() * COEF[i]; + } + return depth; + } + + private static BCLBiome getBiome(BiomeSource biomeSource, int x, int z) { + return BiomeAPI.getBiome(biomeSource.getNoiseBiome(x, 0, z, sampler)); + } + + static { + float sum = 0; + List coef = Lists.newArrayList(); + List pos = Lists.newArrayList(); + for (int x = -3; x <= 3; x++) { + for (int z = -3; z <= 3; z++) { + float dist = MHelper.length(x, z) / 3F; + if (dist <= 1) { + sum += dist; + coef.add(dist); + pos.add(new Point(x, z)); + } + } + } + OFFS = pos.toArray(new Point[]{}); + COEF = new float[coef.size()]; + for (int i = 0; i < COEF.length; i++) { + COEF[i] = coef.get(i) / sum; + } + } + + public static Boolean isLand(int x, int z, int maxHeight) { + int sectionX = TerrainBoolCache.scaleCoordinate(x); + int sectionZ = TerrainBoolCache.scaleCoordinate(z); + final int stepY = (int) Math.ceil(maxHeight / SCALE_Y); + LOCKER.lock(); + POS.setLocation(sectionX, sectionZ); + + TerrainBoolCache section = TERRAIN_BOOL_CACHE_MAP.get(POS); + if (section == null) { + if (TERRAIN_BOOL_CACHE_MAP.size() > 64) { + TERRAIN_BOOL_CACHE_MAP.clear(); + } + section = new TerrainBoolCache(); + TERRAIN_BOOL_CACHE_MAP.put(new Point(POS.x, POS.y), section); + } + byte value = section.getData(x, z); + if (value > 0) { + LOCKER.unlock(); + return value > 1; + } + + double px = (x >> 1) + 0.5; + double pz = (z >> 1) + 0.5; + + double distortion1 = noise1.eval(px * 0.1, pz * 0.1) * 20 + noise2.eval(px * 0.2, pz * 0.2) * 10 + noise1.eval( + px * 0.4, + pz * 0.4 + ) * 5; + double distortion2 = noise2.eval(px * 0.1, pz * 0.1) * 20 + noise1.eval(px * 0.2, pz * 0.2) * 10 + noise2.eval( + px * 0.4, + pz * 0.4 + ) * 5; + px = px * SCALE_XZ + distortion1; + pz = pz * SCALE_XZ + distortion2; + + largeIslands.updatePositions(px, pz, maxHeight); + mediumIslands.updatePositions(px, pz, maxHeight); + smallIslands.updatePositions(px, pz, maxHeight); + + boolean result = false; + for (int y = 0; y < stepY; y++) { + double py = (double) y * SCALE_Y; + float dist = largeIslands.getDensity(px, py, pz); + dist = dist > 1 ? dist : MHelper.max(dist, mediumIslands.getDensity(px, py, pz)); + dist = dist > 1 ? dist : MHelper.max(dist, smallIslands.getDensity(px, py, pz)); + if (dist > -0.5F) { + dist += noise1.eval(px * 0.01, py * 0.01, pz * 0.01) * 0.02 + 0.02; + dist += noise2.eval(px * 0.05, py * 0.05, pz * 0.05) * 0.01 + 0.01; + dist += noise1.eval(px * 0.1, py * 0.1, pz * 0.1) * 0.005 + 0.005; + } + if (dist > -0.01) { + result = true; + break; + } + } + + section.setData(x, z, (byte) (result ? 2 : 1)); + LOCKER.unlock(); + + return result; + } + + public static void onServerLevelInit(ServerLevel level, LevelStem levelStem, long seed) { + if (level.dimension() == Level.END) { + final ChunkGenerator chunkGenerator = levelStem.generator(); + if (chunkGenerator instanceof NoiseBasedChunkGenerator) { + Holder sHolder = ((NoiseBasedChunkGeneratorAccessor) chunkGenerator) + .be_getSettings(); + if (chunkGenerator.getBiomeSource() instanceof BCLibEndBiomeSource bcl) { + BETargetChecker.class + .cast(sHolder.value()) + .be_setTarget(bcl.getTogetherConfig().generatorVersion == BCLEndBiomeSourceConfig.EndBiomeGeneratorType.PAULEVS); + } else { + BETargetChecker.class + .cast(sHolder.value()) + .be_setTarget(false); + } + + } + initNoise( + seed, + chunkGenerator.getBiomeSource(), + level.getChunkSource().randomState().sampler() + ); + } + } + + public static void makeObsidianPlatform(ServerLevel serverLevel, CallbackInfo info) { + if (!GeneratorOptions.generateObsidianPlatform()) { + info.cancel(); + } else if (GeneratorOptions.changeSpawn()) { + BlockPos blockPos = GeneratorOptions.getSpawn(); + int i = blockPos.getX(); + int j = blockPos.getY() - 2; + int k = blockPos.getZ(); + BlockPos.betweenClosed(i - 2, j + 1, k - 2, i + 2, j + 3, k + 2).forEach((blockPosx) -> { + serverLevel.setBlockAndUpdate(blockPosx, Blocks.AIR.defaultBlockState()); + }); + BlockPos.betweenClosed(i - 2, j, k - 2, i + 2, j, k + 2).forEach((blockPosx) -> { + serverLevel.setBlockAndUpdate(blockPosx, Blocks.OBSIDIAN.defaultBlockState()); + }); + info.cancel(); + } + } + + public static void fillSlice( + boolean primarySlice, + int x, + List interpolators, + NoiseChunkAccessor accessor, + NoiseSettings noiseSettings + ) { + final int sizeY = noiseSettings.getCellHeight(); + final int sizeXZ = noiseSettings.getCellWidth(); + final int cellSizeXZ = accessor.bnv_getCellCountXZ() + 1; + final int firstCellZ = accessor.bnv_getFirstCellZ(); + + x *= sizeXZ; + for (int cellXZ = 0; cellXZ < cellSizeXZ; ++cellXZ) { + int z = (firstCellZ + cellXZ) * sizeXZ; + for (NoiseChunk.NoiseInterpolator noiseInterpolator : interpolators) { + if (noiseInterpolator instanceof NoiseInterpolatorAccessor interpolator) { + final double[] ds = (primarySlice + ? interpolator.be_getSlice0() + : interpolator.be_getSlice1())[cellXZ]; + fillTerrainDensity(ds, x, z, sizeXZ, sizeY, noiseSettings.height()); + } + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/structures/features/EternalPortalStructure.java b/src/main/java/org/betterx/betterend/world/structures/features/EternalPortalStructure.java new file mode 100644 index 00000000..a09d8d6f --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/features/EternalPortalStructure.java @@ -0,0 +1,98 @@ +package org.betterx.betterend.world.structures.features; + +import org.betterx.bclib.api.v2.levelgen.structures.BCLStructure; +import org.betterx.bclib.api.v2.levelgen.structures.StructurePlacementType; +import org.betterx.bclib.api.v2.levelgen.structures.TemplateStructure; +import org.betterx.bclib.util.StructureHelper; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.world.structures.piece.NBTPiece; + +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.level.levelgen.structure.StructureType; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; + +import java.util.List; +import java.util.Optional; + +public class EternalPortalStructure extends TemplateStructure { + private static final ResourceLocation STRUCTURE_ID = BetterEnd.makeID("portal/eternal_portal"); + private static final StructureTemplate STRUCTURE = StructureHelper.readStructure(STRUCTURE_ID); + + public EternalPortalStructure(StructureSettings s) { + super(s, List.of( + cfg("portal/eternal_portal", 0, StructurePlacementType.FLOOR, 1.0f) + ) + ); + } + + @Override + public Optional findGenerationPoint(GenerationContext context) { + if (!BCLStructure.isValidBiome(context)) return Optional.empty(); + + final ChunkPos chunkPos = context.chunkPos(); + final ChunkGenerator chunkGenerator = context.chunkGenerator(); + final LevelHeightAccessor levelHeightAccessor = context.heightAccessor(); + + long x = (long) chunkPos.x * (long) chunkPos.x; + long z = (long) chunkPos.z * (long) chunkPos.z; + if (x + z < 1024L) { + return Optional.empty(); + } + if (chunkGenerator.getBaseHeight( + chunkPos.getBlockX(8), + chunkPos.getBlockZ(8), + Heightmap.Types.WORLD_SURFACE_WG, + levelHeightAccessor, + context.randomState() + ) < 5) { + return Optional.empty(); + } + return super.findGenerationPoint(context); + } + + @Override + public StructureType type() { + return EndStructures.ETERNAL_PORTAL.structureType; + } + + @Override + protected int erosion(RandomSource rnd) { + return rnd.nextInt(5); + } + + @Override + protected boolean cover(RandomSource rnd) { + return true; + } + + protected void generatePieces(StructurePiecesBuilder structurePiecesBuilder, GenerationContext context) { + final RandomSource random = context.random(); + final ChunkPos chunkPos = context.chunkPos(); + final ChunkGenerator chunkGenerator = context.chunkGenerator(); + final LevelHeightAccessor levelHeightAccessor = context.heightAccessor(); + int x = chunkPos.getBlockX(8); + int z = chunkPos.getBlockZ(8); + int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor, context.randomState()); + structurePiecesBuilder.addPiece(new NBTPiece( + STRUCTURE_ID, + STRUCTURE, + new BlockPos(x, y - 4, z), + random.nextInt(5), + true, + random + )); + } + + public static TemplateStructure.Config cfg(String name, int offsetY, StructurePlacementType type, float chance) { + return new TemplateStructure.Config(BetterEnd.makeID(name), offsetY, type, chance); + } +} diff --git a/src/main/java/org/betterx/betterend/world/structures/features/FeatureBaseStructure.java b/src/main/java/org/betterx/betterend/world/structures/features/FeatureBaseStructure.java new file mode 100644 index 00000000..bb0fca5f --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/features/FeatureBaseStructure.java @@ -0,0 +1,93 @@ +package org.betterx.betterend.world.structures.features; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.LegacyRandomSource; +import net.minecraft.world.level.levelgen.RandomState; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; + +import java.util.Optional; + +public abstract class FeatureBaseStructure extends Structure { + protected static final BlockState AIR = Blocks.AIR.defaultBlockState(); + + public FeatureBaseStructure(Structure.StructureSettings structureSettings) { + super(structureSettings); + } + + @Override + public Optional findGenerationPoint(GenerationContext context) { + BlockPos pos = getGenerationHeight( + context.chunkPos(), + context.chunkGenerator(), + context.heightAccessor(), + context.randomState() + ); + if (pos.getY() >= 10) { + return Optional.of(new Structure.GenerationStub(pos, (structurePiecesBuilder) -> { + generatePieces(structurePiecesBuilder, context); + })); + } + return Optional.empty(); + } + + protected Holder getNoiseBiome(ChunkGenerator cg, RandomState rState, int i, int j, int k) { + return cg.getBiomeSource().getNoiseBiome(i, j, k, rState.sampler()); + } + + protected abstract void generatePieces( + StructurePiecesBuilder structurePiecesBuilder, + Structure.GenerationContext context + ); + + private static BlockPos getGenerationHeight( + ChunkPos chunkPos, + ChunkGenerator chunkGenerator, + LevelHeightAccessor levelHeightAccessor, + RandomState rState + ) { + LegacyRandomSource random = new LegacyRandomSource(chunkPos.x + chunkPos.z * 10387313); + Rotation blockRotation = Rotation.getRandom(random); + + int offsetX = 5; + int offsetZ = 5; + if (blockRotation == Rotation.CLOCKWISE_90) { + offsetX = -5; + } else if (blockRotation == Rotation.CLOCKWISE_180) { + offsetX = -5; + offsetZ = -5; + } else if (blockRotation == Rotation.COUNTERCLOCKWISE_90) { + offsetZ = -5; + } + + int blockX = chunkPos.getBlockX(7); + int blockZ = chunkPos.getBlockZ(7); + int minZ = Integer.MAX_VALUE; + BlockPos.MutableBlockPos result = new BlockPos.MutableBlockPos(blockX, Integer.MIN_VALUE, blockZ); + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + int z = chunkGenerator.getFirstOccupiedHeight( + blockX + i * offsetX, + blockZ + j * offsetZ, + Heightmap.Types.WORLD_SURFACE_WG, + levelHeightAccessor, + rState + ); + if (z < minZ) { + result.set(blockX + i * offsetX, z, blockZ + j * offsetZ); + } + } + } + + return result; + } +} diff --git a/src/main/java/org/betterx/betterend/world/structures/features/GiantIceStarStructure.java b/src/main/java/org/betterx/betterend/world/structures/features/GiantIceStarStructure.java new file mode 100644 index 00000000..aaefcc08 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/features/GiantIceStarStructure.java @@ -0,0 +1,126 @@ +package org.betterx.betterend.world.structures.features; + +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.SDFRotation; +import org.betterx.bclib.sdf.operator.SDFTranslate; +import org.betterx.bclib.sdf.operator.SDFUnion; +import org.betterx.bclib.sdf.primitive.SDFCappedCone; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.world.structures.piece.VoxelPiece; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.structure.StructureType; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; + +import java.util.ArrayList; +import java.util.List; + +public class GiantIceStarStructure extends SDFStructureFeature { + private static final float minSize = 20; + private static final float maxSize = 35; + private static final int minCount = 25; + private static final int maxCount = 40; + + public GiantIceStarStructure(StructureSettings s) { + super(s); + } + + @Override + public StructureType type() { + return EndStructures.GIANT_ICE_STAR.structureType; + } + + protected static SDF getSDF(BlockPos pos, RandomSource random) { + float size = MHelper.randRange(minSize, maxSize, random); + int count = MHelper.randRange(minCount, maxCount, random); + List points = getFibonacciPoints(count); + SDF sdf = null; + SDF spike = new SDFCappedCone().setRadius1(3 + (size - 5) * 0.2F) + .setRadius2(0) + .setHeight(size) + .setBlock(EndBlocks.DENSE_SNOW); + spike = new SDFTranslate().setTranslate(0, size - 0.5F, 0).setSource(spike); + for (Vector3f point : points) { + SDF rotated = spike; + point = MHelper.normalize(point); + float angle = MHelper.angle(Vector3f.YP, point); + if (angle > 0.01F && angle < 3.14F) { + Vector3f axis = MHelper.normalize(MHelper.cross(Vector3f.YP, point)); + rotated = new SDFRotation().setRotation(axis, angle).setSource(spike); + } else if (angle > 1) { + rotated = new SDFRotation().setRotation(Vector3f.YP, (float) Math.PI).setSource(spike); + } + sdf = (sdf == null) ? rotated : new SDFUnion().setSourceA(sdf).setSourceB(rotated); + } + + final float ancientRadius = size * 0.7F; + final float denseRadius = size * 0.9F; + final float iceRadius = size < 7 ? size * 5 : size * 1.3F; + final float randScale = size * 0.3F; + + final BlockPos center = pos; + final BlockState ice = EndBlocks.EMERALD_ICE.defaultBlockState(); + final BlockState dense = EndBlocks.DENSE_EMERALD_ICE.defaultBlockState(); + final BlockState ancient = EndBlocks.ANCIENT_EMERALD_ICE.defaultBlockState(); + final SDF sdfCopy = sdf; + + return sdf.addPostProcess((info) -> { + BlockPos bpos = info.getPos(); + float px = bpos.getX() - center.getX(); + float py = bpos.getY() - center.getY(); + float pz = bpos.getZ() - center.getZ(); + float distance = MHelper.length(px, py, pz) + sdfCopy.getDistance( + px, + py, + pz + ) * 0.4F + random.nextFloat() * randScale; + if (distance < ancientRadius) { + return ancient; + } else if (distance < denseRadius) { + return dense; + } else if (distance < iceRadius) { + return ice; + } + return info.getState(); + }); + } + + private static List getFibonacciPoints(int count) { + float max = count - 1; + List result = new ArrayList(count); + for (int i = 0; i < count; i++) { + float y = 1F - (i / max) * 2F; + float radius = (float) Math.sqrt(1F - y * y); + float theta = MHelper.PHI * i; + float x = (float) Math.cos(theta) * radius; + float z = (float) Math.sin(theta) * radius; + result.add(new Vector3f(x, y, z)); + } + return result; + } + + public void generatePieces(StructurePiecesBuilder structurePiecesBuilder, GenerationContext context) { + final RandomSource random = context.random(); + final ChunkPos chunkPos = context.chunkPos(); + final ChunkGenerator chunkGenerator = context.chunkGenerator(); + final LevelHeightAccessor levelHeightAccessor = context.heightAccessor(); + + int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random)); + int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random)); + BlockPos start = new BlockPos(x, MHelper.randRange(32, 128, random), z); + VoxelPiece piece = new VoxelPiece((world) -> { + getSDF(start, random).fillRecursive(world, start); + }, random.nextInt()); + structurePiecesBuilder.addPiece(piece); + + //this.calculateBoundingBox(); + } +} diff --git a/src/main/java/org/betterx/betterend/world/structures/features/GiantMossyGlowshroomStructure.java b/src/main/java/org/betterx/betterend/world/structures/features/GiantMossyGlowshroomStructure.java new file mode 100644 index 00000000..9bdddb49 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/features/GiantMossyGlowshroomStructure.java @@ -0,0 +1,158 @@ +package org.betterx.betterend.world.structures.features; + +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.sdf.operator.*; +import org.betterx.bclib.sdf.primitive.SDFCappedCone; +import org.betterx.bclib.sdf.primitive.SDFPrimitive; +import org.betterx.bclib.sdf.primitive.SDFSphere; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.SplineHelper; +import org.betterx.betterend.blocks.MossyGlowshroomCapBlock; +import org.betterx.betterend.blocks.basis.FurBlock; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndStructures; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.levelgen.structure.StructureType; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; + +import java.util.List; + +public class GiantMossyGlowshroomStructure extends SDFStructureFeature { + public GiantMossyGlowshroomStructure(StructureSettings s) { + super(s); + } + + + @Override + protected void generatePieces(StructurePiecesBuilder structurePiecesBuilder, GenerationContext context) { + SDFStructureFeature.generatePieces(structurePiecesBuilder, context, GiantMossyGlowshroomStructure::getSDF); + } + + protected static SDF getSDF(BlockPos center, RandomSource random) { + SDFCappedCone cone1 = new SDFCappedCone().setHeight(2.5F).setRadius1(1.5F).setRadius2(2.5F); + SDFCappedCone cone2 = new SDFCappedCone().setHeight(3F).setRadius1(2.5F).setRadius2(13F); + SDF posedCone2 = new SDFTranslate().setTranslate(0, 5, 0).setSource(cone2); + SDF posedCone3 = new SDFTranslate().setTranslate(0, 12F, 0) + .setSource(new SDFScale().setScale(2).setSource(cone2)); + SDF upCone = new SDFSubtraction().setSourceA(posedCone2).setSourceB(posedCone3); + SDF wave = new SDFFlatWave().setRaysCount(12).setIntensity(1.3F).setSource(upCone); + SDF cones = new SDFSmoothUnion().setRadius(3).setSourceA(cone1).setSourceB(wave); + + SDF innerCone = new SDFTranslate().setTranslate(0, 1.25F, 0).setSource(upCone); + innerCone = new SDFScale3D().setScale(1.2F, 1F, 1.2F).setSource(innerCone); + cones = new SDFUnion().setSourceA(cones).setSourceB(innerCone); + + SDF glowCone = new SDFCappedCone().setHeight(3F).setRadius1(2F).setRadius2(12.5F); + SDFPrimitive priGlowCone = (SDFPrimitive) glowCone; + glowCone = new SDFTranslate().setTranslate(0, 4.25F, 0).setSource(glowCone); + glowCone = new SDFSubtraction().setSourceA(glowCone).setSourceB(posedCone3); + + cones = new SDFUnion().setSourceA(cones).setSourceB(glowCone); + + OpenSimplexNoise noise = new OpenSimplexNoise(1234); + cones = new SDFCoordModify().setFunction((pos) -> { + float dist = MHelper.length(pos.x(), pos.z()); + float y = pos.y() + (float) noise.eval( + pos.x() * 0.1 + center.getX(), + pos.z() * 0.1 + center.getZ() + ) * dist * 0.3F - dist * 0.15F; + pos.set(pos.x(), y, pos.z()); + }).setSource(cones); + + SDFTranslate HEAD_POS = (SDFTranslate) new SDFTranslate().setSource(new SDFTranslate().setTranslate(0, 2.5F, 0) + .setSource(cones)); + + SDF roots = new SDFSphere().setRadius(4F); + SDFPrimitive primRoots = (SDFPrimitive) roots; + roots = new SDFScale3D().setScale(1, 0.7F, 1).setSource(roots); + SDFFlatWave rotRoots = (SDFFlatWave) new SDFFlatWave().setRaysCount(5).setIntensity(1.5F).setSource(roots); + + SDFBinary function = new SDFSmoothUnion().setRadius(4) + .setSourceB(new SDFUnion().setSourceA(HEAD_POS).setSourceB(rotRoots)); + + cone1.setBlock(EndBlocks.MOSSY_GLOWSHROOM_CAP); + cone2.setBlock(EndBlocks.MOSSY_GLOWSHROOM_CAP); + priGlowCone.setBlock(EndBlocks.MOSSY_GLOWSHROOM_HYMENOPHORE); + primRoots.setBlock(EndBlocks.MOSSY_GLOWSHROOM.getBark()); + + float height = MHelper.randRange(10F, 25F, random); + int count = MHelper.floor(height / 4); + List spline = SplineHelper.makeSpline(0, 0, 0, 0, height, 0, count); + SplineHelper.offsetParts(spline, random, 1F, 0, 1F); + SDF sdf = SplineHelper.buildSDF(spline, 2.1F, 1.5F, (pos) -> { + return EndBlocks.MOSSY_GLOWSHROOM.getLog().defaultBlockState(); + }); + Vector3f pos = spline.get(spline.size() - 1); + float scale = MHelper.randRange(2F, 3.5F, random); + + HEAD_POS.setTranslate(pos.x(), pos.y(), pos.z()); + rotRoots.setAngle(random.nextFloat() * MHelper.PI2); + function.setSourceA(sdf); + + return new SDFRound().setRadius(1.5F) + .setSource(new SDFScale().setScale(scale).setSource(function)) + .addPostProcess((info) -> { + if (EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getState())) { + if (random.nextBoolean() && info.getStateUp() + .getBlock() == EndBlocks.MOSSY_GLOWSHROOM_CAP) { + info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.defaultBlockState() + .setValue( + MossyGlowshroomCapBlock.TRANSITION, + true + )); + return info.getState(); + } else if (!EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getStateUp()) || !EndBlocks.MOSSY_GLOWSHROOM + .isTreeLog(info.getStateDown())) { + info.setState(EndBlocks.MOSSY_GLOWSHROOM.getBark().defaultBlockState()); + return info.getState(); + } + } else if (info.getState().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_CAP) { + if (EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown().getBlock())) { + info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.defaultBlockState() + .setValue( + MossyGlowshroomCapBlock.TRANSITION, + true + )); + return info.getState(); + } + + info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.defaultBlockState()); + return info.getState(); + } else if (info.getState().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_HYMENOPHORE) { + for (Direction dir : BlocksHelper.HORIZONTAL) { + if (info.getState(dir) == AIR) { + info.setBlockPos( + info.getPos().relative(dir), + EndBlocks.MOSSY_GLOWSHROOM_FUR.defaultBlockState() + .setValue(FurBlock.FACING, dir) + ); + } + } + + if (info.getStateDown().getBlock() != EndBlocks.MOSSY_GLOWSHROOM_HYMENOPHORE) { + info.setBlockPos( + info.getPos().below(), + EndBlocks.MOSSY_GLOWSHROOM_FUR.defaultBlockState() + .setValue( + FurBlock.FACING, + Direction.DOWN + ) + ); + } + } + return info.getState(); + }); + } + + + @Override + public StructureType type() { + return EndStructures.GIANT_MOSSY_GLOWSHROOM.structureType; + } +} diff --git a/src/main/java/org/betterx/betterend/world/structures/features/MegaLakeSmallStructure.java b/src/main/java/org/betterx/betterend/world/structures/features/MegaLakeSmallStructure.java new file mode 100644 index 00000000..6f90731e --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/features/MegaLakeSmallStructure.java @@ -0,0 +1,51 @@ +package org.betterx.betterend.world.structures.features; + +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.world.structures.piece.LakePiece; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.level.levelgen.RandomState; +import net.minecraft.world.level.levelgen.structure.StructureType; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; + +public class MegaLakeSmallStructure extends FeatureBaseStructure { + public MegaLakeSmallStructure(StructureSettings s) { + super(s); + } + + @Override + public StructureType type() { + return EndStructures.MEGALAKE_SMALL.structureType; + } + + protected void generatePieces(StructurePiecesBuilder structurePiecesBuilder, GenerationContext context) { + final RandomSource random = context.random(); + final ChunkPos chunkPos = context.chunkPos(); + final ChunkGenerator chunkGenerator = context.chunkGenerator(); + final LevelHeightAccessor levelHeightAccessor = context.heightAccessor(); + final RandomState rState = context.randomState(); + + + int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random)); + int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random)); + int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor, rState); + + Holder biome = getNoiseBiome(chunkGenerator, rState, x >> 2, y >> 2, z >> 2); + if (y > 5) { + float radius = MHelper.randRange(20, 40, random); + float depth = MHelper.randRange(5, 10, random); + LakePiece piece = new LakePiece(new BlockPos(x, y, z), radius, depth, random, biome); + structurePiecesBuilder.addPiece(piece); + } + + //this.calculateBoundingBox(); + } +} diff --git a/src/main/java/org/betterx/betterend/world/structures/features/MegaLakeStructure.java b/src/main/java/org/betterx/betterend/world/structures/features/MegaLakeStructure.java new file mode 100644 index 00000000..e0886838 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/features/MegaLakeStructure.java @@ -0,0 +1,54 @@ +package org.betterx.betterend.world.structures.features; + +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.world.structures.piece.LakePiece; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.level.levelgen.RandomState; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.StructureType; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; + +public class MegaLakeStructure extends FeatureBaseStructure { + + + public MegaLakeStructure(Structure.StructureSettings structureSettings) { + super(structureSettings); + } + + @Override + public StructureType type() { + return EndStructures.MEGALAKE.structureType; + } + + protected void generatePieces(StructurePiecesBuilder structurePiecesBuilder, Structure.GenerationContext context) { + final RandomSource random = context.random(); + final ChunkPos chunkPos = context.chunkPos(); + final ChunkGenerator chunkGenerator = context.chunkGenerator(); + final RandomState rState = context.randomState(); + + final LevelHeightAccessor levelHeightAccessor = context.heightAccessor(); + + int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random)); + int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random)); + int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor, rState); + + if (y > 5) { + Holder biome = getNoiseBiome(chunkGenerator, rState, x >> 2, y >> 2, z >> 2); + + float radius = MHelper.randRange(32, 64, random); + float depth = MHelper.randRange(7, 15, random); + LakePiece piece = new LakePiece(new BlockPos(x, y, z), radius, depth, random, biome); + structurePiecesBuilder.addPiece(piece); + } + } + +} diff --git a/src/main/java/org/betterx/betterend/world/structures/features/MountainStructure.java b/src/main/java/org/betterx/betterend/world/structures/features/MountainStructure.java new file mode 100644 index 00000000..272313f4 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/features/MountainStructure.java @@ -0,0 +1,57 @@ +package org.betterx.betterend.world.structures.features; + +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.world.structures.piece.CrystalMountainPiece; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.level.levelgen.RandomState; +import net.minecraft.world.level.levelgen.structure.StructureType; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; + +public class MountainStructure extends FeatureBaseStructure { + + public MountainStructure(StructureSettings s) { + super(s); + } + + @Override + public StructureType type() { + return EndStructures.MOUNTAIN.structureType; + } + + protected void generatePieces(StructurePiecesBuilder structurePiecesBuilder, GenerationContext context) { + final RandomSource random = context.random(); + final ChunkPos chunkPos = context.chunkPos(); + final ChunkGenerator chunkGenerator = context.chunkGenerator(); + final LevelHeightAccessor levelHeightAccessor = context.heightAccessor(); + final RandomState rState = context.randomState(); + + int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random)); + int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random)); + int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor, rState); + if (y > 5) { + Holder biome = getNoiseBiome(chunkGenerator, rState, x >> 2, y >> 2, z >> 2); + float radius = MHelper.randRange(50, 100, random); + float height = radius * MHelper.randRange(0.8F, 1.2F, random); + CrystalMountainPiece piece = new CrystalMountainPiece( + new BlockPos(x, y, z), + radius, + height, + random, + biome + ); + structurePiecesBuilder.addPiece(piece); + } + + //this.calculateBoundingBox(); + } +} + diff --git a/src/main/java/org/betterx/betterend/world/structures/features/PaintedMountainStructure.java b/src/main/java/org/betterx/betterend/world/structures/features/PaintedMountainStructure.java new file mode 100644 index 00000000..5fd0e96e --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/features/PaintedMountainStructure.java @@ -0,0 +1,74 @@ +package org.betterx.betterend.world.structures.features; + +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.world.structures.piece.PaintedMountainPiece; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.level.levelgen.RandomState; +import net.minecraft.world.level.levelgen.structure.StructureType; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; + +public class PaintedMountainStructure extends FeatureBaseStructure { + public static final BlockState[] VARIANTS; + + public PaintedMountainStructure(StructureSettings s) { + super(s); + } + + @Override + public StructureType type() { + return EndStructures.PAINTED_MOUNTAIN.structureType; + } + + protected void generatePieces(StructurePiecesBuilder structurePiecesBuilder, GenerationContext context) { + final RandomSource random = context.random(); + final ChunkPos chunkPos = context.chunkPos(); + final ChunkGenerator chunkGenerator = context.chunkGenerator(); + final LevelHeightAccessor levelHeightAccessor = context.heightAccessor(); + final RandomState rState = context.randomState(); + + int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random)); + int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random)); + int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor, rState); + if (y > 50) { + Holder biome = getNoiseBiome(chunkGenerator, rState, x >> 2, y >> 2, z >> 2); + float radius = MHelper.randRange(50, 100, random); + float height = radius * MHelper.randRange(0.4F, 0.6F, random); + int count = MHelper.floor(height * MHelper.randRange(0.1F, 0.35F, random) + 1); + BlockState[] slices = new BlockState[count]; + for (int i = 0; i < count; i++) { + slices[i] = VARIANTS[random.nextInt(VARIANTS.length)]; + } + structurePiecesBuilder.addPiece(new PaintedMountainPiece( + new BlockPos(x, y, z), + radius, + height, + random, + biome, + slices + )); + } + + //this.calculateBoundingBox(); + } + + + static { + VARIANTS = new BlockState[]{ + Blocks.END_STONE.defaultBlockState(), + EndBlocks.FLAVOLITE.stone.defaultBlockState(), + EndBlocks.VIOLECITE.stone.defaultBlockState(), + }; + } +} diff --git a/src/main/java/org/betterx/betterend/world/structures/features/SDFStructureFeature.java b/src/main/java/org/betterx/betterend/world/structures/features/SDFStructureFeature.java new file mode 100644 index 00000000..cab48a0d --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/features/SDFStructureFeature.java @@ -0,0 +1,45 @@ +package org.betterx.betterend.world.structures.features; + +import org.betterx.bclib.sdf.SDF; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.world.structures.piece.VoxelPiece; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; + +import java.util.function.BiFunction; + +public abstract class SDFStructureFeature extends FeatureBaseStructure { + public SDFStructureFeature(StructureSettings s) { + super(s); + } + + public static void generatePieces( + StructurePiecesBuilder structurePiecesBuilder, + GenerationContext context, + BiFunction sdf + ) { + final RandomSource random = context.random(); + final ChunkPos chunkPos = context.chunkPos(); + final ChunkGenerator chunkGenerator = context.chunkGenerator(); + final LevelHeightAccessor levelHeightAccessor = context.heightAccessor(); + int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random)); + int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random)); + int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG, levelHeightAccessor, context.randomState()); + if (y > 5) { + BlockPos start = new BlockPos(x, y, z); + VoxelPiece piece = new VoxelPiece((world) -> { + sdf.apply(start, random).fillRecursive(world, start); + }, random.nextInt()); + + structurePiecesBuilder.addPiece(piece); + } + + //this.calculateBoundingBox(); + } +} diff --git a/src/main/java/org/betterx/betterend/world/structures/piece/BasePiece.java b/src/main/java/org/betterx/betterend/world/structures/piece/BasePiece.java new file mode 100644 index 00000000..81636c55 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/piece/BasePiece.java @@ -0,0 +1,31 @@ +package org.betterx.betterend.world.structures.piece; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.StructurePiece; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceType; + +public abstract class BasePiece extends StructurePiece { + protected BasePiece(StructurePieceType type, int i, BoundingBox boundingBox) { + super(type, i, boundingBox); + } + + protected BasePiece(StructurePieceType type, CompoundTag tag) { + super(type, tag); + fromNbt(tag); + } + + protected abstract void fromNbt(CompoundTag tag); + + protected void addAdditionalSaveData(CompoundTag tag) { + } + + @Override + protected void addAdditionalSaveData( + StructurePieceSerializationContext structurePieceSerializationContext, + CompoundTag compoundTag + ) { + addAdditionalSaveData(compoundTag); + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/world/structures/piece/CavePiece.java b/src/main/java/org/betterx/betterend/world/structures/piece/CavePiece.java new file mode 100644 index 00000000..671b1982 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/piece/CavePiece.java @@ -0,0 +1,116 @@ +package org.betterx.betterend.world.structures.piece; + +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.util.GlobalState; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext; + +public class CavePiece extends BasePiece { + private OpenSimplexNoise noise; + private BlockPos center; + private float radius; + + public CavePiece(BlockPos center, float radius, int id) { + super(EndStructures.CAVE_PIECE, id, null); + this.center = center; + this.radius = radius; + this.noise = new OpenSimplexNoise(MHelper.getSeed(534, center.getX(), center.getZ())); + makeBoundingBox(); + } + + public CavePiece(StructurePieceSerializationContext type, CompoundTag tag) { + super(EndStructures.CAVE_PIECE, tag); + makeBoundingBox(); + } + + + @Override + public void postProcess( + WorldGenLevel world, + StructureManager arg, + ChunkGenerator chunkGenerator, + RandomSource random, + BoundingBox blockBox, + ChunkPos chunkPos, + BlockPos blockPos + ) { + int x1 = MHelper.max(this.boundingBox.minX(), blockBox.minX()); + int z1 = MHelper.max(this.boundingBox.minZ(), blockBox.minZ()); + int x2 = MHelper.min(this.boundingBox.maxX(), blockBox.maxX()); + int z2 = MHelper.min(this.boundingBox.maxZ(), blockBox.maxZ()); + int y1 = this.boundingBox.minY(); + int y2 = this.boundingBox.maxY(); + + double hr = radius * 0.75; + double nr = radius * 0.25; + final MutableBlockPos pos = GlobalState.stateForThread().POS; + for (int x = x1; x <= x2; x++) { + int xsq = x - center.getX(); + xsq *= xsq; + pos.setX(x); + for (int z = z1; z <= z2; z++) { + int zsq = z - center.getZ(); + zsq *= zsq; + pos.setZ(z); + for (int y = y1; y <= y2; y++) { + int ysq = y - center.getY(); + ysq *= 1.6; + ysq *= ysq; + pos.setY(y); + double r = noise.eval(x * 0.1, y * 0.1, z * 0.1) * nr + hr; + double r2 = r - 4.5; + double dist = xsq + ysq + zsq; + if (dist < r2 * r2) { + if (world.getBlockState(pos).is(CommonBlockTags.END_STONES)) { + BlocksHelper.setWithoutUpdate(world, pos, CAVE_AIR); + } + } else if (dist < r * r) { + if (world.getBlockState(pos).getMaterial().isReplaceable()) { + BlocksHelper.setWithoutUpdate(world, pos, Blocks.END_STONE); + } + } + } + } + } + + return; + } + + @Override + protected void addAdditionalSaveData(CompoundTag tag) { + tag.put("center", NbtUtils.writeBlockPos(center)); + tag.putFloat("radius", radius); + } + + @Override + protected void fromNbt(CompoundTag tag) { + center = NbtUtils.readBlockPos(tag.getCompound("center")); + radius = tag.getFloat("radius"); + noise = new OpenSimplexNoise(MHelper.getSeed(534, center.getX(), center.getZ())); + } + + private void makeBoundingBox() { + int minX = MHelper.floor(center.getX() - radius); + int minY = MHelper.floor(center.getY() - radius); + int minZ = MHelper.floor(center.getZ() - radius); + int maxX = MHelper.floor(center.getX() + radius + 1); + int maxY = MHelper.floor(center.getY() + radius + 1); + int maxZ = MHelper.floor(center.getZ() + radius + 1); + this.boundingBox = new BoundingBox(minX, minY, minZ, maxX, maxY, maxZ); + } +} diff --git a/src/main/java/org/betterx/betterend/world/structures/piece/CrystalMountainPiece.java b/src/main/java/org/betterx/betterend/world/structures/piece/CrystalMountainPiece.java new file mode 100644 index 00000000..a9c93f43 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/piece/CrystalMountainPiece.java @@ -0,0 +1,205 @@ +package org.betterx.betterend.world.structures.piece; + +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.blocks.CrystalMossCoverBlock; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.util.GlobalState; +import org.betterx.betterend.world.surface.SplitNoiseCondition; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext; + +public class CrystalMountainPiece extends MountainPiece { + private BlockState top; + + public CrystalMountainPiece(BlockPos center, float radius, float height, RandomSource random, Holder biome) { + super(EndStructures.MOUNTAIN_PIECE, center, radius, height, random, biome); + top = EndBlocks.CRYSTAL_MOSS.defaultBlockState(); //EndBiome.findTopMaterial(biome.value()); //biome.getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); + } + + public CrystalMountainPiece(StructurePieceSerializationContext type, CompoundTag tag) { + super(EndStructures.MOUNTAIN_PIECE, tag); + top = EndBlocks.CRYSTAL_MOSS.defaultBlockState(); + } + + @Override + protected void fromNbt(CompoundTag tag) { + super.fromNbt(tag); + //top = EndBiome.findTopMaterial(BiomeAPI.getBiome(biomeID)); //BiomeAPI.getBiome(biomeID).getBiome().getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); + } + + @Override + public void postProcess( + WorldGenLevel world, + StructureManager arg, + ChunkGenerator chunkGenerator, + RandomSource random, + BoundingBox blockBox, + ChunkPos chunkPos, + BlockPos blockPos + ) { + int sx = chunkPos.getMinBlockX(); + int sz = chunkPos.getMinBlockZ(); + final MutableBlockPos pos = GlobalState.stateForThread().POS; + ChunkAccess chunk = world.getChunk(chunkPos.x, chunkPos.z); + Heightmap map = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE); + Heightmap map2 = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE_WG); + for (int x = 0; x < 16; x++) { + int px = x + sx; + int px2 = px - center.getX(); + px2 *= px2; + pos.setX(x); + for (int z = 0; z < 16; z++) { + int pz = z + sz; + int pz2 = pz - center.getZ(); + pz2 *= pz2; + float dist = px2 + pz2; + if (dist < r2) { + pos.setZ(z); + dist = 1 - (float) Math.pow(dist / r2, 0.3); + int minY = map.getFirstAvailable(x, z); + if (minY < 10) { + continue; + } + pos.setY(minY); + while (!chunk.getBlockState(pos).is(CommonBlockTags.GEN_END_STONES) + && pos.getY() > 56 + && chunk.getBlockState(pos.below()).is(Blocks.CAVE_AIR) + ) { + pos.setY(pos.getY() - 1); + } + minY = pos.getY(); + minY = Math.max(minY, map2.getFirstAvailable(x, z)); + if (minY > center.getY() - 8) { + float maxY = dist * height * getHeightClamp(world, 12, px, pz); + if (maxY > 0) { + maxY *= (float) noise1.eval(px * 0.05, pz * 0.05) * 0.3F + 0.7F; + maxY *= (float) noise1.eval(px * 0.1, pz * 0.1) * 0.1F + 0.8F; + maxY += center.getY(); + int maxYI = (int) (maxY); + int cover = maxYI - 1; + + final double noise = SplitNoiseCondition.DEFAULT.getNoise(px, pz); + boolean needCover = noise > 0; + boolean needSurroundCover = Math.abs(noise) < 0.2; + for (int y = minY - 1; y < maxYI; y++) { + pos.setY(y); + if (needCover && y == cover) { + chunk.setBlockState(pos, top, false); + } else { + chunk.setBlockState(pos, Blocks.END_STONE.defaultBlockState(), false); + } + if (needSurroundCover && chunk.getBlockState(pos.above()).is(Blocks.AIR)) { + BlockState coverState = EndBlocks.CRYSTAL_MOSS_COVER + .defaultBlockState(); + BlockPos above = pos.above(); + boolean didChange = false; + for (Direction dir : Direction.values()) { + if (chunk.getBlockState(above.relative(dir)).is(CommonBlockTags.END_STONES)) { + coverState = coverState.setValue( + CrystalMossCoverBlock.getFaceProperty(dir), + true + ); + didChange = true; + } + } + if (didChange) chunk.setBlockState(above, coverState, false); + + } + } + } + } + } + } + } + + map = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE); + + // Big crystals + int count = (map.getFirstAvailable(8, 8) - (center.getY() + 24)) / 7; + count = Mth.clamp(count, 0, 8); + for (int i = 0; i < count; i++) { + int radius = MHelper.randRange(2, 3, random); + float fill = MHelper.randRange(0F, 1F, random); + int x = MHelper.randRange(radius, 15 - radius, random); + int z = MHelper.randRange(radius, 15 - radius, random); + int y = map.getFirstAvailable(x, z); + if (y > 60) { + pos.set(x, y, z); + if (chunk.getBlockState(pos.below()).is(Blocks.END_STONE)) { + int height = MHelper.floor(radius * MHelper.randRange(1.5F, 3F, random) + (y - 80) * 0.3F); + crystal(chunk, pos, radius, height, fill, random); + } + } + } + + // Small crystals + count = (map.getFirstAvailable(8, 8) - (center.getY() + 24)) / 2; + count = Mth.clamp(count, 4, 8); + for (int i = 0; i < count; i++) { + int radius = MHelper.randRange(1, 2, random); + float fill = random.nextBoolean() ? 0 : 1; + int x = MHelper.randRange(radius, 15 - radius, random); + int z = MHelper.randRange(radius, 15 - radius, random); + int y = map.getFirstAvailable(x, z); + if (y > 20) { + pos.set(x, y, z); + if (chunk.getBlockState(pos.below()).getBlock() == Blocks.END_STONE) { + int height = MHelper.floor(radius * MHelper.randRange(1.5F, 3F, random) + (y - 80) * 0.3F); + crystal(chunk, pos, radius, height, fill, random); + } + } + } + } + + private void crystal(ChunkAccess chunk, BlockPos pos, int radius, int height, float fill, RandomSource random) { + MutableBlockPos mut = new MutableBlockPos(); + int max = MHelper.floor(fill * radius + radius + 0.5F); + height += pos.getY(); + Heightmap map = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE); + int coefX = MHelper.randRange(-1, 1, random); + int coefZ = MHelper.randRange(-1, 1, random); + for (int x = -radius; x <= radius; x++) { + mut.setX(x + pos.getX()); + if (mut.getX() >= 0 && mut.getX() < 16) { + int ax = Math.abs(x); + for (int z = -radius; z <= radius; z++) { + mut.setZ(z + pos.getZ()); + if (mut.getZ() >= 0 && mut.getZ() < 16) { + int az = Math.abs(z); + if (ax + az < max) { + int minY = map.getFirstAvailable(mut.getX(), mut.getZ()) - MHelper.randRange(3, 7, random); + if (pos.getY() - minY > 8) { + minY = pos.getY() - 8; + } + int h = coefX * x + coefZ * z + height; + for (int y = minY; y < h; y++) { + mut.setY(y); + chunk.setBlockState(mut, EndBlocks.AURORA_CRYSTAL.defaultBlockState(), false); + } + } + } + } + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/structures/piece/LakePiece.java b/src/main/java/org/betterx/betterend/world/structures/piece/LakePiece.java new file mode 100644 index 00000000..b84dc10f --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/piece/LakePiece.java @@ -0,0 +1,288 @@ +package org.betterx.betterend.world.structures.piece; + +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.util.BlocksHelper; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.world.biome.EndBiome; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.core.SectionPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext; +import net.minecraft.world.level.material.FluidState; + +import com.google.common.collect.Maps; + +import java.util.Map; + +public class LakePiece extends BasePiece { + private static final BlockState ENDSTONE = Blocks.END_STONE.defaultBlockState(); + private static final BlockState WATER = Blocks.WATER.defaultBlockState(); + private final Map heightmap = Maps.newHashMap(); + private OpenSimplexNoise noise; + private BlockPos center; + private float radius; + private float aspect; + private float depth; + private int seed; + + private ResourceLocation biomeID; + + public LakePiece(BlockPos center, float radius, float depth, RandomSource random, Holder biome) { + super(EndStructures.LAKE_PIECE, random.nextInt(), null); + this.center = center; + this.radius = radius; + this.depth = depth; + this.seed = random.nextInt(); + this.noise = new OpenSimplexNoise(this.seed); + this.aspect = radius / depth; + this.biomeID = BiomeAPI.getBiomeID(biome.value()); + makeBoundingBox(); + } + + public LakePiece(StructurePieceSerializationContext type, CompoundTag tag) { + super(EndStructures.LAKE_PIECE, tag); + makeBoundingBox(); + } + + @Override + protected void addAdditionalSaveData(CompoundTag tag) { + tag.put("center", NbtUtils.writeBlockPos(center)); + tag.putFloat("radius", radius); + tag.putFloat("depth", depth); + tag.putInt("seed", seed); + tag.putString("biome", biomeID.toString()); + } + + @Override + protected void fromNbt(CompoundTag tag) { + center = NbtUtils.readBlockPos(tag.getCompound("center")); + radius = tag.getFloat("radius"); + depth = tag.getFloat("depth"); + seed = tag.getInt("seed"); + noise = new OpenSimplexNoise(seed); + aspect = radius / depth; + biomeID = new ResourceLocation(tag.getString("biome")); + } + + @Override + public void postProcess( + WorldGenLevel world, + StructureManager arg, + ChunkGenerator chunkGenerator, + RandomSource random, + BoundingBox blockBox, + ChunkPos chunkPos, + BlockPos blockPos + ) { + int minY = this.boundingBox.minY(); + int maxY = this.boundingBox.maxY(); + int sx = SectionPos.sectionToBlockCoord(chunkPos.x); + int sz = SectionPos.sectionToBlockCoord(chunkPos.z); + MutableBlockPos mut = new MutableBlockPos(); + ChunkAccess chunk = world.getChunk(chunkPos.x, chunkPos.z); + for (int x = 0; x < 16; x++) { + mut.setX(x); + int wx = x | sx; + double nx = wx * 0.1; + int x2 = wx - center.getX(); + for (int z = 0; z < 16; z++) { + mut.setZ(z); + int wz = z | sz; + double nz = wz * 0.1; + int z2 = wz - center.getZ(); + float clamp = getHeightClamp(world, 8, wx, wz); + if (clamp < 0.01) continue; + + double n = noise.eval(nx, nz) * 1.5 + 1.5; + double x3 = MHelper.sqr(x2 + noise.eval(nx, nz, 100) * 10); + double z3 = MHelper.sqr(z2 + noise.eval(nx, nz, -100) * 10); + + for (int y = maxY; y >= minY; y--) { + mut.setY((int) (y + n)); + double y2 = MHelper.sqr((y - center.getY()) * aspect); + double r2 = radius * clamp; + double r3 = r2 + 8; + r2 *= r2; + r3 = r3 * r3 + 100; + double dist = x3 + y2 + z3; + if (dist < r2) { + BlockState state = chunk.getBlockState(mut); + if (state.is(CommonBlockTags.GEN_END_STONES) || state.isAir()) { + state = mut.getY() < center.getY() ? WATER : CAVE_AIR; + chunk.setBlockState(mut, state, false); + } + } else if (dist <= r3 && mut.getY() < center.getY()) { + BlockState state = chunk.getBlockState(mut); + BlockPos worldPos = mut.offset(sx, 0, sz); + if (!state.isCollisionShapeFullBlock(world, worldPos) && !state.isRedstoneConductor( + world, + worldPos + )) { + state = chunk.getBlockState(mut.above()); + if (state.isAir()) { + state = random.nextBoolean() ? ENDSTONE : EndBiome.findTopMaterial(world, worldPos); + } else { + state = state.getFluidState().isEmpty() + ? ENDSTONE + : EndBlocks.ENDSTONE_DUST.defaultBlockState(); + } + chunk.setBlockState(mut, state, false); + } + } + } + } + } + fixWater(world, chunk, mut, random, sx, sz); + } + + private void fixWater( + WorldGenLevel world, + ChunkAccess chunk, + MutableBlockPos mut, + RandomSource random, + int sx, + int sz + ) { + int minY = this.boundingBox.minY(); + int maxY = this.boundingBox.maxY(); + for (int x = 0; x < 16; x++) { + mut.setX(x); + for (int z = 0; z < 16; z++) { + mut.setZ(z); + for (int y = minY; y <= maxY; y++) { + mut.setY(y); + FluidState state = chunk.getFluidState(mut); + if (!state.isEmpty()) { + mut.setY(y - 1); + if (chunk.getBlockState(mut).isAir()) { + mut.setY(y + 1); + + BlockState bState = chunk.getBlockState(mut); + if (bState.isAir()) { + bState = random.nextBoolean() + ? ENDSTONE + : EndBiome.findTopMaterial(world, mut.offset(sx, 0, sz)); + } else { + bState = bState.getFluidState().isEmpty() + ? ENDSTONE + : EndBlocks.ENDSTONE_DUST.defaultBlockState(); + } + + mut.setY(y); + + makeEndstonePillar(chunk, mut, bState); + } else if (x > 1 && x < 15 && z > 1 && z < 15) { + mut.setY(y); + for (Direction dir : BlocksHelper.HORIZONTAL) { + BlockPos wPos = mut.offset(dir.getStepX(), 0, dir.getStepZ()); + if (chunk.getBlockState(wPos).isAir()) { + mut.setY(y + 1); + BlockState bState = chunk.getBlockState(mut); + if (bState.isAir()) { + bState = random.nextBoolean() + ? ENDSTONE + : EndBiome.findTopMaterial(world, mut.offset(sx, 0, sz)); + } else { + bState = bState.getFluidState().isEmpty() + ? ENDSTONE + : EndBlocks.ENDSTONE_DUST.defaultBlockState(); + } + mut.setY(y); + makeEndstonePillar(chunk, mut, bState); + break; + } + } + } else if (chunk.getBlockState(mut.move(Direction.UP)).isAir()) { + chunk.markPosForPostprocessing(mut.move(Direction.DOWN).immutable()); + } + } else if (chunk.getBlockState(mut).isRandomlyTicking()) { + chunk.markPosForPostprocessing(mut.immutable()); + } + } + } + } + } + + private void makeEndstonePillar(ChunkAccess chunk, MutableBlockPos mut, BlockState terrain) { + chunk.setBlockState(mut, terrain, false); + mut.setY(mut.getY() - 1); + while (!chunk.getFluidState(mut).isEmpty()) { + chunk.setBlockState(mut, ENDSTONE, false); + mut.setY(mut.getY() - 1); + } + } + + private int getHeight(WorldGenLevel world, BlockPos pos) { + int p = ((pos.getX() & 2047) << 11) | (pos.getZ() & 2047); + int h = heightmap.getOrDefault(p, Byte.MIN_VALUE); + if (h > Byte.MIN_VALUE) { + return h; + } + + if (!BiomeAPI.getBiomeID(world.getBiome(pos)).equals(biomeID)) { + heightmap.put(p, (byte) 0); + return 0; + } + + h = world.getHeight(Types.WORLD_SURFACE_WG, pos.getX(), pos.getZ()); + h = Mth.abs(h - center.getY()); + h = h < 8 ? 1 : 0; + + heightmap.put(p, (byte) h); + return h; + } + + private float getHeightClamp(WorldGenLevel world, int radius, int posX, int posZ) { + MutableBlockPos mut = new MutableBlockPos(); + int r2 = radius * radius; + float height = 0; + float max = 0; + for (int x = -radius; x <= radius; x++) { + mut.setX(posX + x); + int x2 = x * x; + for (int z = -radius; z <= radius; z++) { + mut.setZ(posZ + z); + int z2 = z * z; + if (x2 + z2 < r2) { + float mult = 1 - (float) Math.sqrt(x2 + z2) / radius; + max += mult; + height += getHeight(world, mut) * mult; + } + } + } + height /= max; + return Mth.clamp(height, 0, 1); + } + + private void makeBoundingBox() { + int minX = MHelper.floor(center.getX() - radius - 8); + int minY = MHelper.floor(center.getY() - depth - 8); + int minZ = MHelper.floor(center.getZ() - radius - 8); + int maxX = MHelper.floor(center.getX() + radius + 8); + int maxY = MHelper.floor(center.getY() + depth); + int maxZ = MHelper.floor(center.getZ() + radius + 8); + this.boundingBox = new BoundingBox(minX, minY, minZ, maxX, maxY, maxZ); + } +} \ No newline at end of file diff --git a/src/main/java/org/betterx/betterend/world/structures/piece/MountainPiece.java b/src/main/java/org/betterx/betterend/world/structures/piece/MountainPiece.java new file mode 100644 index 00000000..30e53e5b --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/piece/MountainPiece.java @@ -0,0 +1,150 @@ +package org.betterx.betterend.world.structures.piece; + +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.noise.OpenSimplexNoise; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Holder; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceType; + +import com.google.common.collect.Maps; + +import java.util.Map; + +public abstract class MountainPiece extends BasePiece { + protected Map heightmap = Maps.newHashMap(); + protected OpenSimplexNoise noise1; + protected OpenSimplexNoise noise2; + protected BlockPos center; + protected float radius; + protected float height; + protected float r2; + protected ResourceLocation biomeID; + protected int seed1; + protected int seed2; + + public MountainPiece( + StructurePieceType type, + BlockPos center, + float radius, + float height, + RandomSource random, + Holder biome + ) { + super(type, random.nextInt(), null); + this.center = center; + this.radius = radius; + this.height = height; + this.r2 = radius * radius; + this.seed1 = random.nextInt(); + this.seed2 = random.nextInt(); + this.noise1 = new OpenSimplexNoise(this.seed1); + this.noise2 = new OpenSimplexNoise(this.seed2); + this.biomeID = BiomeAPI.getBiomeID(biome); + makeBoundingBox(); + } + + public MountainPiece(StructurePieceType type, CompoundTag tag) { + super(type, tag); + makeBoundingBox(); + } + + @Override + protected void addAdditionalSaveData(CompoundTag tag) { + tag.put("center", NbtUtils.writeBlockPos(center)); + tag.putFloat("radius", radius); + tag.putFloat("height", height); + tag.putString("biome", biomeID.toString()); + tag.putInt("seed1", seed1); + tag.putInt("seed2", seed2); + } + + @Override + protected void fromNbt(CompoundTag tag) { + center = NbtUtils.readBlockPos(tag.getCompound("center")); + radius = tag.getFloat("radius"); + height = tag.getFloat("height"); + biomeID = new ResourceLocation(tag.getString("biome")); + r2 = radius * radius; + seed1 = tag.getInt("seed1"); + seed2 = tag.getInt("seed2"); + noise1 = new OpenSimplexNoise(seed1); + noise2 = new OpenSimplexNoise(seed2); + } + + private int getHeight(WorldGenLevel world, BlockPos pos) { + int p = ((pos.getX() & 2047) << 11) | (pos.getZ() & 2047); + int h = heightmap.getOrDefault(p, Integer.MIN_VALUE); + if (h > Integer.MIN_VALUE) { + return h; + } + + if (!BiomeAPI.getBiomeID(world.getBiome(pos)).equals(biomeID)) { + heightmap.put(p, -10); + return -10; + } + h = world.getHeight(Types.WORLD_SURFACE_WG, pos.getX(), pos.getZ()); + h = Mth.abs(h - center.getY()); + if (h > 4) { + h = 4 - h; + heightmap.put(p, h); + return h; + } + + h = MHelper.floor(noise2.eval(pos.getX() * 0.01, pos.getZ() * 0.01) * noise2.eval( + pos.getX() * 0.002, + pos.getZ() * 0.002 + ) * 8 + 8); + + if (h < 0) { + heightmap.put(p, 0); + return 0; + } + + heightmap.put(p, h); + + return h; + } + + protected float getHeightClamp(WorldGenLevel world, int radius, int posX, int posZ) { + MutableBlockPos mut = new MutableBlockPos(); + float height = 0; + float max = 0; + for (int x = -radius; x <= radius; x++) { + mut.setX(posX + x); + int x2 = x * x; + for (int z = -radius; z <= radius; z++) { + mut.setZ(posZ + z); + int z2 = z * z; + float mult = 1 - (float) Math.sqrt(x2 + z2) / radius; + if (mult > 0) { + max += mult; + height += getHeight(world, mut) * mult; + } + } + } + height /= max; + return Mth.clamp(height / radius, 0, 1); + } + + private void makeBoundingBox() { + int minX = MHelper.floor(center.getX() - radius); + int minY = MHelper.floor(center.getY() - radius); + int minZ = MHelper.floor(center.getZ() - radius); + int maxX = MHelper.floor(center.getX() + radius + 1); + int maxY = MHelper.floor(center.getY() + radius + 1); + int maxZ = MHelper.floor(center.getZ() + radius + 1); + this.boundingBox = new BoundingBox(minX, minY, minZ, maxX, maxY, maxZ); + } +} diff --git a/src/main/java/org/betterx/betterend/world/structures/piece/NBTPiece.java b/src/main/java/org/betterx/betterend/world/structures/piece/NBTPiece.java new file mode 100644 index 00000000..18818d7b --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/piece/NBTPiece.java @@ -0,0 +1,116 @@ +package org.betterx.betterend.world.structures.piece; + +import org.betterx.bclib.util.MHelper; +import org.betterx.bclib.util.StructureErode; +import org.betterx.bclib.util.StructureHelper; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.world.biome.EndBiome; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; + +public class NBTPiece extends BasePiece { + private ResourceLocation structureID; + private Rotation rotation; + private Mirror mirror; + private StructureTemplate structure; + private BlockPos pos; + private int erosion; + private boolean cover; + + public NBTPiece( + ResourceLocation structureID, + StructureTemplate structure, + BlockPos pos, + int erosion, + boolean cover, + RandomSource random + ) { + super(EndStructures.NBT_PIECE, random.nextInt(), null); + this.structureID = structureID; + this.structure = structure; + this.rotation = Rotation.getRandom(random); + this.mirror = Mirror.values()[random.nextInt(3)]; + this.pos = StructureHelper.offsetPos(pos, structure, rotation, mirror); + this.erosion = erosion; + this.cover = cover; + makeBoundingBox(); + } + + public NBTPiece(StructurePieceSerializationContext type, CompoundTag tag) { + super(EndStructures.NBT_PIECE, tag); + makeBoundingBox(); + } + + @Override + protected void addAdditionalSaveData(CompoundTag tag) { + super.addAdditionalSaveData(tag); + tag.putString("structureID", structureID.toString()); + tag.putInt("rotation", rotation.ordinal()); + tag.putInt("mirror", mirror.ordinal()); + tag.putInt("erosion", erosion); + tag.put("pos", NbtUtils.writeBlockPos(pos)); + tag.putBoolean("cover", cover); + } + + @Override + protected void fromNbt(CompoundTag tag) { + structureID = new ResourceLocation(tag.getString("structureID")); + rotation = Rotation.values()[tag.getInt("rotation")]; + mirror = Mirror.values()[tag.getInt("mirror")]; + erosion = tag.getInt("erosion"); + pos = NbtUtils.readBlockPos(tag.getCompound("pos")); + cover = tag.getBoolean("cover"); + structure = StructureHelper.readStructure(structureID); + } + + @Override + public void postProcess( + WorldGenLevel world, + StructureManager arg, + ChunkGenerator chunkGenerator, + RandomSource random, + BoundingBox blockBox, + ChunkPos chunkPos, + BlockPos blockPos + ) { + BoundingBox bounds = BoundingBox.fromCorners(new Vec3i( + blockBox.minX(), + this.boundingBox.minY(), + blockBox.minZ() + ), new Vec3i(blockBox.maxX(), this.boundingBox.maxX(), blockBox.maxZ())); + StructurePlaceSettings placementData = new StructurePlaceSettings().setRotation(rotation) + .setMirror(mirror) + .setBoundingBox(bounds); + structure.placeInWorld(world, pos, pos, placementData, random, 2); + if (erosion > 0) { + int x1 = MHelper.min(bounds.maxX(), boundingBox.maxX()); + int x0 = MHelper.max(bounds.minX(), boundingBox.minX()); + int z1 = MHelper.min(bounds.maxZ(), boundingBox.maxZ()); + int z0 = MHelper.max(bounds.minZ(), boundingBox.minZ()); + bounds = BoundingBox.fromCorners(new Vec3i(x0, bounds.minY(), z0), new Vec3i(x1, bounds.maxY(), z1)); + StructureErode.erode(world, bounds, erosion, random); + } + if (cover) { + StructureErode.cover(world, bounds, random, EndBiome.Config.DEFAULT_MATERIAL.getTopMaterial()); + } + } + + private void makeBoundingBox() { + this.boundingBox = StructureHelper.getStructureBounds(pos, structure, rotation, mirror); + } +} diff --git a/src/main/java/org/betterx/betterend/world/structures/piece/PaintedMountainPiece.java b/src/main/java/org/betterx/betterend/world/structures/piece/PaintedMountainPiece.java new file mode 100644 index 00000000..943d2db8 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/piece/PaintedMountainPiece.java @@ -0,0 +1,122 @@ +package org.betterx.betterend.world.structures.piece; + +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.registry.EndStructures; +import org.betterx.betterend.util.GlobalState; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Holder; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.Heightmap.Types; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext; + +public class PaintedMountainPiece extends MountainPiece { + private BlockState[] slices; + + public PaintedMountainPiece( + BlockPos center, + float radius, + float height, + RandomSource random, + Holder biome, + BlockState[] slices + ) { + super(EndStructures.PAINTED_MOUNTAIN_PIECE, center, radius, height, random, biome); + this.slices = slices; + } + + public PaintedMountainPiece(StructurePieceSerializationContext type, CompoundTag tag) { + super(EndStructures.PAINTED_MOUNTAIN_PIECE, tag); + } + + @Override + protected void addAdditionalSaveData(CompoundTag tag) { + super.addAdditionalSaveData(tag); + ListTag slice = new ListTag(); + for (BlockState state : slices) { + slice.add(NbtUtils.writeBlockState(state)); + } + tag.put("slises", slice); + } + + @Override + protected void fromNbt(CompoundTag tag) { + super.fromNbt(tag); + ListTag slise = tag.getList("slises", 10); + slices = new BlockState[slise.size()]; + for (int i = 0; i < slices.length; i++) { + slices[i] = NbtUtils.readBlockState(slise.getCompound(i)); + } + } + + @Override + public void postProcess( + WorldGenLevel world, + StructureManager arg, + ChunkGenerator chunkGenerator, + RandomSource random, + BoundingBox blockBox, + ChunkPos chunkPos, + BlockPos blockPos + ) { + int sx = chunkPos.getMinBlockX(); + int sz = chunkPos.getMinBlockZ(); + final MutableBlockPos pos = GlobalState.stateForThread().POS; + ChunkAccess chunk = world.getChunk(chunkPos.x, chunkPos.z); + Heightmap map = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE); + Heightmap map2 = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE_WG); + for (int x = 0; x < 16; x++) { + int px = x + sx; + int px2 = px - center.getX(); + px2 *= px2; + pos.setX(x); + for (int z = 0; z < 16; z++) { + int pz = z + sz; + int pz2 = pz - center.getZ(); + pz2 *= pz2; + float dist = px2 + pz2; + if (dist < r2) { + pos.setZ(z); + dist = 1 - dist / r2; + int minY = map.getFirstAvailable(x, z); + pos.setY(minY - 1); + while (chunk.getBlockState(pos).isAir() && pos.getY() > 50) { + pos.setY(minY--); + } + minY = pos.getY(); + minY = Math.max(minY, map2.getFirstAvailable(x, z)); + if (minY > center.getY() - 8) { + float maxY = dist * height * getHeightClamp(world, 10, px, pz); + if (maxY > 0) { + maxY *= (float) noise1.eval(px * 0.05, pz * 0.05) * 0.3F + 0.7F; + maxY *= (float) noise1.eval(px * 0.1, pz * 0.1) * 0.1F + 0.9F; + maxY += center.getY(); + float offset = (float) (noise1.eval(px * 0.07, pz * 0.07) * 5 + noise1.eval( + px * 0.2, + pz * 0.2 + ) * 2 + 7); + for (int y = minY - 1; y < maxY; y++) { + pos.setY(y); + int index = MHelper.floor((y + offset) * 0.65F) % slices.length; + chunk.setBlockState(pos, slices[index], false); + } + } + } + } + } + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/structures/piece/VoxelPiece.java b/src/main/java/org/betterx/betterend/world/structures/piece/VoxelPiece.java new file mode 100644 index 00000000..8f987474 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/structures/piece/VoxelPiece.java @@ -0,0 +1,55 @@ +package org.betterx.betterend.world.structures.piece; + +import org.betterx.bclib.api.v2.levelgen.structures.StructureWorld; +import org.betterx.betterend.registry.EndStructures; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext; + +import java.util.function.Consumer; + +public class VoxelPiece extends BasePiece { + private StructureWorld world; + + public VoxelPiece(Consumer function, int id) { + super(EndStructures.VOXEL_PIECE, id, null); + world = new StructureWorld(); + function.accept(world); + this.boundingBox = world.getBounds(); + } + + public VoxelPiece(StructurePieceSerializationContext type, CompoundTag tag) { + super(EndStructures.VOXEL_PIECE, tag); + this.boundingBox = world.getBounds(); + } + + @Override + protected void addAdditionalSaveData(CompoundTag tag) { + tag.put("world", world.toBNT()); + } + + @Override + protected void fromNbt(CompoundTag tag) { + world = new StructureWorld(tag.getCompound("world")); + } + + @Override + public void postProcess( + WorldGenLevel world, + StructureManager arg, + ChunkGenerator chunkGenerator, + RandomSource random, + BoundingBox blockBox, + ChunkPos chunkPos, + BlockPos blockPos + ) { + this.world.placeChunk(world, chunkPos); + } +} diff --git a/src/main/java/org/betterx/betterend/world/surface/SplitNoiseCondition.java b/src/main/java/org/betterx/betterend/world/surface/SplitNoiseCondition.java new file mode 100644 index 00000000..c70f935f --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/surface/SplitNoiseCondition.java @@ -0,0 +1,49 @@ +package org.betterx.betterend.world.surface; + +import org.betterx.bclib.interfaces.NumericProvider; +import org.betterx.bclib.mixin.common.SurfaceRulesContextAccessor; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.noise.OpenSimplexNoise; + +import com.mojang.serialization.Codec; +import net.minecraft.core.Registry; + +/** + * Noise source that returns a value in [0, 1] + */ +public class SplitNoiseCondition implements NumericProvider { + public static final SplitNoiseCondition DEFAULT = new SplitNoiseCondition(); + public static final Codec CODEC = Codec.BYTE.fieldOf("split_noise") + .xmap((obj) -> DEFAULT, obj -> (byte) 0) + .codec(); + + private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(4141); + + @Override + public int getNumber(SurfaceRulesContextAccessor context) { + final int x = context.getBlockX(); + final int z = context.getBlockZ(); + float noise = (float) NOISE.eval(x * 0.1, z * 0.1) + MHelper.randRange(-0.4F, 0.4F, MHelper.RANDOM_SOURCE); + return noise > 0 ? 1 : 0; + } + + public double getNoise(int x, int z) { + float noise = (float) NOISE.eval(x * 0.1, z * 0.1) + MHelper.randRange( + -0.2F, + 0.2F, + MHelper.RANDOM_SOURCE + ); + return noise; + } + + + @Override + public Codec pcodec() { + return CODEC; + } + + static { + Registry.register(NumericProvider.NUMERIC_PROVIDER, BetterEnd.makeID("split_noise"), SplitNoiseCondition.CODEC); + } +} diff --git a/src/main/java/org/betterx/betterend/world/surface/SulphuricSurfaceNoiseCondition.java b/src/main/java/org/betterx/betterend/world/surface/SulphuricSurfaceNoiseCondition.java new file mode 100644 index 00000000..9e2df76e --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/surface/SulphuricSurfaceNoiseCondition.java @@ -0,0 +1,59 @@ +package org.betterx.betterend.world.surface; + +import org.betterx.bclib.interfaces.NumericProvider; +import org.betterx.bclib.mixin.common.SurfaceRulesContextAccessor; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.noise.OpenSimplexNoise; + +import com.mojang.serialization.Codec; +import net.minecraft.core.Registry; + +/** + * Noise source that returns a value in [0, 3] + */ +public class SulphuricSurfaceNoiseCondition implements NumericProvider { + public static final SulphuricSurfaceNoiseCondition DEFAULT = new SulphuricSurfaceNoiseCondition(); + public static final Codec CODEC = Codec.BYTE.fieldOf("sulphuric_surf") + .xmap((obj) -> DEFAULT, obj -> (byte) 0) + .codec(); + + private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(5123); + + @Override + public int getNumber(SurfaceRulesContextAccessor context) { + final int x = context.getBlockX(); + final int z = context.getBlockZ(); + final double value = NOISE.eval(x * 0.03, z * 0.03) + NOISE.eval( + x * 0.1, + z * 0.1 + ) * 0.3 + MHelper.randRange( + -0.1, + 0.1, + MHelper.RANDOM_SOURCE + ); + if (value < -0.6) return 0; + if (value < -0.3) return 1; + if (value < 0.5) return 2; + return 3; + } + + @Override + public Codec pcodec() { + return CODEC; + } + + static { + Registry.register( + NumericProvider.NUMERIC_PROVIDER, + BetterEnd.makeID("sulphuric_surf"), + SulphuricSurfaceNoiseCondition.CODEC + ); + + Registry.register( + NumericProvider.NUMERIC_PROVIDER, + BetterEnd.makeID("vertical_band"), + VerticalBandNoiseCondition.CODEC + ); + } +} diff --git a/src/main/java/org/betterx/betterend/world/surface/UmbraSurfaceNoiseCondition.java b/src/main/java/org/betterx/betterend/world/surface/UmbraSurfaceNoiseCondition.java new file mode 100644 index 00000000..bfcadd86 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/surface/UmbraSurfaceNoiseCondition.java @@ -0,0 +1,58 @@ +package org.betterx.betterend.world.surface; + +import org.betterx.bclib.interfaces.NumericProvider; +import org.betterx.bclib.mixin.common.SurfaceRulesContextAccessor; +import org.betterx.bclib.util.MHelper; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.noise.OpenSimplexNoise; + +import com.mojang.serialization.Codec; +import net.minecraft.core.Registry; + +/** + * Noise source that returns a value in [0, 4] + */ +public class UmbraSurfaceNoiseCondition implements NumericProvider { + public static final UmbraSurfaceNoiseCondition DEFAULT = new UmbraSurfaceNoiseCondition(); + public static final Codec CODEC = Codec.BYTE.fieldOf("umbra_srf") + .xmap((obj) -> DEFAULT, obj -> (byte) 0) + .codec(); + + private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(1512); + + @Override + public int getNumber(SurfaceRulesContextAccessor context) { + final int x = context.getBlockX(); + final int z = context.getBlockZ(); + return getDepth(x, z); + } + + public static int getDepth(int x, int z) { + final double value = NOISE.eval(x * 0.03, z * 0.03) + NOISE.eval( + x * 0.1, + z * 0.1 + ) * 0.3 + MHelper.randRange( + -0.1, + 0.1, + MHelper.RANDOM_SOURCE + ); + if (value > 0.4) return 0; + if (value > 0.15) return 1; + if (value > -0.15) return 2; + if (value > -0.4) return 3; + return 4; + } + + @Override + public Codec pcodec() { + return CODEC; + } + + static { + Registry.register( + NumericProvider.NUMERIC_PROVIDER, + BetterEnd.makeID("umbra_srf"), + UmbraSurfaceNoiseCondition.CODEC + ); + } +} diff --git a/src/main/java/org/betterx/betterend/world/surface/VerticalBandNoiseCondition.java b/src/main/java/org/betterx/betterend/world/surface/VerticalBandNoiseCondition.java new file mode 100644 index 00000000..7257d641 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/surface/VerticalBandNoiseCondition.java @@ -0,0 +1,68 @@ +package org.betterx.betterend.world.surface; + +import org.betterx.bclib.interfaces.NumericProvider; +import org.betterx.bclib.mixin.common.SurfaceRulesContextAccessor; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.levelgen.Noises; +import net.minecraft.world.level.levelgen.synth.NormalNoise; + +public class VerticalBandNoiseCondition implements NumericProvider { + public static final VerticalBandNoiseCondition DEFAULT = new VerticalBandNoiseCondition( + Noises.CLAY_BANDS_OFFSET, + 4.0, + 4.0, + 6.0, + 1.3 + ); + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + ResourceKey.codec(Registry.NOISE_REGISTRY).fieldOf("noise").forGetter(o -> o.noise), + Codec.DOUBLE.fieldOf("offset_scale").orElse(4.0).forGetter(o -> o.offsetScale), + Codec.DOUBLE.fieldOf("band_scale").orElse(4.0).forGetter(o -> o.bandScale), + Codec.DOUBLE.fieldOf("xz_scale").orElse(6.0).forGetter(o -> o.xzScale), + Codec.DOUBLE.fieldOf("y_scale").orElse(1.3).forGetter(o -> o.yScale) + ) + .apply(instance, VerticalBandNoiseCondition::new)); + + private final ResourceKey noise; + private final double offsetScale; + private final double bandScale; + private final double xzScale; + private final double yScale; + + public VerticalBandNoiseCondition( + ResourceKey noise, + double offsetScale, + double bandScale, + double xzScale, + double yScale + ) { + this.noise = noise; + this.offsetScale = offsetScale; + this.bandScale = bandScale; + this.xzScale = xzScale; + this.yScale = yScale; + } + + @Override + public int getNumber(SurfaceRulesContextAccessor context) { + final NormalNoise normalNoise = context.getRandomState().getOrCreateNoise(this.noise); + double offset = normalNoise.getValue( + (double) context.getBlockX() * xzScale, + context.getBlockY() * yScale * 10, + (double) context.getBlockZ() * xzScale + ) * offsetScale; + + + return (int) (context.getBlockY() / bandScale + offset); + } + + @Override + public Codec pcodec() { + return CODEC; + } +} diff --git a/src/main/java/ru/betterend/BetterEnd.java b/src/main/java/ru/betterend/BetterEnd.java deleted file mode 100644 index df163a84..00000000 --- a/src/main/java/ru/betterend/BetterEnd.java +++ /dev/null @@ -1,77 +0,0 @@ -package ru.betterend; - -import net.fabricmc.api.ModInitializer; -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.resources.ResourceLocation; -import ru.bclib.api.WorldDataAPI; -import ru.bclib.util.Logger; -import ru.betterend.api.BetterEndPlugin; -import ru.betterend.config.Configs; -import ru.betterend.effects.EndEnchantments; -import ru.betterend.effects.EndPotions; -import ru.betterend.integration.Integrations; -import ru.betterend.recipe.AlloyingRecipes; -import ru.betterend.recipe.AnvilRecipes; -import ru.betterend.recipe.CraftingRecipes; -import ru.betterend.recipe.FurnaceRecipes; -import ru.betterend.recipe.InfusionRecipes; -import ru.betterend.recipe.SmithingRecipes; -import ru.betterend.registry.EndBiomes; -import ru.betterend.registry.EndBlockEntities; -import ru.betterend.registry.EndEntities; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndPortals; -import ru.betterend.registry.EndSounds; -import ru.betterend.registry.EndStructures; -import ru.betterend.registry.EndTags; -import ru.betterend.util.BonemealPlants; -import ru.betterend.util.LootTableUtil; -import ru.betterend.world.generator.BetterEndBiomeSource; -import ru.betterend.world.generator.GeneratorOptions; -import ru.betterend.world.surface.SurfaceBuilders; - -public class BetterEnd implements ModInitializer { - public static final String MOD_ID = "betterend"; - public static final Logger LOGGER = new Logger(MOD_ID); - - @Override - public void onInitialize() { - WorldDataAPI.registerModCache(MOD_ID); - EndPortals.loadPortals(); - EndSounds.register(); - EndBlockEntities.register(); - EndFeatures.register(); - EndEntities.register(); - SurfaceBuilders.register(); - EndBiomes.register(); - BetterEndBiomeSource.register(); - EndTags.register(); - EndEnchantments.register(); - EndPotions.register(); - CraftingRecipes.register(); - FurnaceRecipes.register(); - AlloyingRecipes.register(); - AnvilRecipes.register(); - SmithingRecipes.register(); - InfusionRecipes.register(); - EndStructures.register(); - BonemealPlants.init(); - GeneratorOptions.init(); - LootTableUtil.init(); - FabricLoader.getInstance().getEntrypoints("betterend", BetterEndPlugin.class).forEach(BetterEndPlugin::register); - Integrations.init(); - Configs.saveConfigs(); - } - - public static ResourceLocation makeID(String path) { - return new ResourceLocation(MOD_ID, path); - } - - public static String getStringId(String id) { - return String.format("%s:%s", MOD_ID, id); - } - - public static boolean isModId(ResourceLocation id) { - return id.getNamespace().equals(MOD_ID); - } -} diff --git a/src/main/java/ru/betterend/api/BetterEndPlugin.java b/src/main/java/ru/betterend/api/BetterEndPlugin.java deleted file mode 100644 index 4b278aec..00000000 --- a/src/main/java/ru/betterend/api/BetterEndPlugin.java +++ /dev/null @@ -1,34 +0,0 @@ -package ru.betterend.api; - -public interface BetterEndPlugin { - /** - * Alloying recipes registration. - * See AlloyingRecipe.Builder for details. - */ - default void registerAlloyingRecipes() {} - - /** - * Smithing recipes registration. - * See AnvilSmithingRecipe.Builder for details. - */ - default void registerSmithingRecipes() {} - - /** - * Additional biomes registration. - * See BiomeRegistry.registerBiome for details. - */ - default void registerEndBiomes() {} - - /** - * Register other mod stuff, for example, EndHammers. - */ - default void registerOthers() {} - - - public static void register(BetterEndPlugin plugin) { - plugin.registerAlloyingRecipes(); - plugin.registerSmithingRecipes(); - plugin.registerEndBiomes(); - plugin.registerOthers(); - } -} diff --git a/src/main/java/ru/betterend/blocks/AeterniumAnvil.java b/src/main/java/ru/betterend/blocks/AeterniumAnvil.java deleted file mode 100644 index 7233dedb..00000000 --- a/src/main/java/ru/betterend/blocks/AeterniumAnvil.java +++ /dev/null @@ -1,33 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.world.item.Item; -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import ru.betterend.blocks.basis.EndAnvilBlock; -import ru.betterend.item.EndAnvilItem; -import ru.betterend.item.material.EndToolMaterial; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class AeterniumAnvil extends EndAnvilBlock { - - protected final Item anvilItem; - - public AeterniumAnvil() { - super(EndBlocks.AETERNIUM_BLOCK.defaultMaterialColor(), EndToolMaterial.AETERNIUM.getLevel()); - this.anvilItem = EndItems.registerEndItem("aeternuim_anvil_item", new EndAnvilItem(this)); - } - - @Override - public IntegerProperty getDurability() { - if (durability == null) { - this.maxDurability = 8; - this.durability = IntegerProperty.create("durability", 0, maxDurability); - } - return durability; - } - - @Override - public Item asItem() { - return anvilItem; - } -} diff --git a/src/main/java/ru/betterend/blocks/AeterniumBlock.java b/src/main/java/ru/betterend/blocks/AeterniumBlock.java deleted file mode 100644 index d176689d..00000000 --- a/src/main/java/ru/betterend/blocks/AeterniumBlock.java +++ /dev/null @@ -1,28 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.blocks.BaseBlock; - -public class AeterniumBlock extends BaseBlock { - - public AeterniumBlock() { - super(FabricBlockSettings.of(Material.METAL, MaterialColor.COLOR_GRAY) - .hardness(65F) - .resistance(1200F) - .requiresCorrectToolForDrops() - .sound(SoundType.NETHERITE_BLOCK)); - } - - @Environment(EnvType.CLIENT) - public int getColor(BlockState state, BlockGetter world, BlockPos pos) { - return 0xFF657A7A; - } -} diff --git a/src/main/java/ru/betterend/blocks/AmaranitaCapBlock.java b/src/main/java/ru/betterend/blocks/AmaranitaCapBlock.java deleted file mode 100644 index 83ccd506..00000000 --- a/src/main/java/ru/betterend/blocks/AmaranitaCapBlock.java +++ /dev/null @@ -1,13 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.material.Material; -import ru.bclib.blocks.BaseBlock; - -public class AmaranitaCapBlock extends BaseBlock { - public AmaranitaCapBlock() { - super(FabricBlockSettings.of(Material.WOOD).breakByTool(FabricToolTags.AXES).sound(SoundType.WOOD)); - } -} diff --git a/src/main/java/ru/betterend/blocks/AmaranitaHymenophoreBlock.java b/src/main/java/ru/betterend/blocks/AmaranitaHymenophoreBlock.java deleted file mode 100644 index a3f14802..00000000 --- a/src/main/java/ru/betterend/blocks/AmaranitaHymenophoreBlock.java +++ /dev/null @@ -1,20 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.material.Material; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; - -public class AmaranitaHymenophoreBlock extends BaseBlock implements IRenderTyped { - public AmaranitaHymenophoreBlock() { - super(FabricBlockSettings.of(Material.WOOD).breakByTool(FabricToolTags.AXES).sound(SoundType.WOOD)); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } -} diff --git a/src/main/java/ru/betterend/blocks/AncientEmeraldIceBlock.java b/src/main/java/ru/betterend/blocks/AncientEmeraldIceBlock.java deleted file mode 100644 index 2c73a6d1..00000000 --- a/src/main/java/ru/betterend/blocks/AncientEmeraldIceBlock.java +++ /dev/null @@ -1,70 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; -import java.util.Random; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.Enchantments; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndParticles; - -public class AncientEmeraldIceBlock extends BaseBlock { - public AncientEmeraldIceBlock() { - super(FabricBlockSettings.copyOf(Blocks.BLUE_ICE).randomTicks()); - } - - @Override - public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) { - Direction dir = BlocksHelper.randomDirection(random); - - if (random.nextBoolean()) { - int x = MHelper.randRange(-2, 2, random); - int y = MHelper.randRange(-2, 2, random); - int z = MHelper.randRange(-2, 2, random); - BlockPos p = pos.offset(x, y, z); - if (world.getBlockState(p).is(Blocks.WATER)) { - world.setBlockAndUpdate(p, EndBlocks.EMERALD_ICE.defaultBlockState()); - makeParticles(world, p, random); - } - } - - pos = pos.relative(dir); - state = world.getBlockState(pos); - if (state.is(Blocks.WATER)) { - world.setBlockAndUpdate(pos, EndBlocks.EMERALD_ICE.defaultBlockState()); - makeParticles(world, pos, random); - } - else if (state.is(EndBlocks.EMERALD_ICE)) { - world.setBlockAndUpdate(pos, EndBlocks.DENSE_EMERALD_ICE.defaultBlockState()); - makeParticles(world, pos, random); - } - } - - private void makeParticles(ServerLevel world, BlockPos pos, Random random) { - world.sendParticles(EndParticles.SNOWFLAKE, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 20, 0.5, 0.5, 0.5, 0); - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - ItemStack tool = builder.getOptionalParameter(LootContextParams.TOOL); - if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) != 0) { - return Collections.singletonList(new ItemStack(this)); - } - else { - return Collections.emptyList(); - } - } -} diff --git a/src/main/java/ru/betterend/blocks/AuroraCrystalBlock.java b/src/main/java/ru/betterend/blocks/AuroraCrystalBlock.java deleted file mode 100644 index 22473aa7..00000000 --- a/src/main/java/ru/betterend/blocks/AuroraCrystalBlock.java +++ /dev/null @@ -1,118 +0,0 @@ -package ru.betterend.blocks; - -import java.util.List; - -import com.google.common.collect.Lists; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.client.color.block.BlockColor; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Vec3i; -import net.minecraft.util.Mth; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.Enchantments; -import net.minecraft.world.level.block.AbstractGlassBlock; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IColorProvider; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.ColorUtil; -import ru.bclib.util.MHelper; -import ru.betterend.registry.EndItems; -import ru.betterend.registry.EndTags; - -public class AuroraCrystalBlock extends AbstractGlassBlock implements IRenderTyped, IColorProvider { - public static final Vec3i[] COLORS; - private static final int MIN_DROP = 1; - private static final int MAX_DROP = 4; - - public AuroraCrystalBlock() { - super(FabricBlockSettings.of(Material.GLASS) - .breakByTool(FabricToolTags.PICKAXES) - .breakByTool(EndTags.HAMMERS) - .hardness(1F) - .resistance(1F) - .luminance(15) - .noOcclusion() - .isSuffocating((state, world, pos) -> false) - .sound(SoundType.GLASS)); - } - - @Override - public BlockColor getProvider() { - return (state, world, pos, tintIndex) -> { - if (pos == null) { - pos = BlockPos.ZERO; - }; - - long i = (long) pos.getX() + (long) pos.getY() + (long) pos.getZ(); - double delta = i * 0.1; - int index = MHelper.floor(delta); - int index2 = (index + 1) & 3; - delta -= index; - index &= 3; - - Vec3i color1 = COLORS[index]; - Vec3i color2 = COLORS[index2]; - - int r = MHelper.floor(Mth.lerp(delta, color1.getX(), color2.getX())); - int g = MHelper.floor(Mth.lerp(delta, color1.getY(), color2.getY())); - int b = MHelper.floor(Mth.lerp(delta, color1.getZ(), color2.getZ())); - - return ColorUtil.color(r, g, b); - }; - } - - @Override - public ItemColor getItemProvider() { - return (stack, tintIndex) -> { - return ColorUtil.color(COLORS[3].getX(), COLORS[3].getY(), COLORS[3].getZ()); - }; - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.TRANSLUCENT; - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - ItemStack tool = builder.getParameter(LootContextParams.TOOL); - if (tool != null && tool.isCorrectToolForDrops(state)) { - int count = 0; - int enchant = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool); - if (enchant > 0) { - return Lists.newArrayList(new ItemStack(this)); - } - enchant = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, tool); - if (enchant > 0) { - int min = Mth.clamp(MIN_DROP + enchant, MIN_DROP, MAX_DROP); - int max = MAX_DROP + (enchant / Enchantments.BLOCK_FORTUNE.getMaxLevel()); - if (min == max) { - return Lists.newArrayList(new ItemStack(EndItems.CRYSTAL_SHARDS, max)); - } - count = MHelper.randRange(min, max, MHelper.RANDOM); - } else { - count = MHelper.randRange(MIN_DROP, MAX_DROP, MHelper.RANDOM); - } - return Lists.newArrayList(new ItemStack(EndItems.CRYSTAL_SHARDS, count)); - } - return Lists.newArrayList(); - } - - static { - COLORS = new Vec3i[] { - new Vec3i(247, 77, 161), - new Vec3i(120, 184, 255), - new Vec3i(120, 255, 168), - new Vec3i(243, 58, 255) - }; - } -} diff --git a/src/main/java/ru/betterend/blocks/BlueVineBlock.java b/src/main/java/ru/betterend/blocks/BlueVineBlock.java deleted file mode 100644 index 5e13a8f5..00000000 --- a/src/main/java/ru/betterend/blocks/BlueVineBlock.java +++ /dev/null @@ -1,23 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.UpDownPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class BlueVineBlock extends UpDownPlantBlock { - public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(SHAPE); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.getBlock() == EndBlocks.END_MOSS || state.getBlock() == EndBlocks.END_MYCELIUM; - } -} diff --git a/src/main/java/ru/betterend/blocks/BlueVineLanternBlock.java b/src/main/java/ru/betterend/blocks/BlueVineLanternBlock.java deleted file mode 100644 index bec0c00e..00000000 --- a/src/main/java/ru/betterend/blocks/BlueVineLanternBlock.java +++ /dev/null @@ -1,47 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.material.Material; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.blocks.BlockProperties; -import ru.betterend.registry.EndBlocks; - -public class BlueVineLanternBlock extends BaseBlock { - public static final BooleanProperty NATURAL = BlockProperties.NATURAL; - - public BlueVineLanternBlock() { - super(FabricBlockSettings.of(Material.WOOD).breakByTool(FabricToolTags.AXES).luminance(15).sound(SoundType.WART_BLOCK)); - this.registerDefaultState(this.stateDefinition.any().setValue(NATURAL, false)); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - return !state.getValue(NATURAL) || world.getBlockState(pos.below()).getBlock() == EndBlocks.BLUE_VINE; - } - - @Override - public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - if (!canSurvive(state, world, pos)) { - return Blocks.AIR.defaultBlockState(); - } - else { - return state; - } - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(NATURAL); - } -} diff --git a/src/main/java/ru/betterend/blocks/BlueVineSeedBlock.java b/src/main/java/ru/betterend/blocks/BlueVineSeedBlock.java deleted file mode 100644 index 8f8edc36..00000000 --- a/src/main/java/ru/betterend/blocks/BlueVineSeedBlock.java +++ /dev/null @@ -1,55 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.blocks.basis.EndPlantWithAgeBlock; -import ru.betterend.blocks.basis.FurBlock; -import ru.betterend.registry.EndBlocks; - -public class BlueVineSeedBlock extends EndPlantWithAgeBlock { - @Override - public void growAdult(WorldGenLevel world, Random random, BlockPos pos) { - int height = MHelper.randRange(2, 5, random); - int h = BlocksHelper.upRay(world, pos, height + 2); - if (h < height + 1) { - return; - } - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.BLUE_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.BOTTOM)); - for (int i = 1; i < height; i++) { - BlocksHelper.setWithoutUpdate(world, pos.above(i), EndBlocks.BLUE_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.MIDDLE)); - } - BlocksHelper.setWithoutUpdate(world, pos.above(height), EndBlocks.BLUE_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.TOP)); - placeLantern(world, pos.above(height + 1)); - } - - private void placeLantern(WorldGenLevel world, BlockPos pos) { - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.BLUE_VINE_LANTERN.defaultBlockState().setValue(BlueVineLanternBlock.NATURAL, true)); - for (Direction dir: BlocksHelper.HORIZONTAL) { - BlockPos p = pos.relative(dir); - if (world.isEmptyBlock(p)) { - BlocksHelper.setWithoutUpdate(world, p, EndBlocks.BLUE_VINE_FUR.defaultBlockState().setValue(FurBlock.FACING, dir)); - } - } - if (world.isEmptyBlock(pos.above())) { - BlocksHelper.setWithoutUpdate(world, pos.above(), EndBlocks.BLUE_VINE_FUR.defaultBlockState().setValue(FurBlock.FACING, Direction.UP)); - } - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.END_MOSS) || state.is(EndBlocks.END_MYCELIUM); - } - - @Override - public BlockBehaviour.OffsetType getOffsetType() { - return BlockBehaviour.OffsetType.NONE; - } -} diff --git a/src/main/java/ru/betterend/blocks/BoluxMushroomBlock.java b/src/main/java/ru/betterend/blocks/BoluxMushroomBlock.java deleted file mode 100644 index a7c95243..00000000 --- a/src/main/java/ru/betterend/blocks/BoluxMushroomBlock.java +++ /dev/null @@ -1,57 +0,0 @@ -package ru.betterend.blocks; - -import java.util.List; -import java.util.Random; - -import com.google.common.collect.Lists; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.betterend.blocks.basis.EndPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class BoluxMushroomBlock extends EndPlantBlock { - private static final VoxelShape SHAPE = Block.box(1, 0, 1, 15, 9, 15); - - public BoluxMushroomBlock() { - super(10); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.RUTISCUS); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return SHAPE; - } - - @Override - public BlockBehaviour.OffsetType getOffsetType() { - return BlockBehaviour.OffsetType.NONE; - } - - @Override - public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { - return false; - } - - @Override - public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) { - return false; - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - return Lists.newArrayList(new ItemStack(this)); - } -} diff --git a/src/main/java/ru/betterend/blocks/BrimstoneBlock.java b/src/main/java/ru/betterend/blocks/BrimstoneBlock.java deleted file mode 100644 index e26d2ce1..00000000 --- a/src/main/java/ru/betterend/blocks/BrimstoneBlock.java +++ /dev/null @@ -1,103 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import org.jetbrains.annotations.Nullable; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.util.BlocksHelper; -import ru.betterend.registry.EndBlocks; - -public class BrimstoneBlock extends BaseBlock { - public static final BooleanProperty ACTIVATED = BlockProperties.ACTIVE; - - public BrimstoneBlock() { - super(FabricBlockSettings.copyOf(Blocks.END_STONE).materialColor(MaterialColor.COLOR_BROWN).randomTicks()); - registerDefaultState(stateDefinition.any().setValue(ACTIVATED, false)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(ACTIVATED); - } - - @Override - public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) { - if (world.isClientSide()) { - updateChunks((ClientLevel) world, pos); - } - } - - public void destroy(LevelAccessor world, BlockPos pos, BlockState state) { - if (world.isClientSide()) { - updateChunks((ClientLevel) world, pos); - } - } - - private void updateChunks(ClientLevel world, BlockPos pos) { - int y = pos.getY() >> 4; - int x1 = (pos.getX() - 2) >> 4; - int z1 = (pos.getZ() - 2) >> 4; - int x2 = (pos.getX() + 2) >> 4; - int z2 = (pos.getZ() + 2) >> 4; - for (int x = x1; x <= x2; x++) { - for (int z = z1; z <= z2; z++) { - world.setSectionDirtyWithNeighbors(x, y, z); - } - } - } - - @Override - public void tick(BlockState state, ServerLevel world, BlockPos pos, Random random) { - boolean deactivate = true; - for (Direction dir: BlocksHelper.DIRECTIONS) { - if (world.getFluidState(pos.relative(dir)).getType().equals(Fluids.WATER)) { - deactivate = false; - break; - } - } - if (state.getValue(ACTIVATED)) { - if (deactivate) { - world.setBlockAndUpdate(pos, defaultBlockState().setValue(ACTIVATED, false)); - } - else if (state.getValue(ACTIVATED) && random.nextInt(16) == 0) { - Direction dir = BlocksHelper.randomDirection(random); - BlockPos side = pos.relative(dir); - BlockState sideState = world.getBlockState(side); - if (sideState.getBlock() instanceof SulphurCrystalBlock) { - if (sideState.getValue(SulphurCrystalBlock.AGE) < 2 && sideState.getValue(SulphurCrystalBlock.WATERLOGGED)) { - int age = sideState.getValue(SulphurCrystalBlock.AGE) + 1; - world.setBlockAndUpdate(side, sideState.setValue(SulphurCrystalBlock.AGE, age)); - } - } - else if (sideState.getFluidState().getType() == Fluids.WATER) { - BlockState crystal = EndBlocks.SULPHUR_CRYSTAL.defaultBlockState() - .setValue(SulphurCrystalBlock.FACING, dir) - .setValue(SulphurCrystalBlock.WATERLOGGED, true) - .setValue(SulphurCrystalBlock.AGE, 0); - world.setBlockAndUpdate(side, crystal); - } - } - } - else if (!deactivate && !state.getValue(ACTIVATED)) { - world.setBlockAndUpdate(pos, defaultBlockState().setValue(ACTIVATED, true)); - } - } -} diff --git a/src/main/java/ru/betterend/blocks/BubbleCoralBlock.java b/src/main/java/ru/betterend/blocks/BubbleCoralBlock.java deleted file mode 100644 index 22bbaa67..00000000 --- a/src/main/java/ru/betterend/blocks/BubbleCoralBlock.java +++ /dev/null @@ -1,61 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.betterend.blocks.basis.EndUnderwaterPlantBlock; - -public class BubbleCoralBlock extends EndUnderwaterPlantBlock { - - private static final VoxelShape SHAPE = Block.box(0, 0, 0, 16, 14, 16); - - public BubbleCoralBlock() { - super(FabricBlockSettings.of(Material.WATER_PLANT) - .breakByTool(FabricToolTags.SHEARS) - .breakByHand(true) - .sound(SoundType.CORAL_BLOCK) - .noCollission()); - } - - @Override - public BlockBehaviour.OffsetType getOffsetType() { - return BlockBehaviour.OffsetType.NONE; - } - - @Environment(EnvType.CLIENT) - public void animateTick(BlockState state, Level world, BlockPos pos, Random random) { - double x = pos.getX() + random.nextDouble(); - double y = pos.getY() + random.nextDouble() * 0.5F + 0.5F; - double z = pos.getZ() + random.nextDouble(); - world.addParticle(ParticleTypes.BUBBLE, x, y, z, 0.0D, 0.0D, 0.0D); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return SHAPE; - } - - @Override - public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { - return false; - } - - @Override - public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) { - return false; - } -} diff --git a/src/main/java/ru/betterend/blocks/BulbVineBlock.java b/src/main/java/ru/betterend/blocks/BulbVineBlock.java deleted file mode 100644 index 09b53a11..00000000 --- a/src/main/java/ru/betterend/blocks/BulbVineBlock.java +++ /dev/null @@ -1,47 +0,0 @@ -package ru.betterend.blocks; - -import java.util.List; - -import com.google.common.collect.Lists; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.storage.loot.LootContext; -import ru.bclib.blocks.BaseVineBlock; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.util.MHelper; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class BulbVineBlock extends BaseVineBlock { - public BulbVineBlock() { - super(15, true); - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - if (state.getValue(SHAPE) == TripleShape.BOTTOM) { - return Lists.newArrayList(new ItemStack(EndItems.GLOWING_BULB)); - } - else if (MHelper.RANDOM.nextInt(8) == 0) { - return Lists.newArrayList(new ItemStack(EndBlocks.BULB_VINE_SEED)); - } - else { - return Lists.newArrayList(); - } - } - - @Override - public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { - return false; - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - boolean canPlace = super.canSurvive(state, world, pos); - return (state.is(this) && state.getValue(SHAPE) == TripleShape.BOTTOM) ? canPlace : canPlace && world.getBlockState(pos.below()).is(this); - } -} diff --git a/src/main/java/ru/betterend/blocks/BulbVineLanternBlock.java b/src/main/java/ru/betterend/blocks/BulbVineLanternBlock.java deleted file mode 100644 index 0302faab..00000000 --- a/src/main/java/ru/betterend/blocks/BulbVineLanternBlock.java +++ /dev/null @@ -1,80 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Map; -import java.util.Optional; - -import org.jetbrains.annotations.Nullable; - -import com.google.common.collect.Maps; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.material.MaterialColor; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.client.models.BlockModelProvider; -import ru.bclib.client.models.ModelsHelper; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.betterend.blocks.basis.EndLanternBlock; -import ru.betterend.client.models.Patterns; - -public class BulbVineLanternBlock extends EndLanternBlock implements IRenderTyped, BlockModelProvider { - private static final VoxelShape SHAPE_CEIL = Block.box(4, 4, 4, 12, 16, 12); - private static final VoxelShape SHAPE_FLOOR = Block.box(4, 0, 4, 12, 12, 12); - - public BulbVineLanternBlock() { - this(FabricBlockSettings.of(Material.METAL) - .hardness(1) - .resistance(1) - .breakByTool(FabricToolTags.PICKAXES) - .materialColor(MaterialColor.COLOR_LIGHT_GRAY) - .luminance(15) - .requiresCorrectToolForDrops() - .sound(SoundType.LANTERN)); - } - - public BulbVineLanternBlock(Properties settings) { - super(settings); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return state.getValue(IS_FLOOR) ? SHAPE_FLOOR : SHAPE_CEIL; - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - @Override - public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { - Map textures = Maps.newHashMap(); - textures.put("%glow%", getGlowTexture()); - textures.put("%metal%", getMetalTexture(resourceLocation)); - Optional pattern = blockState.getValue(IS_FLOOR) ? - Patterns.createJson(Patterns.BLOCK_BULB_LANTERN_FLOOR, textures) : - Patterns.createJson(Patterns.BLOCK_BULB_LANTERN_CEIL, textures); - return ModelsHelper.fromPattern(pattern); - } - - protected String getMetalTexture(ResourceLocation blockId) { - String name = blockId.getPath(); - name = name.substring(0, name.indexOf('_')); - return name + "_bulb_vine_lantern_metal"; - } - - protected String getGlowTexture() { - return "bulb_vine_lantern_bulb"; - } - -} diff --git a/src/main/java/ru/betterend/blocks/BulbVineLanternColoredBlock.java b/src/main/java/ru/betterend/blocks/BulbVineLanternColoredBlock.java deleted file mode 100644 index 4eab8f1a..00000000 --- a/src/main/java/ru/betterend/blocks/BulbVineLanternColoredBlock.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.client.color.block.BlockColor; -import net.minecraft.client.color.item.ItemColor; -import ru.bclib.interfaces.IColorProvider; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.ColorUtil; - -public class BulbVineLanternColoredBlock extends BulbVineLanternBlock implements IColorProvider { - public BulbVineLanternColoredBlock(FabricBlockSettings settings) { - super(settings); - } - - @Override - public BlockColor getProvider() { - return (state, world, pos, tintIndex) -> getColor(); - } - - @Override - public ItemColor getItemProvider() { - return (stack, tintIndex) -> getColor(); - } - - private int getColor() { - int color = BlocksHelper.getBlockColor(this); - int b = (color & 255); - int g = ((color >> 8) & 255); - int r = ((color >> 16) & 255); - float[] hsv = ColorUtil.RGBtoHSB(r, g, b, new float[3]); - return ColorUtil.HSBtoRGB(hsv[0], hsv[1], hsv[1] > 0.2 ? 1 : hsv[2]); - } - - @Override - protected String getGlowTexture() { - return "bulb_vine_lantern_overlay"; - } -} diff --git a/src/main/java/ru/betterend/blocks/BulbVineSeedBlock.java b/src/main/java/ru/betterend/blocks/BulbVineSeedBlock.java deleted file mode 100644 index e0fa5161..00000000 --- a/src/main/java/ru/betterend/blocks/BulbVineSeedBlock.java +++ /dev/null @@ -1,36 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.tags.BlockTags; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.util.BlocksHelper; -import ru.betterend.blocks.basis.EndPlantWithAgeBlock; -import ru.betterend.registry.EndBlocks; - -public class BulbVineSeedBlock extends EndPlantWithAgeBlock { - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - BlockState up = world.getBlockState(pos.above()); - return up.is(TagAPI.GEN_TERRAIN) || up.is(BlockTags.LOGS) || up.is(BlockTags.LEAVES); - } - - @Override - public void growAdult(WorldGenLevel world, Random random, BlockPos pos) { - int h = BlocksHelper.downRay(world, pos, random.nextInt(24)) - 1; - if (h > 2) { - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.BULB_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP)); - for (int i = 1; i < h; i++) { - BlocksHelper.setWithoutUpdate(world, pos.below(i), EndBlocks.BULB_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE)); - } - BlocksHelper.setWithoutUpdate(world, pos.below(h), EndBlocks.BULB_VINE.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM)); - } - } -} diff --git a/src/main/java/ru/betterend/blocks/CavePumpkinBlock.java b/src/main/java/ru/betterend/blocks/CavePumpkinBlock.java deleted file mode 100644 index f61aa0cb..00000000 --- a/src/main/java/ru/betterend/blocks/CavePumpkinBlock.java +++ /dev/null @@ -1,66 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BaseBlockNotFull; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.betterend.registry.EndBlocks; - -public class CavePumpkinBlock extends BaseBlockNotFull implements IRenderTyped { - public static final BooleanProperty SMALL = BlockProperties.SMALL; - private static final VoxelShape SHAPE_SMALL; - private static final VoxelShape SHAPE_BIG; - - public CavePumpkinBlock() { - super(FabricBlockSettings.copyOf(Blocks.PUMPKIN).luminance((state) -> state.getValue(SMALL) ? 10 : 15)); - registerDefaultState(defaultBlockState().setValue(SMALL, false)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(SMALL); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { - return state.getValue(SMALL) ? SHAPE_SMALL : SHAPE_BIG; - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - return state.getValue(SMALL) ? Collections.singletonList(new ItemStack(EndBlocks.CAVE_PUMPKIN_SEED)) : Collections.singletonList(new ItemStack(this)); - } - - static { - VoxelShape lantern = Block.box(1, 0, 1, 15, 13, 15); - VoxelShape cap = Block.box(0, 12, 0, 16, 15, 16); - VoxelShape top = Block.box(5, 15, 5, 11, 16, 11); - SHAPE_BIG = Shapes.or(lantern, cap, top); - - lantern = Block.box(1, 7, 1, 15, 13, 15); - cap = Block.box(4, 12, 4, 12, 15, 12); - top = Block.box(6, 15, 6, 10, 16, 10); - SHAPE_SMALL = Shapes.or(lantern, cap, top); - } -} diff --git a/src/main/java/ru/betterend/blocks/CavePumpkinVineBlock.java b/src/main/java/ru/betterend/blocks/CavePumpkinVineBlock.java deleted file mode 100644 index 9e5278d9..00000000 --- a/src/main/java/ru/betterend/blocks/CavePumpkinVineBlock.java +++ /dev/null @@ -1,71 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BlockProperties; -import ru.betterend.blocks.basis.EndPlantWithAgeBlock; -import ru.betterend.registry.EndBlocks; - -public class CavePumpkinVineBlock extends EndPlantWithAgeBlock { - private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 16, 12); - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - BlockState down = world.getBlockState(pos.above()); - return isTerrain(down); - } - - @Override - public void performBonemeal(ServerLevel world, Random random, BlockPos pos, BlockState state) { - int age = state.getValue(AGE); - BlockState down = world.getBlockState(pos.below()); - if (down.getMaterial().isReplaceable() || (down.is(EndBlocks.CAVE_PUMPKIN) && down.getValue(BlockProperties.SMALL))) { - if (age < 3) { - world.setBlockAndUpdate(pos, state.setValue(AGE, age + 1)); - } - if (age == 2) { - world.setBlockAndUpdate(pos.below(), EndBlocks.CAVE_PUMPKIN.defaultBlockState().setValue(BlockProperties.SMALL, true)); - } - else if (age == 3) { - world.setBlockAndUpdate(pos.below(), EndBlocks.CAVE_PUMPKIN.defaultBlockState()); - } - } - } - - @Override - public void growAdult(WorldGenLevel world, Random random, BlockPos pos) {} - - @Override - public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - state = super.updateShape(state, facing, neighborState, world, pos, neighborPos); - if (state.is(this) && state.getValue(BlockProperties.AGE) > 1) { - BlockState down = world.getBlockState(pos.below()); - if (!down.is(EndBlocks.CAVE_PUMPKIN)) { - state = state.setValue(BlockProperties.AGE, 1); - } - } - return state; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return SHAPE; - } - - @Override - public BlockBehaviour.OffsetType getOffsetType() { - return BlockBehaviour.OffsetType.NONE; - } -} diff --git a/src/main/java/ru/betterend/blocks/ChandelierBlock.java b/src/main/java/ru/betterend/blocks/ChandelierBlock.java deleted file mode 100644 index 21a906f7..00000000 --- a/src/main/java/ru/betterend/blocks/ChandelierBlock.java +++ /dev/null @@ -1,105 +0,0 @@ -package ru.betterend.blocks; - -import java.util.EnumMap; -import java.util.Map; -import java.util.Optional; - -import org.jetbrains.annotations.Nullable; - -import com.google.common.collect.Maps; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.resources.model.BlockModelRotation; -import net.minecraft.client.resources.model.UnbakedModel; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BaseAttachedBlock; -import ru.bclib.client.models.BlockModelProvider; -import ru.bclib.client.models.ModelsHelper; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.betterend.client.models.Patterns; - -public class ChandelierBlock extends BaseAttachedBlock implements IRenderTyped, BlockModelProvider { - private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(Direction.class); - - public ChandelierBlock(Block source) { - super(FabricBlockSettings.copyOf(source).luminance(15).noCollission().noOcclusion().requiresCorrectToolForDrops()); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return BOUNDING_SHAPES.get(state.getValue(FACING)); - } - - @Override - public BlockModel getItemModel(ResourceLocation blockId) { - return ModelsHelper.createItemModel(blockId); - } - - @Override - public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { - Optional pattern; - switch (blockState.getValue(FACING)) { - case UP: - pattern = Patterns.createJson(Patterns.BLOCK_CHANDELIER_FLOOR, resourceLocation.getPath()); - break; - case DOWN: - pattern = Patterns.createJson(Patterns.BLOCK_CHANDELIER_CEIL, resourceLocation.getPath()); - break; - default: - pattern = Patterns.createJson(Patterns.BLOCK_CHANDELIER_WALL, resourceLocation.getPath()); - } - return ModelsHelper.fromPattern(pattern); - } - - @Override - public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map modelCache) { - String state = "_wall"; - BlockModelRotation rotation = BlockModelRotation.X0_Y0; - switch (blockState.getValue(FACING)) { - case UP: - state = "_floor"; - break; - case DOWN: - state = "_ceil"; - break; - case EAST: - rotation = BlockModelRotation.X0_Y270; - break; - case NORTH: - rotation = BlockModelRotation.X0_Y180; - break; - case WEST: - rotation = BlockModelRotation.X0_Y90; - break; - default: - break; - } - ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath() + state); - registerBlockModel(stateId, modelId, blockState, modelCache); - return ModelsHelper.createMultiVariant(modelId, rotation.getRotation(), false); - } - - static { - BOUNDING_SHAPES.put(Direction.UP, Block.box(5, 0, 5, 11, 13, 11)); - BOUNDING_SHAPES.put(Direction.DOWN, Block.box(5, 3, 5, 11, 16, 11)); - BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.0, 0.0, 0.5, 1.0, 1.0, 1.0)); - BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 0.5)); - BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.5, 0.0, 0.0, 1.0, 1.0, 1.0)); - BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.0, 0.0, 0.5, 1.0, 1.0)); - } -} diff --git a/src/main/java/ru/betterend/blocks/CharcoalBlock.java b/src/main/java/ru/betterend/blocks/CharcoalBlock.java deleted file mode 100644 index d9fa10a8..00000000 --- a/src/main/java/ru/betterend/blocks/CharcoalBlock.java +++ /dev/null @@ -1,13 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.registry.FuelRegistry; -import net.minecraft.world.level.block.Blocks; -import ru.bclib.blocks.BaseBlock; - -public class CharcoalBlock extends BaseBlock { - public CharcoalBlock() { - super(FabricBlockSettings.copyOf(Blocks.COAL_BLOCK)); - FuelRegistry.INSTANCE.add(this, 16000); - } -} diff --git a/src/main/java/ru/betterend/blocks/CharniaBlock.java b/src/main/java/ru/betterend/blocks/CharniaBlock.java deleted file mode 100644 index 5a665ab6..00000000 --- a/src/main/java/ru/betterend/blocks/CharniaBlock.java +++ /dev/null @@ -1,16 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Fluids; -import ru.betterend.blocks.basis.EndUnderwaterPlantBlock; - -public class CharniaBlock extends EndUnderwaterPlantBlock { - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - return canSupportCenter(world, pos.below(), Direction.UP) && world.getFluidState(pos).getType() == Fluids.WATER; - } -} diff --git a/src/main/java/ru/betterend/blocks/ChorusGrassBlock.java b/src/main/java/ru/betterend/blocks/ChorusGrassBlock.java deleted file mode 100644 index 71635d36..00000000 --- a/src/main/java/ru/betterend/blocks/ChorusGrassBlock.java +++ /dev/null @@ -1,16 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.world.level.block.state.BlockState; -import ru.betterend.blocks.basis.EndPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class ChorusGrassBlock extends EndPlantBlock { - public ChorusGrassBlock() { - super(true); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.getBlock() == EndBlocks.CHORUS_NYLIUM; - } -} diff --git a/src/main/java/ru/betterend/blocks/DenseEmeraldIceBlock.java b/src/main/java/ru/betterend/blocks/DenseEmeraldIceBlock.java deleted file mode 100644 index ece46509..00000000 --- a/src/main/java/ru/betterend/blocks/DenseEmeraldIceBlock.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.Enchantments; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; - -public class DenseEmeraldIceBlock extends BaseBlock implements IRenderTyped { - public DenseEmeraldIceBlock() { - super(FabricBlockSettings.copyOf(Blocks.PACKED_ICE)); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.TRANSLUCENT; - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - ItemStack tool = builder.getOptionalParameter(LootContextParams.TOOL); - if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) != 0) { - return Collections.singletonList(new ItemStack(this)); - } - else { - return Collections.emptyList(); - } - } -} diff --git a/src/main/java/ru/betterend/blocks/DragonTreeSaplingBlock.java b/src/main/java/ru/betterend/blocks/DragonTreeSaplingBlock.java deleted file mode 100644 index 12310aab..00000000 --- a/src/main/java/ru/betterend/blocks/DragonTreeSaplingBlock.java +++ /dev/null @@ -1,25 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.feature.Feature; -import ru.bclib.blocks.FeatureSaplingBlock; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; - -public class DragonTreeSaplingBlock extends FeatureSaplingBlock { - public DragonTreeSaplingBlock() { - super(); - } - - @Override - protected Feature getFeature() { - return EndFeatures.DRAGON_TREE.getFeature(); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - return world.getBlockState(pos.below()).is(EndBlocks.SHADOW_GRASS); - } -} diff --git a/src/main/java/ru/betterend/blocks/EmeraldIceBlock.java b/src/main/java/ru/betterend/blocks/EmeraldIceBlock.java deleted file mode 100644 index f8c010f1..00000000 --- a/src/main/java/ru/betterend/blocks/EmeraldIceBlock.java +++ /dev/null @@ -1,91 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; -import java.util.Random; - -import org.jetbrains.annotations.Nullable; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.Enchantments; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LightLayer; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.HalfTransparentBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import ru.bclib.client.models.BlockModelProvider; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; - -public class EmeraldIceBlock extends HalfTransparentBlock implements IRenderTyped, BlockModelProvider { - public EmeraldIceBlock() { - super(FabricBlockSettings.copyOf(Blocks.ICE)); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.TRANSLUCENT; - } - - @Override - public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack stack) { - super.playerDestroy(world, player, pos, state, blockEntity, stack); - if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, stack) == 0) { - if (world.dimensionType().ultraWarm()) { - world.removeBlock(pos, false); - return; - } - - Material material = world.getBlockState(pos.below()).getMaterial(); - if (material.blocksMotion() || material.isLiquid()) { - world.setBlockAndUpdate(pos, Blocks.WATER.defaultBlockState()); - } - } - - } - - @Override - public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) { - if (world.getBrightness(LightLayer.BLOCK, pos) > 11 - state.getLightBlock(world, pos)) { - this.melt(state, world, pos); - } - - } - - protected void melt(BlockState state, Level world, BlockPos pos) { - if (world.dimensionType().ultraWarm()) { - world.removeBlock(pos, false); - } - else { - world.setBlockAndUpdate(pos, Blocks.WATER.defaultBlockState()); - world.neighborChanged(pos, Blocks.WATER, pos); - } - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - ItemStack tool = builder.getOptionalParameter(LootContextParams.TOOL); - if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) != 0) { - return Collections.singletonList(new ItemStack(this)); - } - else { - return Collections.emptyList(); - } - } - - @Override - public BlockModel getItemModel(ResourceLocation resourceLocation) { - return getBlockModel(resourceLocation, defaultBlockState()); - } -} diff --git a/src/main/java/ru/betterend/blocks/EndBlockProperties.java b/src/main/java/ru/betterend/blocks/EndBlockProperties.java deleted file mode 100644 index 233c5f05..00000000 --- a/src/main/java/ru/betterend/blocks/EndBlockProperties.java +++ /dev/null @@ -1,127 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.util.StringRepresentable; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import ru.bclib.blocks.BlockProperties; -import ru.betterend.registry.EndPortals; - -public class EndBlockProperties extends BlockProperties { - public static final EnumProperty HYDRALUX_SHAPE = EnumProperty.create("shape", HydraluxShape.class); - public static final EnumProperty PEDESTAL_STATE = EnumProperty.create("state", PedestalState.class); - public static final EnumProperty CACTUS_BOTTOM = EnumProperty.create("bottom", CactusBottom.class); - - public static final BooleanProperty HAS_ITEM = BooleanProperty.create("has_item"); - public static final IntegerProperty PORTAL = IntegerProperty.create("portal", 0, EndPortals.getCount()); - - public enum PedestalState implements StringRepresentable { - PEDESTAL_TOP("pedestal_top"), - COLUMN_TOP("column_top"), - BOTTOM("bottom"), - PILLAR("pillar"), - COLUMN("column"), - DEFAULT("default"); - - private final String name; - - PedestalState(String name) { - this.name = name; - } - - @Override - public String getSerializedName() { - return this.name; - } - - @Override - public String toString() { - return this.name; - } - } - - public enum HydraluxShape implements StringRepresentable { - FLOWER_BIG_BOTTOM("flower_big_bottom", true), - FLOWER_BIG_TOP("flower_big_top", true), - FLOWER_SMALL_BOTTOM("flower_small_bottom", true), - FLOWER_SMALL_TOP("flower_small_top", true), - VINE("vine", false), - ROOTS("roots", false); - - private final String name; - private final boolean glow; - - HydraluxShape(String name, boolean glow) { - this.name = name; - this.glow = glow; - } - - @Override - public String getSerializedName() { - return name; - } - - @Override - public String toString() { - return name; - } - - public boolean hasGlow() { - return glow; - } - } - - public enum LumecornShape implements StringRepresentable { - LIGHT_TOP("light_top", 15), - LIGHT_TOP_MIDDLE("light_top_middle", 15), - LIGHT_MIDDLE("light_middle", 15), - LIGHT_BOTTOM("light_bottom", 15), - MIDDLE("middle", 0), - BOTTOM_BIG("bottom_big", 0), - BOTTOM_SMALL("bottom_small", 0); - - private final String name; - private final int light; - - LumecornShape(String name, int light) { - this.name = name; - this.light = light; - } - - @Override - public String getSerializedName() { - return name; - } - - @Override - public String toString() { - return name; - } - - public int getLight() { - return light; - } - } - - public enum CactusBottom implements StringRepresentable { - EMPTY("empty"), - SAND("sand"), - MOSS("moss"); - - private final String name; - - CactusBottom(String name) { - this.name = name; - } - - @Override - public String getSerializedName() { - return name; - } - - @Override - public String toString() { - return name; - } - } -} diff --git a/src/main/java/ru/betterend/blocks/EndLilyBlock.java b/src/main/java/ru/betterend/blocks/EndLilyBlock.java deleted file mode 100644 index 63b4dcb4..00000000 --- a/src/main/java/ru/betterend/blocks/EndLilyBlock.java +++ /dev/null @@ -1,119 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; -import java.util.Random; - -import com.google.common.collect.Lists; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.phys.Vec3; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.util.MHelper; -import ru.betterend.blocks.basis.EndUnderwaterPlantBlock; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class EndLilyBlock extends EndUnderwaterPlantBlock { - public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; - private static final VoxelShape SHAPE_BOTTOM = Block.box(4, 0, 4, 12, 16, 12); - private static final VoxelShape SHAPE_TOP = Block.box(2, 0, 2, 14, 6, 14); - - public EndLilyBlock() { - super(FabricBlockSettings.of(Material.WATER_PLANT) - .breakByTool(FabricToolTags.SHEARS) - .breakByHand(true) - .sound(SoundType.WET_GRASS) - .lightLevel((state) -> state.getValue(SHAPE) == TripleShape.TOP ? 13 : 0) - .noCollission()); - } - - @Override - public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - if (!canSurvive(state, world, pos)) { - return state.getValue(SHAPE) == TripleShape.TOP ? Blocks.AIR.defaultBlockState() : Blocks.WATER.defaultBlockState(); - } - else { - return state; - } - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - Vec3 vec3d = state.getOffset(view, pos); - VoxelShape shape = state.getValue(SHAPE) == TripleShape.TOP ? SHAPE_TOP : SHAPE_BOTTOM; - return shape.move(vec3d.x, vec3d.y, vec3d.z); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(SHAPE); - } - - @Override - public FluidState getFluidState(BlockState state) { - return state.getValue(SHAPE) == TripleShape.TOP ? Fluids.EMPTY.defaultFluidState() : Fluids.WATER.getSource(false); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - if (state.getValue(SHAPE) == TripleShape.TOP) { - return world.getBlockState(pos.below()).getBlock() == this; - } - else if (state.getValue(SHAPE) == TripleShape.BOTTOM) { - return isTerrain(world.getBlockState(pos.below())); - } - else { - BlockState up = world.getBlockState(pos.above()); - BlockState down = world.getBlockState(pos.below()); - return up.getBlock() == this && down.getBlock() == this; - } - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - if (state.getValue(SHAPE) == TripleShape.TOP) { - return Lists.newArrayList(new ItemStack(EndItems.END_LILY_LEAF, MHelper.randRange(1, 2, MHelper.RANDOM)), new ItemStack(EndBlocks.END_LILY_SEED, MHelper.randRange(1, 2, MHelper.RANDOM))); - } - return Collections.emptyList(); - } - - @Override - @Environment(EnvType.CLIENT) - public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) { - return new ItemStack(EndBlocks.END_LILY_SEED); - } - - @Override - public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { - return false; - } - - @Override - public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) { - return false; - } -} diff --git a/src/main/java/ru/betterend/blocks/EndLilySeedBlock.java b/src/main/java/ru/betterend/blocks/EndLilySeedBlock.java deleted file mode 100644 index b955a39f..00000000 --- a/src/main/java/ru/betterend/blocks/EndLilySeedBlock.java +++ /dev/null @@ -1,41 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Fluids; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.blocks.UnderwaterPlantWithAgeBlock; -import ru.bclib.util.BlocksHelper; -import ru.betterend.registry.EndBlocks; - -public class EndLilySeedBlock extends UnderwaterPlantWithAgeBlock { - @Override - public void grow(WorldGenLevel world, Random random, BlockPos pos) { - if (canGrow(world, pos)) { - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.END_LILY.defaultBlockState().setValue(EndLilyBlock.SHAPE, TripleShape.BOTTOM)); - BlockPos up = pos.above(); - while (world.getFluidState(up).isSource()) { - BlocksHelper.setWithoutUpdate(world, up, EndBlocks.END_LILY.defaultBlockState().setValue(EndLilyBlock.SHAPE, TripleShape.MIDDLE)); - up = up.above(); - } - BlocksHelper.setWithoutUpdate(world, up, EndBlocks.END_LILY.defaultBlockState().setValue(EndLilyBlock.SHAPE, TripleShape.TOP)); - } - } - - private boolean canGrow(WorldGenLevel world, BlockPos pos) { - BlockPos up = pos.above(); - while (world.getBlockState(up).getFluidState().getType().equals(Fluids.WATER.getSource())) { - up = up.above(); - } - return world.isEmptyBlock(up); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(TagAPI.END_GROUND); - } -} diff --git a/src/main/java/ru/betterend/blocks/EndLotusFlowerBlock.java b/src/main/java/ru/betterend/blocks/EndLotusFlowerBlock.java deleted file mode 100644 index d79a31ac..00000000 --- a/src/main/java/ru/betterend/blocks/EndLotusFlowerBlock.java +++ /dev/null @@ -1,63 +0,0 @@ -package ru.betterend.blocks; - -import java.util.List; - -import com.google.common.collect.Lists; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.util.MHelper; -import ru.betterend.blocks.basis.EndPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class EndLotusFlowerBlock extends EndPlantBlock { - private static final VoxelShape SHAPE_OUTLINE = Block.box(2, 0, 2, 14, 14, 14); - private static final VoxelShape SHAPE_COLLISION = Block.box(0, 0, 0, 16, 2, 16); - - public EndLotusFlowerBlock() { - super(FabricBlockSettings.of(Material.PLANT).luminance(15).noOcclusion()); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.END_LOTUS_STEM); - } - - @Override - public BlockBehaviour.OffsetType getOffsetType() { - return BlockBehaviour.OffsetType.NONE; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return SHAPE_OUTLINE; - } - - @Override - public VoxelShape getCollisionShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return SHAPE_COLLISION; - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - int count = MHelper.randRange(1, 2, MHelper.RANDOM); - return Lists.newArrayList(new ItemStack(EndBlocks.END_LOTUS_SEED, count)); - } - - @Override - @Environment(EnvType.CLIENT) - public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) { - return new ItemStack(EndBlocks.END_LOTUS_SEED); - } -} diff --git a/src/main/java/ru/betterend/blocks/EndLotusLeafBlock.java b/src/main/java/ru/betterend/blocks/EndLotusLeafBlock.java deleted file mode 100644 index af3199f3..00000000 --- a/src/main/java/ru/betterend/blocks/EndLotusLeafBlock.java +++ /dev/null @@ -1,76 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.material.WaterFluid; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BaseBlockNotFull; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.BlocksHelper; -import ru.betterend.registry.EndBlocks; - -public class EndLotusLeafBlock extends BaseBlockNotFull implements IRenderTyped { - public static final EnumProperty HORIZONTAL_FACING = BlockStateProperties.HORIZONTAL_FACING; - public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; - private static final VoxelShape VSHAPE = Block.box(0, 0, 0, 16, 1, 16); - - public EndLotusLeafBlock() { - super(FabricBlockSettings.of(Material.PLANT).noOcclusion().sound(SoundType.WET_GRASS)); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - BlockState down = world.getBlockState(pos.below()); - return !down.getFluidState().isEmpty() && down.getFluidState().getType() instanceof WaterFluid; - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - builder.add(SHAPE, HORIZONTAL_FACING); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return VSHAPE; - } - - @Override - public BlockState rotate(BlockState state, Rotation rotation) { - return BlocksHelper.rotateHorizontal(state, rotation, HORIZONTAL_FACING); - } - - @Override - public BlockState mirror(BlockState state, Mirror mirror) { - return BlocksHelper.mirrorHorizontal(state, mirror, HORIZONTAL_FACING); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - @Override - @Environment(EnvType.CLIENT) - public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) { - return new ItemStack(EndBlocks.END_LOTUS_SEED); - } -} diff --git a/src/main/java/ru/betterend/blocks/EndLotusSeedBlock.java b/src/main/java/ru/betterend/blocks/EndLotusSeedBlock.java deleted file mode 100644 index de268c6a..00000000 --- a/src/main/java/ru/betterend/blocks/EndLotusSeedBlock.java +++ /dev/null @@ -1,124 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Fluids; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.blocks.UnderwaterPlantWithAgeBlock; -import ru.bclib.util.BlocksHelper; -import ru.betterend.registry.EndBlocks; - -public class EndLotusSeedBlock extends UnderwaterPlantWithAgeBlock { - @Override - public void grow(WorldGenLevel world, Random random, BlockPos pos) { - if (canGrow(world, pos)) { - BlockState startLeaf = EndBlocks.END_LOTUS_STEM.defaultBlockState().setValue(EndLotusStemBlock.LEAF, true); - BlockState roots = EndBlocks.END_LOTUS_STEM.defaultBlockState().setValue(EndLotusStemBlock.SHAPE, TripleShape.BOTTOM).setValue(EndLotusStemBlock.WATERLOGGED, true); - BlockState stem = EndBlocks.END_LOTUS_STEM.defaultBlockState(); - BlockState flower = EndBlocks.END_LOTUS_FLOWER.defaultBlockState(); - - BlocksHelper.setWithoutUpdate(world, pos, roots); - MutableBlockPos bpos = new MutableBlockPos().set(pos); - bpos.setY(bpos.getY() + 1); - while (world.getFluidState(bpos).isSource()) { - BlocksHelper.setWithoutUpdate(world, bpos, stem.setValue(EndLotusStemBlock.WATERLOGGED, true)); - bpos.setY(bpos.getY() + 1); - } - - int height = random.nextBoolean() ? 0 : random.nextBoolean() ? 1 : random.nextBoolean() ? 1 : -1; - TripleShape shape = (height == 0) ? TripleShape.TOP : TripleShape.MIDDLE; - Direction dir = BlocksHelper.randomHorizontal(random); - BlockPos leafCenter = bpos.immutable().relative(dir); - if (hasLeaf(world, leafCenter)) { - generateLeaf(world, leafCenter); - BlocksHelper.setWithoutUpdate(world, bpos, startLeaf.setValue(EndLotusStemBlock.SHAPE, shape).setValue(EndLotusStemBlock.FACING, dir)); - } - else { - BlocksHelper.setWithoutUpdate(world, bpos, stem.setValue(EndLotusStemBlock.SHAPE, shape)); - } - - bpos.setY(bpos.getY() + 1); - for (int i = 1; i <= height; i++) { - if (!world.isEmptyBlock(bpos)) { - bpos.setY(bpos.getY() - 1); - BlocksHelper.setWithoutUpdate(world, bpos, flower); - bpos.setY(bpos.getY() - 1); - stem = world.getBlockState(bpos); - BlocksHelper.setWithoutUpdate(world, bpos, stem.setValue(EndLotusStemBlock.SHAPE, TripleShape.TOP)); - return; - } - BlocksHelper.setWithoutUpdate(world, bpos, stem); - bpos.setY(bpos.getY() + 1); - } - - if (!world.isEmptyBlock(bpos) || height < 0) { - bpos.setY(bpos.getY() - 1); - } - - BlocksHelper.setWithoutUpdate(world, bpos, flower); - bpos.setY(bpos.getY() - 1); - stem = world.getBlockState(bpos); - if (!stem.is(EndBlocks.END_LOTUS_STEM)) { - stem = EndBlocks.END_LOTUS_STEM.defaultBlockState(); - if (!world.getBlockState(bpos.north()).getFluidState().isEmpty()) { - stem = stem.setValue(EndLotusStemBlock.WATERLOGGED, true); - } - } - - if (world.getBlockState(bpos.relative(dir)).is(EndBlocks.END_LOTUS_LEAF)) { - stem = stem.setValue(EndLotusStemBlock.LEAF, true).setValue(EndLotusStemBlock.FACING, dir); - } - - BlocksHelper.setWithoutUpdate(world, bpos, stem.setValue(EndLotusStemBlock.SHAPE, TripleShape.TOP)); - } - } - - private boolean canGrow(WorldGenLevel world, BlockPos pos) { - MutableBlockPos bpos = new MutableBlockPos(); - bpos.set(pos); - while (world.getBlockState(bpos).getFluidState().getType().equals(Fluids.WATER.getSource())) { - bpos.setY(bpos.getY() + 1); - } - return world.isEmptyBlock(bpos) && world.isEmptyBlock(bpos.above()); - } - - private void generateLeaf(WorldGenLevel world, BlockPos pos) { - MutableBlockPos p = new MutableBlockPos(); - BlockState leaf = EndBlocks.END_LOTUS_LEAF.defaultBlockState(); - BlocksHelper.setWithoutUpdate(world, pos, leaf.setValue(EndLotusLeafBlock.SHAPE, TripleShape.BOTTOM)); - for (Direction move: BlocksHelper.HORIZONTAL) { - BlocksHelper.setWithoutUpdate(world, p.set(pos).move(move), leaf.setValue(EndLotusLeafBlock.HORIZONTAL_FACING, move).setValue(EndLotusLeafBlock.SHAPE, TripleShape.MIDDLE)); - } - for (int i = 0; i < 4; i ++) { - Direction d1 = BlocksHelper.HORIZONTAL[i]; - Direction d2 = BlocksHelper.HORIZONTAL[(i + 1) & 3]; - BlocksHelper.setWithoutUpdate(world, p.set(pos).move(d1).move(d2), leaf.setValue(EndLotusLeafBlock.HORIZONTAL_FACING, d1).setValue(EndLotusLeafBlock.SHAPE, TripleShape.TOP)); - } - } - - private boolean hasLeaf(WorldGenLevel world, BlockPos pos) { - MutableBlockPos p = new MutableBlockPos(); - p.setY(pos.getY()); - int count = 0; - for (int x = -1; x < 2; x ++) { - p.setX(pos.getX() + x); - for (int z = -1; z < 2; z ++) { - p.setZ(pos.getZ() + z); - if (world.isEmptyBlock(p) && !world.getFluidState(p.below()).isEmpty()) - count ++; - } - } - return count == 9; - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(TagAPI.END_GROUND); - } -} diff --git a/src/main/java/ru/betterend/blocks/EndLotusStemBlock.java b/src/main/java/ru/betterend/blocks/EndLotusStemBlock.java deleted file mode 100644 index 0c27ece2..00000000 --- a/src/main/java/ru/betterend/blocks/EndLotusStemBlock.java +++ /dev/null @@ -1,97 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Map; - -import com.google.common.collect.Maps; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Direction.Axis; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.SimpleWaterloggedBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.BlocksHelper; - -public class EndLotusStemBlock extends BaseBlock implements SimpleWaterloggedBlock, IRenderTyped { - public static final EnumProperty FACING = BlockStateProperties.FACING; - public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; - public static final BooleanProperty LEAF = BooleanProperty.create("leaf"); - public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; - private static final Map SHAPES = Maps.newEnumMap(Axis.class); - - public EndLotusStemBlock() { - super(FabricBlockSettings.copyOf(Blocks.OAK_PLANKS)); - this.registerDefaultState(defaultBlockState().setValue(WATERLOGGED, false).setValue(SHAPE, TripleShape.MIDDLE).setValue(LEAF, false).setValue(FACING, Direction.UP)); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return state.getValue(LEAF) ? SHAPES.get(Axis.Y) : SHAPES.get(state.getValue(FACING).getAxis()); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - builder.add(FACING, WATERLOGGED, SHAPE, LEAF); - } - - @Override - public FluidState getFluidState(BlockState state) { - return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - LevelAccessor worldAccess = ctx.getLevel(); - BlockPos blockPos = ctx.getClickedPos(); - return this.defaultBlockState().setValue(WATERLOGGED, worldAccess.getFluidState(blockPos).getType() == Fluids.WATER).setValue(FACING, ctx.getClickedFace()); - } - - @Override - public BlockState rotate(BlockState state, Rotation rotation) { - return BlocksHelper.rotateHorizontal(state, rotation, FACING); - } - - @Override - public BlockState mirror(BlockState state, Mirror mirror) { - return BlocksHelper.mirrorHorizontal(state, mirror, FACING); - } - - @Override - public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) { - if (state.getValue(WATERLOGGED)) { - world.getLiquidTicks().scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); - } - return state; - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - static { - SHAPES.put(Axis.X, Block.box(0, 6, 6, 16, 10, 10)); - SHAPES.put(Axis.Y, Block.box(6, 0, 6, 10, 16, 10)); - SHAPES.put(Axis.Z, Block.box(6, 6, 0, 10, 10, 16)); - } -} diff --git a/src/main/java/ru/betterend/blocks/EndPedestal.java b/src/main/java/ru/betterend/blocks/EndPedestal.java deleted file mode 100644 index be4b0a78..00000000 --- a/src/main/java/ru/betterend/blocks/EndPedestal.java +++ /dev/null @@ -1,33 +0,0 @@ -package ru.betterend.blocks; - -import java.util.HashMap; -import java.util.Map; - -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.Block; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.basis.PedestalBlock; - -public class EndPedestal extends PedestalBlock { - - public EndPedestal(Block parent) { - super(parent); - } - - @Override - protected Map createTexturesMap() { - ResourceLocation blockId = Registry.BLOCK.getKey(parent); - String name = blockId.getPath(); - return new HashMap() { - private static final long serialVersionUID = 1L; - { - put("%mod%", BetterEnd.MOD_ID ); - put("%top%", name + "_polished"); - put("%base%", name + "_polished"); - put("%pillar%", name + "_pillar_side"); - put("%bottom%", name + "_polished"); - } - }; - } -} diff --git a/src/main/java/ru/betterend/blocks/EndPortalBlock.java b/src/main/java/ru/betterend/blocks/EndPortalBlock.java deleted file mode 100644 index 6d5ab346..00000000 --- a/src/main/java/ru/betterend/blocks/EndPortalBlock.java +++ /dev/null @@ -1,181 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Objects; -import java.util.Optional; -import java.util.Random; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.client.color.block.BlockColor; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Direction.Axis; -import net.minecraft.core.Direction.AxisDirection; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.NetherPortalBlock; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import net.minecraft.world.level.dimension.DimensionType; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IColorProvider; -import ru.bclib.interfaces.IRenderTyped; -import ru.betterend.interfaces.TeleportingEntity; -import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndPortals; -import ru.betterend.rituals.EternalRitual; - -public class EndPortalBlock extends NetherPortalBlock implements IRenderTyped, IColorProvider { - public static final IntegerProperty PORTAL = EndBlockProperties.PORTAL; - - public EndPortalBlock() { - super(FabricBlockSettings.copyOf(Blocks.NETHER_PORTAL).resistance(Blocks.BEDROCK.getExplosionResistance()).luminance(15)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - builder.add(PORTAL); - } - - @Override - @Environment(EnvType.CLIENT) - public void animateTick(BlockState state, Level world, BlockPos pos, Random random) { - if (random.nextInt(100) == 0) { - world.playLocalSound(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, SoundEvents.PORTAL_AMBIENT, SoundSource.BLOCKS, 0.5F, random.nextFloat() * 0.4F + 0.8F, false); - } - - double x = pos.getX() + random.nextDouble(); - double y = pos.getY() + random.nextDouble(); - double z = pos.getZ() + random.nextDouble(); - int k = random.nextInt(2) * 2 - 1; - if (!world.getBlockState(pos.west()).is(this) && !world.getBlockState(pos.east()).is(this)) { - x = pos.getX() + 0.5D + 0.25D * k; - } else { - z = pos.getZ() + 0.5D + 0.25D * k; - } - - world.addParticle(EndParticles.PORTAL_SPHERE, x, y, z, 0, 0, 0); - } - - @Override - public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) {} - - @Override - public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) { - return state; - } - - @Override - public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { - if (world.isClientSide || !validate(entity)) return; - entity.setPortalCooldown(); - ServerLevel currentWorld = (ServerLevel) world; - MinecraftServer server = currentWorld.getServer(); - ServerLevel targetWorld = EndPortals.getWorld(server, state.getValue(PORTAL)); - boolean isInEnd = currentWorld.dimension().equals(Level.END); - ServerLevel destination = isInEnd ? targetWorld : server.getLevel(Level.END); - BlockPos exitPos = findExitPos(currentWorld, destination, pos, entity); - if (exitPos == null) return; - if (entity instanceof ServerPlayer && ((ServerPlayer) entity).isCreative()) { - ((ServerPlayer) entity).teleportTo(destination, exitPos.getX() + 0.5, exitPos.getY(), - exitPos.getZ() + 0.5, entity.yRot, entity.xRot); - } else { - ((TeleportingEntity) entity).be_setExitPos(exitPos); - Optional teleported = Optional.ofNullable(entity.changeDimension(destination)); - teleported.ifPresent(Entity::setPortalCooldown); - } - } - - private boolean validate(Entity entity) { - return !entity.isPassenger() && !entity.isVehicle() && - entity.canChangeDimensions() && !entity.isOnPortalCooldown(); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.TRANSLUCENT; - } - - private BlockPos findExitPos(ServerLevel currentWorld, ServerLevel targetWorld, BlockPos currentPos, Entity entity) { - if (targetWorld == null) return null; - Registry registry = targetWorld.registryAccess().dimensionTypes(); - ResourceLocation targetWorldId = targetWorld.dimension().location(); - ResourceLocation currentWorldId = currentWorld.dimension().location(); - double targetMultiplier = Objects.requireNonNull(registry.get(targetWorldId)).coordinateScale(); - double currentMultiplier = Objects.requireNonNull(registry.get(currentWorldId)).coordinateScale(); - double multiplier = targetMultiplier > currentMultiplier ? 1.0 / targetMultiplier : currentMultiplier; - MutableBlockPos basePos = currentPos.mutable().set(currentPos.getX() * multiplier, currentPos.getY(), currentPos.getZ() * multiplier); - MutableBlockPos checkPos = basePos.mutable(); - BlockState currentState = currentWorld.getBlockState(currentPos); - int radius = (EternalRitual.SEARCH_RADIUS >> 4) + 1; - checkPos = EternalRitual.findBlockPos(targetWorld, checkPos, radius, this, state -> state.is(this) && - state.getValue(PORTAL).equals(currentState.getValue(PORTAL))); - if (checkPos != null) { - BlockState checkState = targetWorld.getBlockState(checkPos); - Axis axis = checkState.getValue(AXIS); - checkPos = findCenter(targetWorld, checkPos, axis); - Direction frontDir = Direction.fromAxisAndDirection(axis, AxisDirection.POSITIVE).getClockWise(); - Direction entityDir = entity.getMotionDirection(); - if (entityDir.getAxis().isVertical()) { - entityDir = frontDir; - } - if (frontDir != entityDir && frontDir.getOpposite() != entityDir) { - entity.rotate(Rotation.CLOCKWISE_90); - entityDir = entityDir.getClockWise(); - } - return checkPos.relative(entityDir); - } - return null; - } - - private MutableBlockPos findCenter(Level world, MutableBlockPos pos, Direction.Axis axis) { - return findCenter(world, pos, axis, 1); - } - - private MutableBlockPos findCenter(Level world, MutableBlockPos pos, Direction.Axis axis, int step) { - if (step > 8) return pos; - BlockState right, left; - Direction rightDir, leftDir; - rightDir = Direction.fromAxisAndDirection(axis, AxisDirection.POSITIVE); - leftDir = rightDir.getOpposite(); - right = world.getBlockState(pos.relative(rightDir)); - left = world.getBlockState(pos.relative(leftDir)); - BlockState down = world.getBlockState(pos.below()); - if (down.is(this)) { - return findCenter(world, pos.move(Direction.DOWN), axis, step); - } else if (right.is(this) && left.is(this)) { - return pos; - } else if (right.is(this)) { - return findCenter(world, pos.move(rightDir), axis, ++step); - } else if (left.is(this)) { - return findCenter(world, pos.move(leftDir), axis, ++step); - } - return pos; - } - - @Override - public BlockColor getProvider() { - return (state, world, pos, tintIndex) -> EndPortals.getColor(state.getValue(PORTAL)); - } - - @Override - public ItemColor getItemProvider() { - return (stack, tintIndex) -> EndPortals.getColor(0); - } -} diff --git a/src/main/java/ru/betterend/blocks/EndStoneSmelter.java b/src/main/java/ru/betterend/blocks/EndStoneSmelter.java deleted file mode 100644 index 46e17878..00000000 --- a/src/main/java/ru/betterend/blocks/EndStoneSmelter.java +++ /dev/null @@ -1,152 +0,0 @@ -package ru.betterend.blocks; - -import java.util.List; -import java.util.Random; - -import com.google.common.collect.Lists; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.HorizontalDirectionalBlock; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.RenderShape; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.material.MaterialColor; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import net.minecraft.world.phys.BlockHitResult; -import ru.bclib.blocks.BaseBlockWithEntity; -import ru.betterend.blocks.entities.EndStoneSmelterBlockEntity; - -public class EndStoneSmelter extends BaseBlockWithEntity { - public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING; - public static final BooleanProperty LIT = BlockStateProperties.LIT; - public static final String ID = "end_stone_smelter"; - - public EndStoneSmelter() { - super(FabricBlockSettings.of(Material.STONE, MaterialColor.COLOR_GRAY) - .hardness(4F) - .resistance(100F) - .requiresCorrectToolForDrops() - .sound(SoundType.STONE)); - this.registerDefaultState(this.stateDefinition.any() - .setValue(FACING, Direction.NORTH) - .setValue(LIT, false)); - } - - public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { - if (world.isClientSide) { - return InteractionResult.SUCCESS; - } else { - this.openScreen(world, pos, player); - return InteractionResult.CONSUME; - } - } - - private void openScreen(Level world, BlockPos pos, Player player) { - BlockEntity blockEntity = world.getBlockEntity(pos); - if (blockEntity instanceof EndStoneSmelterBlockEntity) { - player.openMenu((EndStoneSmelterBlockEntity) blockEntity); - } - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - return this.defaultBlockState().setValue(FACING, ctx.getHorizontalDirection().getOpposite()); - } - - @Override - public BlockEntity newBlockEntity(BlockGetter world) { - return new EndStoneSmelterBlockEntity(); - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - List drop = Lists.newArrayList(new ItemStack(this)); - BlockEntity blockEntity = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY); - if (blockEntity instanceof EndStoneSmelterBlockEntity) { - EndStoneSmelterBlockEntity smelterBlockEntity = (EndStoneSmelterBlockEntity) blockEntity; - for (int i = 0; i < smelterBlockEntity.getContainerSize(); i++) { - ItemStack item = smelterBlockEntity.getItem(i); - if (!item.isEmpty()) { - drop.add(item); - } - } - } - return drop; - } - - @Override - public boolean hasAnalogOutputSignal(BlockState state) { - return true; - } - - @Override - public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) { - //TODO - return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos)); - } - - @Override - public RenderShape getRenderShape(BlockState state) { - return RenderShape.MODEL; - } - - @Override - public BlockState rotate(BlockState state, Rotation rotation) { - return state.setValue(FACING, rotation.rotate(state.getValue(FACING))); - } - - @Override - public BlockState mirror(BlockState state, Mirror mirror) { - return state.rotate(mirror.getRotation(state.getValue(FACING))); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - builder.add(FACING, LIT); - } - - @Environment(EnvType.CLIENT) - public void animateTick(BlockState state, Level world, BlockPos pos, Random random) { - if (state.getValue(LIT)) { - double x = pos.getX() + 0.5D; - double y = pos.getY(); - double z = pos.getZ() + 0.5D; - if (random.nextDouble() < 0.1D) { - world.playLocalSound(x, y, z, SoundEvents.BLASTFURNACE_FIRE_CRACKLE, SoundSource.BLOCKS, 1.0F, 1.0F, false); - } - - Direction direction = state.getValue(FACING); - Direction.Axis axis = direction.getAxis(); - double defOffset = random.nextDouble() * 0.6D - 0.3D; - double offX = axis == Direction.Axis.X ? direction.getStepX() * 0.52D : defOffset; - double offY = random.nextDouble() * 9.0D / 16.0D; - double offZ = axis == Direction.Axis.Z ? direction.getStepZ() * 0.52D : defOffset; - world.addParticle(ParticleTypes.SMOKE, x + offX, y + offY, z + offZ, 0.0D, 0.0D, 0.0D); - } - } -} diff --git a/src/main/java/ru/betterend/blocks/EnderBlock.java b/src/main/java/ru/betterend/blocks/EnderBlock.java deleted file mode 100644 index 31469430..00000000 --- a/src/main/java/ru/betterend/blocks/EnderBlock.java +++ /dev/null @@ -1,28 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.blocks.BaseBlock; - -public class EnderBlock extends BaseBlock { - - public EnderBlock() { - super(FabricBlockSettings.of(Material.STONE, MaterialColor.WARPED_WART_BLOCK) - .hardness(5F) - .resistance(6F) - .requiresCorrectToolForDrops() - .sound(SoundType.STONE)); - } - - @Environment(EnvType.CLIENT) - public int getColor(BlockState state, BlockGetter world, BlockPos pos) { - return 0xFF005548; - } -} diff --git a/src/main/java/ru/betterend/blocks/EndstoneDustBlock.java b/src/main/java/ru/betterend/blocks/EndstoneDustBlock.java deleted file mode 100644 index 28ca0d6e..00000000 --- a/src/main/java/ru/betterend/blocks/EndstoneDustBlock.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.FallingBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.storage.loot.LootContext; -import ru.bclib.util.ColorUtil; - -public class EndstoneDustBlock extends FallingBlock { - @Environment(EnvType.CLIENT) - private static final int COLOR = ColorUtil.color(226, 239, 168); - - public EndstoneDustBlock() { - super(FabricBlockSettings.copyOf(Blocks.SAND) - .breakByTool(FabricToolTags.SHOVELS) - .materialColor(Blocks.END_STONE.defaultMaterialColor())); - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - return Collections.singletonList(new ItemStack(this)); - } - - @Environment(EnvType.CLIENT) - public int getDustColor(BlockState state, BlockGetter world, BlockPos pos) { - return COLOR; - } -} diff --git a/src/main/java/ru/betterend/blocks/EternalPedestal.java b/src/main/java/ru/betterend/blocks/EternalPedestal.java deleted file mode 100644 index e1b5404e..00000000 --- a/src/main/java/ru/betterend/blocks/EternalPedestal.java +++ /dev/null @@ -1,137 +0,0 @@ -package ru.betterend.blocks; - -import java.util.List; - -import com.google.common.collect.Lists; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Explosion; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import ru.betterend.blocks.basis.PedestalBlock; -import ru.betterend.blocks.entities.EternalPedestalEntity; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndPortals; -import ru.betterend.rituals.EternalRitual; - -public class EternalPedestal extends PedestalBlock { - public static final BooleanProperty ACTIVATED = EndBlockProperties.ACTIVE; - - public EternalPedestal() { - super(EndBlocks.FLAVOLITE_RUNED_ETERNAL); - this.registerDefaultState(defaultBlockState().setValue(ACTIVATED, false)); - } - - @Override - public void checkRitual(Level world, BlockPos pos) { - BlockEntity blockEntity = world.getBlockEntity(pos); - if (blockEntity instanceof EternalPedestalEntity) { - EternalPedestalEntity pedestal = (EternalPedestalEntity) blockEntity; - BlockState updatedState = world.getBlockState(pos); - if (pedestal.isEmpty()) { - if (pedestal.hasRitual()) { - EternalRitual ritual = pedestal.getRitual(); - if (ritual.isActive()) { - ResourceLocation targetWorld = ritual.getTargetWorldId(); - int portalId; - if (targetWorld != null) { - portalId = EndPortals.getPortalIdByWorld(targetWorld); - } else { - portalId = EndPortals.getPortalIdByWorld(EndPortals.OVERWORLD_ID); - } - ritual.disablePortal(portalId); - } - } - world.setBlockAndUpdate(pos, updatedState.setValue(ACTIVATED, false).setValue(HAS_LIGHT, false)); - } else { - ItemStack itemStack = pedestal.getItem(0); - ResourceLocation id = Registry.ITEM.getKey(itemStack.getItem()); - if (EndPortals.isAvailableItem(id)) { - world.setBlockAndUpdate(pos, updatedState.setValue(ACTIVATED, true).setValue(HAS_LIGHT, true)); - if (pedestal.hasRitual()) { - pedestal.getRitual().checkStructure(); - } else { - EternalRitual ritual = new EternalRitual(world, pos); - ritual.checkStructure(); - } - } - } - } - } - - @Override - @Deprecated - public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) { - BlockState updated = super.updateShape(state, direction, newState, world, pos, posFrom); - if (!updated.is(this)) return updated; - if (!this.isPlaceable(updated)) { - return updated.setValue(ACTIVATED, false); - } - return updated; - } - - @Override - @Deprecated - public float getDestroyProgress(BlockState state, Player player, BlockGetter world, BlockPos pos) { - return 0.0F; - } - - @Override - public float getExplosionResistance() { - return Blocks.BEDROCK.getExplosionResistance(); - } - - @Override - public boolean dropFromExplosion(Explosion explosion) { - return false; - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - if (state.is(this)) { - EndBlockProperties.PedestalState currentState = state.getValue(EndBlockProperties.PEDESTAL_STATE); - if (currentState.equals(EndBlockProperties.PedestalState.BOTTOM) || currentState.equals(EndBlockProperties.PedestalState.PILLAR)) { - return Lists.newArrayList(); - } - } - List drop = Lists.newArrayList(); - BlockEntity blockEntity = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY); - if (blockEntity instanceof EternalPedestalEntity) { - EternalPedestalEntity pedestal = (EternalPedestalEntity) blockEntity; - if (!pedestal.isEmpty()) { - drop.add(pedestal.getItem(0)); - } - } - return drop; - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - super.createBlockStateDefinition(stateManager); - stateManager.add(ACTIVATED); - } - - @Override - public BlockEntity newBlockEntity(BlockGetter world) { - return new EternalPedestalEntity(); - } - - @Override - public boolean hasUniqueEntity() { - return true; - } -} diff --git a/src/main/java/ru/betterend/blocks/FilaluxBlock.java b/src/main/java/ru/betterend/blocks/FilaluxBlock.java deleted file mode 100644 index 55d35214..00000000 --- a/src/main/java/ru/betterend/blocks/FilaluxBlock.java +++ /dev/null @@ -1,15 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.world.level.block.state.BlockBehaviour; -import ru.bclib.blocks.BaseVineBlock; - -public class FilaluxBlock extends BaseVineBlock { - public FilaluxBlock() { - super(15, true); - } - - @Override - public BlockBehaviour.OffsetType getOffsetType() { - return BlockBehaviour.OffsetType.NONE; - } -} diff --git a/src/main/java/ru/betterend/blocks/FilaluxLanternBlock.java b/src/main/java/ru/betterend/blocks/FilaluxLanternBlock.java deleted file mode 100644 index 658195b7..00000000 --- a/src/main/java/ru/betterend/blocks/FilaluxLanternBlock.java +++ /dev/null @@ -1,13 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.material.Material; -import ru.bclib.blocks.BaseBlock; - -public class FilaluxLanternBlock extends BaseBlock { - public FilaluxLanternBlock() { - super(FabricBlockSettings.of(Material.WOOD).breakByTool(FabricToolTags.AXES).luminance(15).sound(SoundType.WOOD)); - } -} diff --git a/src/main/java/ru/betterend/blocks/FilaluxWingsBlock.java b/src/main/java/ru/betterend/blocks/FilaluxWingsBlock.java deleted file mode 100644 index 7a3ef492..00000000 --- a/src/main/java/ru/betterend/blocks/FilaluxWingsBlock.java +++ /dev/null @@ -1,47 +0,0 @@ -package ru.betterend.blocks; - -import java.util.EnumMap; - -import com.google.common.collect.Maps; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BaseAttachedBlock; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; - -public class FilaluxWingsBlock extends BaseAttachedBlock implements IRenderTyped { - private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(Direction.class); - - public FilaluxWingsBlock() { - super(FabricBlockSettings.of(Material.PLANT).breakByTool(FabricToolTags.SHEARS).sound(SoundType.WET_GRASS).noCollission()); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return BOUNDING_SHAPES.get(state.getValue(FACING)); - } - - static { - BOUNDING_SHAPES.put(Direction.UP, Shapes.box(0.0, 0.0, 0.0, 1.0, 0.5, 1.0)); - BOUNDING_SHAPES.put(Direction.DOWN, Shapes.box(0.0, 0.5, 0.0, 1.0, 1.0, 1.0)); - BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.0, 0.0, 0.5, 1.0, 1.0, 1.0)); - BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 0.5)); - BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.5, 0.0, 0.0, 1.0, 1.0, 1.0)); - BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.0, 0.0, 0.5, 1.0, 1.0)); - } -} diff --git a/src/main/java/ru/betterend/blocks/FlamaeaBlock.java b/src/main/java/ru/betterend/blocks/FlamaeaBlock.java deleted file mode 100644 index bba1a69d..00000000 --- a/src/main/java/ru/betterend/blocks/FlamaeaBlock.java +++ /dev/null @@ -1,63 +0,0 @@ -package ru.betterend.blocks; - -import java.util.List; - -import com.google.common.collect.Lists; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.betterend.blocks.basis.EndPlantBlock; -import ru.betterend.interfaces.ISpetialItem; - -public class FlamaeaBlock extends EndPlantBlock implements ISpetialItem { - private static final VoxelShape SHAPE = Block.box(0, 0, 0, 16, 1, 16); - - public FlamaeaBlock() { - super(FabricBlockSettings.of(Material.PLANT) - .breakByTool(FabricToolTags.SHEARS) - .breakByHand(true) - .sound(SoundType.WET_GRASS)); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(Blocks.WATER); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return SHAPE; - } - - @Override - public BlockBehaviour.OffsetType getOffsetType() { - return BlockBehaviour.OffsetType.NONE; - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - return Lists.newArrayList(new ItemStack(this)); - } - - @Override - public int getStackSize() { - return 64; - } - - @Override - public boolean canPlaceOnWater() { - return true; - } -} diff --git a/src/main/java/ru/betterend/blocks/GlowingHymenophoreBlock.java b/src/main/java/ru/betterend/blocks/GlowingHymenophoreBlock.java deleted file mode 100644 index 699fc309..00000000 --- a/src/main/java/ru/betterend/blocks/GlowingHymenophoreBlock.java +++ /dev/null @@ -1,13 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.material.Material; -import ru.bclib.blocks.BaseBlock; - -public class GlowingHymenophoreBlock extends BaseBlock { - public GlowingHymenophoreBlock() { - super(FabricBlockSettings.of(Material.WOOD).breakByTool(FabricToolTags.AXES).luminance(15).sound(SoundType.WART_BLOCK)); - } -} diff --git a/src/main/java/ru/betterend/blocks/GlowingPillarLuminophorBlock.java b/src/main/java/ru/betterend/blocks/GlowingPillarLuminophorBlock.java deleted file mode 100644 index 1a3c6fe0..00000000 --- a/src/main/java/ru/betterend/blocks/GlowingPillarLuminophorBlock.java +++ /dev/null @@ -1,52 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.blocks.BaseBlock; -import ru.betterend.registry.EndBlocks; - -public class GlowingPillarLuminophorBlock extends BaseBlock { - public static final BooleanProperty NATURAL = EndBlockProperties.NATURAL; - - public GlowingPillarLuminophorBlock() { - super(FabricBlockSettings.of(Material.LEAVES) - .materialColor(MaterialColor.COLOR_ORANGE) - .breakByTool(FabricToolTags.SHEARS) - .strength(0.2F) - .luminance(15) - .sound(SoundType.GRASS)); - this.registerDefaultState(this.stateDefinition.any().setValue(NATURAL, false)); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - return !state.getValue(NATURAL) || world.getBlockState(pos.below()).is(EndBlocks.GLOWING_PILLAR_ROOTS); - } - - @Override - public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - if (!canSurvive(state, world, pos)) { - return Blocks.AIR.defaultBlockState(); - } - else { - return state; - } - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(NATURAL); - } -} diff --git a/src/main/java/ru/betterend/blocks/GlowingPillarRootsBlock.java b/src/main/java/ru/betterend/blocks/GlowingPillarRootsBlock.java deleted file mode 100644 index fe1f49ef..00000000 --- a/src/main/java/ru/betterend/blocks/GlowingPillarRootsBlock.java +++ /dev/null @@ -1,35 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.core.BlockPos; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.blocks.UpDownPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class GlowingPillarRootsBlock extends UpDownPlantBlock { - public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(SHAPE); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.AMBER_MOSS); - } - - @Override - @Environment(EnvType.CLIENT) - public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) { - return new ItemStack(EndBlocks.GLOWING_PILLAR_SEED); - } -} diff --git a/src/main/java/ru/betterend/blocks/GlowingPillarSeedBlock.java b/src/main/java/ru/betterend/blocks/GlowingPillarSeedBlock.java deleted file mode 100644 index fa20609d..00000000 --- a/src/main/java/ru/betterend/blocks/GlowingPillarSeedBlock.java +++ /dev/null @@ -1,75 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.material.Material; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.blocks.basis.EndPlantWithAgeBlock; -import ru.betterend.registry.EndBlocks; - -public class GlowingPillarSeedBlock extends EndPlantWithAgeBlock { - - public GlowingPillarSeedBlock() { - super(FabricBlockSettings.of(Material.PLANT) - .breakByTool(FabricToolTags.SHEARS) - .breakByHand(true) - .sound(SoundType.GRASS) - .lightLevel(state -> state.getValue(AGE) * 3 + 3) - .randomTicks() - .noCollission()); - } - - @Override - public void growAdult(WorldGenLevel world, Random random, BlockPos pos) { - int height = MHelper.randRange(1, 2, random); - int h = BlocksHelper.upRay(world, pos, height + 2); - if (h < height) { - return; - } - - MutableBlockPos mut = new MutableBlockPos().set(pos); - BlockState roots = EndBlocks.GLOWING_PILLAR_ROOTS.defaultBlockState(); - if (height < 2) { - BlocksHelper.setWithUpdate(world, mut, roots.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE)); - } else { - BlocksHelper.setWithUpdate(world, mut, roots.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM)); - mut.move(Direction.UP); - BlocksHelper.setWithUpdate(world, mut, roots.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP)); - } - mut.move(Direction.UP); - BlocksHelper.setWithUpdate(world, mut, EndBlocks.GLOWING_PILLAR_LUMINOPHOR.defaultBlockState().setValue(BlueVineLanternBlock.NATURAL, true)); - for (Direction dir: BlocksHelper.DIRECTIONS) { - pos = mut.relative(dir); - if (world.isEmptyBlock(pos)) { - BlocksHelper.setWithUpdate(world, pos, EndBlocks.GLOWING_PILLAR_LEAVES.defaultBlockState().setValue(BlockStateProperties.FACING, dir)); - } - } - mut.move(Direction.UP); - if (world.isEmptyBlock(mut)) { - BlocksHelper.setWithUpdate(world, mut, EndBlocks.GLOWING_PILLAR_LEAVES.defaultBlockState().setValue(BlockStateProperties.FACING, Direction.UP)); - } - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.AMBER_MOSS); - } - - @Override - public BlockBehaviour.OffsetType getOffsetType() { - return BlockBehaviour.OffsetType.NONE; - } -} diff --git a/src/main/java/ru/betterend/blocks/HelixTreeLeavesBlock.java b/src/main/java/ru/betterend/blocks/HelixTreeLeavesBlock.java deleted file mode 100644 index 625d503c..00000000 --- a/src/main/java/ru/betterend/blocks/HelixTreeLeavesBlock.java +++ /dev/null @@ -1,93 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; - -import com.google.common.collect.Lists; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.client.color.block.BlockColor; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.util.Mth; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.Enchantments; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.material.MaterialColor; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.interfaces.IColorProvider; -import ru.bclib.util.ColorUtil; -import ru.bclib.util.MHelper; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class HelixTreeLeavesBlock extends BaseBlock implements IColorProvider { - public static final IntegerProperty COLOR = EndBlockProperties.COLOR; - private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(0); - - public HelixTreeLeavesBlock() { - super(FabricBlockSettings.of(Material.LEAVES) - .materialColor(MaterialColor.COLOR_ORANGE) - .breakByTool(FabricToolTags.SHEARS) - .sound(SoundType.WART_BLOCK) - .sound(SoundType.GRASS) - .strength(0.2F)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(COLOR); - } - - @Override - public BlockColor getProvider() { - return (state, world, pos, tintIndex) -> { - return ColorUtil.color(237, getGreen(state.getValue(COLOR)), 20); - }; - } - - @Override - public ItemColor getItemProvider() { - return (stack, tintIndex) -> { - return ColorUtil.color(237, getGreen(4), 20); - }; - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - double px = ctx.getClickedPos().getX() * 0.1; - double py = ctx.getClickedPos().getY() * 0.1; - double pz = ctx.getClickedPos().getZ() * 0.1; - return this.defaultBlockState().setValue(COLOR, MHelper.floor(NOISE.eval(px, py, pz) * 3.5 + 4)); - } - - private int getGreen(int color) { - float delta = color / 7F; - return (int) Mth.lerp(delta, 80, 158); - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - ItemStack tool = builder.getParameter(LootContextParams.TOOL); - if (tool != null) { - if (tool.getItem().is(FabricToolTags.SHEARS) || tool.isCorrectToolForDrops(state) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) { - return Collections.singletonList(new ItemStack(this)); - } - int fortune = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, tool); - if (MHelper.RANDOM.nextInt(16) <= fortune) { - return Lists.newArrayList(new ItemStack(EndBlocks.HELIX_TREE_SAPLING)); - } - return Lists.newArrayList(); - } - return MHelper.RANDOM.nextInt(32) == 0 ? Lists.newArrayList(new ItemStack(EndBlocks.HELIX_TREE_SAPLING)) : Lists.newArrayList(); - } -} diff --git a/src/main/java/ru/betterend/blocks/HelixTreeSaplingBlock.java b/src/main/java/ru/betterend/blocks/HelixTreeSaplingBlock.java deleted file mode 100644 index 527cfd49..00000000 --- a/src/main/java/ru/betterend/blocks/HelixTreeSaplingBlock.java +++ /dev/null @@ -1,12 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.world.level.levelgen.feature.Feature; -import ru.bclib.blocks.FeatureSaplingBlock; -import ru.betterend.registry.EndFeatures; - -public class HelixTreeSaplingBlock extends FeatureSaplingBlock { - @Override - protected Feature getFeature() { - return EndFeatures.HELIX_TREE.getFeature(); - } -} diff --git a/src/main/java/ru/betterend/blocks/HydraluxBlock.java b/src/main/java/ru/betterend/blocks/HydraluxBlock.java deleted file mode 100644 index 9169bfaf..00000000 --- a/src/main/java/ru/betterend/blocks/HydraluxBlock.java +++ /dev/null @@ -1,97 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; -import java.util.Random; - -import com.google.common.collect.Lists; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.storage.loot.LootContext; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.UnderwaterPlantBlock; -import ru.bclib.util.MHelper; -import ru.betterend.blocks.EndBlockProperties.HydraluxShape; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class HydraluxBlock extends UnderwaterPlantBlock { - - public static final EnumProperty SHAPE = EndBlockProperties.HYDRALUX_SHAPE; - - public HydraluxBlock() { - super(FabricBlockSettings.of(Material.WATER_PLANT) - .breakByTool(FabricToolTags.SHEARS) - .breakByHand(true) - .sound(SoundType.WET_GRASS) - .lightLevel((state) -> state.getValue(SHAPE).hasGlow() ? 15 : 0) - .noCollission()); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(SHAPE); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - BlockState down = world.getBlockState(pos.below()); - HydraluxShape shape = state.getValue(SHAPE); - if (shape == HydraluxShape.FLOWER_BIG_TOP || shape == HydraluxShape.FLOWER_SMALL_TOP) { - return down.is(this); - } - else if (shape == HydraluxShape.ROOTS) { - return down.is(EndBlocks.SULPHURIC_ROCK.stone) && world.getBlockState(pos.above()).is(this); - } - else { - return down.is(this) && world.getBlockState(pos.above()).is(this); - } - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(TagAPI.END_GROUND); - } - - @Override - public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { - return false; - } - - @Override - public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) { - return false; - } - - @Override - @Environment(EnvType.CLIENT) - public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) { - return new ItemStack(EndBlocks.HYDRALUX_SAPLING); - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - HydraluxShape shape = state.getValue(SHAPE); - if (shape == HydraluxShape.FLOWER_BIG_BOTTOM || shape == HydraluxShape.FLOWER_SMALL_BOTTOM) { - return Lists.newArrayList(new ItemStack(EndItems.HYDRALUX_PETAL, MHelper.randRange(1, 4, MHelper.RANDOM))); - } - else if (shape == HydraluxShape.ROOTS) { - return Lists.newArrayList(new ItemStack(EndBlocks.HYDRALUX_SAPLING, MHelper.randRange(1, 2, MHelper.RANDOM))); - } - return Collections.emptyList(); - } -} diff --git a/src/main/java/ru/betterend/blocks/HydraluxPetalBlock.java b/src/main/java/ru/betterend/blocks/HydraluxPetalBlock.java deleted file mode 100644 index 5c82d09a..00000000 --- a/src/main/java/ru/betterend/blocks/HydraluxPetalBlock.java +++ /dev/null @@ -1,30 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.blocks.BaseBlock; - -public class HydraluxPetalBlock extends BaseBlock { - public HydraluxPetalBlock() { - this(FabricBlockSettings.of(Material.PLANT) - .breakByTool(FabricToolTags.AXES) - .breakByHand(true) - .hardness(1) - .resistance(1) - .materialColor(MaterialColor.PODZOL) - .sound(SoundType.WART_BLOCK)); - } - - public HydraluxPetalBlock(Properties settings) { - super(settings); - } - - @Override - public void fallOn(Level world, BlockPos pos, Entity entity, float distance) {} -} diff --git a/src/main/java/ru/betterend/blocks/HydraluxPetalColoredBlock.java b/src/main/java/ru/betterend/blocks/HydraluxPetalColoredBlock.java deleted file mode 100644 index f9a882b5..00000000 --- a/src/main/java/ru/betterend/blocks/HydraluxPetalColoredBlock.java +++ /dev/null @@ -1,39 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Optional; - -import org.jetbrains.annotations.Nullable; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.client.color.block.BlockColor; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.client.models.ModelsHelper; -import ru.bclib.interfaces.IColorProvider; -import ru.bclib.util.BlocksHelper; -import ru.betterend.client.models.Patterns; - -public class HydraluxPetalColoredBlock extends HydraluxPetalBlock implements IColorProvider { - public HydraluxPetalColoredBlock(FabricBlockSettings settings) { - super(settings); - } - - @Override - public BlockColor getProvider() { - return (state, world, pos, tintIndex) -> BlocksHelper.getBlockColor(this); - } - - @Override - public ItemColor getItemProvider() { - return (stack, tintIndex) -> BlocksHelper.getBlockColor(this); - } - - @Override - public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { - String path = "betterend:block/block_petal_colored"; - Optional pattern = Patterns.createJson(Patterns.BLOCK_PETAL_COLORED, path, path); - return ModelsHelper.fromPattern(pattern); - } -} diff --git a/src/main/java/ru/betterend/blocks/HydraluxSaplingBlock.java b/src/main/java/ru/betterend/blocks/HydraluxSaplingBlock.java deleted file mode 100644 index f3b11147..00000000 --- a/src/main/java/ru/betterend/blocks/HydraluxSaplingBlock.java +++ /dev/null @@ -1,50 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.UnderwaterPlantWithAgeBlock; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.blocks.EndBlockProperties.HydraluxShape; -import ru.betterend.registry.EndBlocks; - -public class HydraluxSaplingBlock extends UnderwaterPlantWithAgeBlock { - - @Override - public void grow(WorldGenLevel world, Random random, BlockPos pos) { - int h = MHelper.randRange(4, 8, random); - MutableBlockPos mut = new MutableBlockPos().set(pos); - - for (int i = 1; i < h; i++) { - mut.setY(pos.getY() + i); - if (!world.getBlockState(mut).is(Blocks.WATER)) { - return; - } - } - - mut.setY(pos.getY()); - BlockState state = EndBlocks.HYDRALUX.defaultBlockState(); - BlocksHelper.setWithoutUpdate(world, pos, state.setValue(EndBlockProperties.HYDRALUX_SHAPE, HydraluxShape.ROOTS)); - for (int i = 1; i < h - 2; i++) { - mut.setY(pos.getY() + i); - BlocksHelper.setWithoutUpdate(world, mut, state.setValue(EndBlockProperties.HYDRALUX_SHAPE, HydraluxShape.VINE)); - } - - mut.setY(mut.getY() + 1); - boolean big = random.nextBoolean(); - BlocksHelper.setWithoutUpdate(world, mut, state.setValue(EndBlockProperties.HYDRALUX_SHAPE, big ? HydraluxShape.FLOWER_BIG_BOTTOM : HydraluxShape.FLOWER_SMALL_BOTTOM)); - - mut.setY(mut.getY() + 1); - BlocksHelper.setWithoutUpdate(world, mut, state.setValue(EndBlockProperties.HYDRALUX_SHAPE, big ? HydraluxShape.FLOWER_BIG_TOP : HydraluxShape.FLOWER_SMALL_TOP)); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.SULPHURIC_ROCK.stone); - } -} diff --git a/src/main/java/ru/betterend/blocks/HydrothermalVentBlock.java b/src/main/java/ru/betterend/blocks/HydrothermalVentBlock.java deleted file mode 100644 index 806455f5..00000000 --- a/src/main/java/ru/betterend/blocks/HydrothermalVentBlock.java +++ /dev/null @@ -1,146 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import org.jetbrains.annotations.Nullable; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.LiquidBlockContainer; -import net.minecraft.world.level.block.SimpleWaterloggedBlock; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BaseBlockNotFull; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.util.BlocksHelper; -import ru.betterend.blocks.entities.BlockEntityHydrothermalVent; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndParticles; - -@SuppressWarnings("deprecation") -public class HydrothermalVentBlock extends BaseBlockNotFull implements EntityBlock, LiquidBlockContainer, SimpleWaterloggedBlock { - public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; - public static final BooleanProperty ACTIVATED = BlockProperties.ACTIVE; - private static final VoxelShape SHAPE = Block.box(1, 1, 1, 15, 16, 15); - - public HydrothermalVentBlock() { - super(FabricBlockSettings.of(Material.STONE) - .breakByTool(FabricToolTags.PICKAXES) - .sound(SoundType.STONE) - .noCollission() - .requiresCorrectToolForDrops()); - this.registerDefaultState(defaultBlockState().setValue(WATERLOGGED, true).setValue(ACTIVATED, false)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - builder.add(WATERLOGGED, ACTIVATED); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return SHAPE; - } - - @Override - public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { - return false; - } - - @Override - public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) { - return false; - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - state = world.getBlockState(pos.below()); - return state.is(EndBlocks.SULPHURIC_ROCK.stone); - } - - @Override - public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - if (!canSurvive(state, world, pos)) { - return Blocks.WATER.defaultBlockState(); - } - else if (state.getValue(WATERLOGGED) && facing == Direction.UP && neighborState.is(Blocks.WATER)) { - world.getBlockTicks().scheduleTick(pos, this, 20); - } - return state; - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - LevelAccessor worldAccess = ctx.getLevel(); - BlockPos blockPos = ctx.getClickedPos(); - return this.defaultBlockState().setValue(WATERLOGGED, worldAccess.getFluidState(blockPos).getType() == Fluids.WATER); - } - - @Override - public FluidState getFluidState(BlockState state) { - return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); - } - - @Override - public BlockEntity newBlockEntity(BlockGetter world) { - return new BlockEntityHydrothermalVent(); - } - - @Override - public void tick(BlockState state, ServerLevel world, BlockPos pos, Random random) { - BlockPos up = pos.above(); - if (world.getBlockState(up).is(Blocks.WATER)) { - BlocksHelper.setWithoutUpdate(world, up, EndBlocks.VENT_BUBBLE_COLUMN); - world.getBlockTicks().scheduleTick(up, EndBlocks.VENT_BUBBLE_COLUMN, 5); - } - } - - @Override - public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) { - if (world instanceof ServerLevel && state.getValue(WATERLOGGED) && world.getBlockState(pos.above()).is(Blocks.WATER)) { - tick(state,(ServerLevel) world, pos, world.random); - } - } - - @Environment(EnvType.CLIENT) - public void animateTick(BlockState state, Level world, BlockPos pos, Random random) { - if (!state.getValue(ACTIVATED) && random.nextBoolean()) { - super.animateTick(state, world, pos, random); - double x = pos.getX() + random.nextDouble(); - double y = pos.getY() + 0.9 + random.nextDouble() * 0.3; - double z = pos.getZ() + random.nextDouble(); - if (state.getValue(WATERLOGGED)) { - world.addParticle(EndParticles.GEYSER_PARTICLE, x, y, z, 0, 0, 0); - } - else { - world.addParticle(ParticleTypes.SMOKE, x, y, z, 0, 0, 0); - } - } - } -} diff --git a/src/main/java/ru/betterend/blocks/InfusionPedestal.java b/src/main/java/ru/betterend/blocks/InfusionPedestal.java deleted file mode 100644 index 2604055d..00000000 --- a/src/main/java/ru/betterend/blocks/InfusionPedestal.java +++ /dev/null @@ -1,88 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.betterend.blocks.basis.PedestalBlock; -import ru.betterend.blocks.entities.InfusionPedestalEntity; -import ru.betterend.rituals.InfusionRitual; - -@SuppressWarnings("deprecation") -public class InfusionPedestal extends PedestalBlock { - private static final VoxelShape SHAPE_DEFAULT; - private static final VoxelShape SHAPE_PEDESTAL_TOP; - - public InfusionPedestal() { - super(Blocks.OBSIDIAN); - this.height = 1.08F; - } - - @Override - public void checkRitual(Level world, BlockPos pos) { - BlockEntity blockEntity = world.getBlockEntity(pos); - if (blockEntity instanceof InfusionPedestalEntity) { - InfusionPedestalEntity pedestal = (InfusionPedestalEntity) blockEntity; - if (pedestal.hasRitual()) { - InfusionRitual ritual = pedestal.getRitual(); - if (!ritual.isValid()) { - ritual.configure(); - } - pedestal.getRitual().checkRecipe(); - } else { - InfusionRitual ritual = new InfusionRitual(pedestal, world, pos); - pedestal.linkRitual(ritual); - ritual.checkRecipe(); - } - } - } - - @Override - public BlockEntity newBlockEntity(BlockGetter world) { - return new InfusionPedestalEntity(); - } - - @Override - public boolean hasUniqueEntity() { - return true; - } - - @Override - @Deprecated - public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { - if (state.is(this)) { - switch(state.getValue(STATE)) { - case PEDESTAL_TOP: { - return SHAPE_PEDESTAL_TOP; - } - case DEFAULT: { - return SHAPE_DEFAULT; - } - default: { - return super.getShape(state, world, pos, context); - } - } - } - return super.getShape(state, world, pos, context); - } - - static { - VoxelShape basinUp = Block.box(2, 3, 2, 14, 4, 14); - VoxelShape basinDown = Block.box(0, 0, 0, 16, 3, 16); - VoxelShape pedestalTop = Block.box(1, 9, 1, 15, 11, 15); - VoxelShape pedestalDefault = Block.box(1, 13, 1, 15, 15, 15); - VoxelShape pillar = Block.box(3, 0, 3, 13, 9, 13); - VoxelShape pillarDefault = Block.box(3, 4, 3, 13, 13, 13); - VoxelShape eyeDefault = Block.box(4, 15, 4, 12, 16, 12); - VoxelShape eyeTop = Block.box(4, 11, 4, 12, 12, 12); - VoxelShape basin = Shapes.or(basinDown, basinUp); - SHAPE_DEFAULT = Shapes.or(basin, pillarDefault, pedestalDefault, eyeDefault); - SHAPE_PEDESTAL_TOP = Shapes.or(pillar, pedestalTop, eyeTop); - } -} diff --git a/src/main/java/ru/betterend/blocks/JellyshroomCapBlock.java b/src/main/java/ru/betterend/blocks/JellyshroomCapBlock.java deleted file mode 100644 index caf38d89..00000000 --- a/src/main/java/ru/betterend/blocks/JellyshroomCapBlock.java +++ /dev/null @@ -1,101 +0,0 @@ -package ru.betterend.blocks; - -import java.util.List; -import java.util.Optional; - -import org.jetbrains.annotations.Nullable; - -import com.google.common.collect.Lists; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.client.color.block.BlockColor; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.core.Vec3i; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Mth; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.SlimeBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import net.minecraft.world.level.storage.loot.LootContext; -import ru.bclib.client.models.BlockModelProvider; -import ru.bclib.client.models.ModelsHelper; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IColorProvider; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.ColorUtil; -import ru.bclib.util.MHelper; -import ru.betterend.client.models.Patterns; -import ru.betterend.noise.OpenSimplexNoise; - -public class JellyshroomCapBlock extends SlimeBlock implements IRenderTyped, BlockModelProvider, IColorProvider { - public static final IntegerProperty COLOR = EndBlockProperties.COLOR; - private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(0); - private final Vec3i colorStart; - private final Vec3i colorEnd; - private final int coloritem; - - public JellyshroomCapBlock(int r1, int g1, int b1, int r2, int g2, int b2) { - super(FabricBlockSettings.copyOf(Blocks.SLIME_BLOCK)); - colorStart = new Vec3i(r1, g1, b1); - colorEnd = new Vec3i(r2, g2, b2); - coloritem = ColorUtil.color((r1 + r2) >> 1, (g1 + g2) >> 1, (b1 + b2) >> 1); - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - double px = ctx.getClickedPos().getX() * 0.1; - double py = ctx.getClickedPos().getY() * 0.1; - double pz = ctx.getClickedPos().getZ() * 0.1; - return this.defaultBlockState().setValue(COLOR, MHelper.floor(NOISE.eval(px, py, pz) * 3.5 + 4)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(COLOR); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.TRANSLUCENT; - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - return Lists.newArrayList(new ItemStack(this)); - } - - @Override - public BlockModel getItemModel(ResourceLocation resourceLocation) { - return getBlockModel(resourceLocation, defaultBlockState()); - } - - @Override - public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { - Optional pattern = Patterns.createJson(Patterns.BLOCK_COLORED, "jellyshroom_cap"); - return ModelsHelper.fromPattern(pattern); - } - - @Override - public BlockColor getProvider() { - return (state, world, pos, tintIndex) -> { - float delta = (float) state.getValue(COLOR) / 7F; - int r = Mth.floor(Mth.lerp(delta, colorStart.getX() / 255F, colorEnd.getX() / 255F) * 255F); - int g = Mth.floor(Mth.lerp(delta, colorStart.getY() / 255F, colorEnd.getY() / 255F) * 255F); - int b = Mth.floor(Mth.lerp(delta, colorStart.getZ() / 255F, colorEnd.getZ() / 255F) * 255F); - return ColorUtil.color(r, g, b); - }; - } - - @Override - public ItemColor getItemProvider() { - return (stack, tintIndex) -> { - return coloritem; - }; - } -} diff --git a/src/main/java/ru/betterend/blocks/LacugroveSaplingBlock.java b/src/main/java/ru/betterend/blocks/LacugroveSaplingBlock.java deleted file mode 100644 index 5c2a678e..00000000 --- a/src/main/java/ru/betterend/blocks/LacugroveSaplingBlock.java +++ /dev/null @@ -1,25 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.feature.Feature; -import ru.bclib.blocks.FeatureSaplingBlock; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; - -public class LacugroveSaplingBlock extends FeatureSaplingBlock { - public LacugroveSaplingBlock() { - super(); - } - - @Override - protected Feature getFeature() { - return EndFeatures.LACUGROVE.getFeature(); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - return world.getBlockState(pos.below()).is(EndBlocks.END_MOSS) || world.getBlockState(pos.below()).is(EndBlocks.ENDSTONE_DUST); - } -} diff --git a/src/main/java/ru/betterend/blocks/LanceleafBlock.java b/src/main/java/ru/betterend/blocks/LanceleafBlock.java deleted file mode 100644 index a7e29890..00000000 --- a/src/main/java/ru/betterend/blocks/LanceleafBlock.java +++ /dev/null @@ -1,69 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import net.minecraft.world.level.storage.loot.LootContext; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.PentaShape; -import ru.bclib.util.MHelper; -import ru.betterend.blocks.basis.EndPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class LanceleafBlock extends EndPlantBlock { - - public static final EnumProperty SHAPE = BlockProperties.PENTA_SHAPE; - public static final IntegerProperty ROTATION = BlockProperties.ROTATION; - - public LanceleafBlock() { - super(); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(SHAPE, ROTATION); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - PentaShape shape = state.getValue(SHAPE); - if (shape == PentaShape.TOP) { - return world.getBlockState(pos.below()).is(this); - } - else if (shape == PentaShape.BOTTOM) { - return world.getBlockState(pos.below()).is(EndBlocks.AMBER_MOSS) && world.getBlockState(pos.above()).is(this); - } - else { - return world.getBlockState(pos.below()).is(this) && world.getBlockState(pos.above()).is(this); - } - } - - @Override - public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - if (!canSurvive(state, world, pos)) { - return Blocks.AIR.defaultBlockState(); - } - else { - return state; - } - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - if (state.getValue(SHAPE) == PentaShape.BOTTOM) { - return Collections.singletonList(new ItemStack(EndBlocks.LANCELEAF_SEED)); - } - return MHelper.RANDOM.nextBoolean() ? Collections.emptyList() : Collections.singletonList(new ItemStack(EndBlocks.LANCELEAF_SEED)); - } -} diff --git a/src/main/java/ru/betterend/blocks/LanceleafSeedBlock.java b/src/main/java/ru/betterend/blocks/LanceleafSeedBlock.java deleted file mode 100644 index 8c8455e9..00000000 --- a/src/main/java/ru/betterend/blocks/LanceleafSeedBlock.java +++ /dev/null @@ -1,47 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.PentaShape; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.blocks.basis.EndPlantWithAgeBlock; -import ru.betterend.registry.EndBlocks; - -public class LanceleafSeedBlock extends EndPlantWithAgeBlock { - @Override - public void growAdult(WorldGenLevel world, Random random, BlockPos pos) { - int height = MHelper.randRange(4, 6, random); - int h = BlocksHelper.upRay(world, pos, height + 2); - if (h < height + 1) { - return; - } - int rotation = random.nextInt(4); - MutableBlockPos mut = new MutableBlockPos().set(pos); - BlockState plant = EndBlocks.LANCELEAF.defaultBlockState().setValue(BlockProperties.ROTATION, rotation); - BlocksHelper.setWithoutUpdate(world, mut, plant.setValue(BlockProperties.PENTA_SHAPE, PentaShape.BOTTOM)); - BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), plant.setValue(BlockProperties.PENTA_SHAPE, PentaShape.PRE_BOTTOM)); - for (int i = 2; i < height - 2; i++) { - BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), plant.setValue(BlockProperties.PENTA_SHAPE, PentaShape.MIDDLE)); - } - BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), plant.setValue(BlockProperties.PENTA_SHAPE, PentaShape.PRE_TOP)); - BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), plant.setValue(BlockProperties.PENTA_SHAPE, PentaShape.TOP)); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.AMBER_MOSS); - } - - @Override - public BlockBehaviour.OffsetType getOffsetType() { - return BlockBehaviour.OffsetType.NONE; - } -} diff --git a/src/main/java/ru/betterend/blocks/LargeAmaranitaBlock.java b/src/main/java/ru/betterend/blocks/LargeAmaranitaBlock.java deleted file mode 100644 index d45f9de2..00000000 --- a/src/main/java/ru/betterend/blocks/LargeAmaranitaBlock.java +++ /dev/null @@ -1,81 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.betterend.blocks.basis.EndPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class LargeAmaranitaBlock extends EndPlantBlock { - public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; - private static final VoxelShape SHAPE_BOTTOM = Block.box(4, 0, 4, 12, 14, 12); - private static final VoxelShape SHAPE_TOP = Shapes.or(Block.box(1, 3, 1, 15, 16, 15), SHAPE_BOTTOM); - - public LargeAmaranitaBlock() { - super(FabricBlockSettings.of(Material.PLANT) - .breakByTool(FabricToolTags.SHEARS) - .breakByHand(true) - .sound(SoundType.GRASS) - .lightLevel((state) -> (state.getValue(SHAPE) == TripleShape.TOP) ? 15 : 0)); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return state.getValue(SHAPE) == TripleShape.TOP ? SHAPE_TOP : SHAPE_BOTTOM; - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.SANGNUM) || state.is(EndBlocks.MOSSY_OBSIDIAN) || state.is(EndBlocks.MOSSY_DRAGON_BONE); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(SHAPE); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - TripleShape shape = state.getValue(SHAPE); - if (shape == TripleShape.BOTTOM) { - return isTerrain(world.getBlockState(pos.below())) && world.getBlockState(pos.above()).is(this); - } - else if (shape == TripleShape.TOP) { - return world.getBlockState(pos.below()).is(this); - } - else { - return world.getBlockState(pos.below()).is(this) && world.getBlockState(pos.above()).is(this); - } - } - - @Override - public OffsetType getOffsetType() { - return OffsetType.NONE; - } - - @Override - public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { - return false; - } - - @Override - public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) { - return false; - } -} diff --git a/src/main/java/ru/betterend/blocks/LucerniaSaplingBlock.java b/src/main/java/ru/betterend/blocks/LucerniaSaplingBlock.java deleted file mode 100644 index 91ed218a..00000000 --- a/src/main/java/ru/betterend/blocks/LucerniaSaplingBlock.java +++ /dev/null @@ -1,25 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.feature.Feature; -import ru.bclib.blocks.FeatureSaplingBlock; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; - -public class LucerniaSaplingBlock extends FeatureSaplingBlock { - public LucerniaSaplingBlock() { - super(); - } - - @Override - protected Feature getFeature() { - return EndFeatures.LUCERNIA.getFeature(); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - return world.getBlockState(pos.below()).is(EndBlocks.RUTISCUS); - } -} diff --git a/src/main/java/ru/betterend/blocks/LumecornBlock.java b/src/main/java/ru/betterend/blocks/LumecornBlock.java deleted file mode 100644 index e0717bea..00000000 --- a/src/main/java/ru/betterend/blocks/LumecornBlock.java +++ /dev/null @@ -1,104 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BaseBlockNotFull; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.MHelper; -import ru.betterend.blocks.EndBlockProperties.LumecornShape; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -@SuppressWarnings("deprecation") -public class LumecornBlock extends BaseBlockNotFull implements IRenderTyped { - public static final EnumProperty SHAPE = EnumProperty.create("shape", LumecornShape.class); - private static final VoxelShape SHAPE_BOTTOM = Block.box(6, 0, 6, 10, 16, 10); - private static final VoxelShape SHAPE_TOP = Block.box(6, 0, 6, 10, 8, 10); - - public LumecornBlock() { - super(FabricBlockSettings.of(Material.WOOD) - .breakByTool(FabricToolTags.AXES) - .hardness(0.5F) - .luminance(state -> state.getValue(SHAPE).getLight())); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(SHAPE); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return state.getValue(SHAPE) == LumecornShape.LIGHT_TOP ? SHAPE_TOP : SHAPE_BOTTOM; - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - LumecornShape shape = state.getValue(SHAPE); - if (shape == LumecornShape.BOTTOM_BIG || shape == LumecornShape.BOTTOM_SMALL) { - return world.getBlockState(pos.below()).is(TagAPI.END_GROUND); - } - else if (shape == LumecornShape.LIGHT_TOP) { - return world.getBlockState(pos.below()).is(this); - } - else { - return world.getBlockState(pos.below()).is(this) && world.getBlockState(pos.above()).is(this); - } - } - - @Override - public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - if (!canSurvive(state, world, pos)) { - return Blocks.AIR.defaultBlockState(); - } - else { - return state; - } - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - LumecornShape shape = state.getValue(SHAPE); - if (shape == LumecornShape.BOTTOM_BIG || shape == LumecornShape.BOTTOM_SMALL || shape == LumecornShape.MIDDLE) { - return Collections.singletonList(new ItemStack(EndBlocks.LUMECORN_SEED, MHelper.randRange(1, 2, MHelper.RANDOM))); - } - return MHelper.RANDOM.nextBoolean() ? Collections.singletonList(new ItemStack(EndItems.LUMECORN_ROD)) : Collections.emptyList(); - } - - @Override - @Environment(EnvType.CLIENT) - public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) { - LumecornShape shape = state.getValue(SHAPE); - if (shape == LumecornShape.BOTTOM_BIG || shape == LumecornShape.BOTTOM_SMALL || shape == LumecornShape.MIDDLE) { - return new ItemStack(EndBlocks.LUMECORN_SEED); - } - return new ItemStack(EndItems.LUMECORN_ROD); - } -} diff --git a/src/main/java/ru/betterend/blocks/LumecornSeedBlock.java b/src/main/java/ru/betterend/blocks/LumecornSeedBlock.java deleted file mode 100644 index ed04a881..00000000 --- a/src/main/java/ru/betterend/blocks/LumecornSeedBlock.java +++ /dev/null @@ -1,29 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import ru.betterend.blocks.basis.EndPlantWithAgeBlock; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; - -public class LumecornSeedBlock extends EndPlantWithAgeBlock { - - @Override - public void growAdult(WorldGenLevel world, Random random, BlockPos pos) { - EndFeatures.LUMECORN.getFeature().place(world, null, random, pos, null); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.END_MOSS); - } - - @Override - public BlockBehaviour.OffsetType getOffsetType() { - return BlockBehaviour.OffsetType.NONE; - } -} diff --git a/src/main/java/ru/betterend/blocks/MengerSpongeBlock.java b/src/main/java/ru/betterend/blocks/MengerSpongeBlock.java deleted file mode 100644 index d644fcaf..00000000 --- a/src/main/java/ru/betterend/blocks/MengerSpongeBlock.java +++ /dev/null @@ -1,99 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Queue; - -import com.google.common.collect.Lists; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.tags.FluidTags; -import net.minecraft.util.Tuple; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.BucketPickup; -import net.minecraft.world.level.block.LiquidBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.material.Material; -import ru.bclib.blocks.BaseBlockNotFull; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.betterend.registry.EndBlocks; - -@SuppressWarnings("deprecation") -public class MengerSpongeBlock extends BaseBlockNotFull implements IRenderTyped { - public MengerSpongeBlock() { - super(FabricBlockSettings.copyOf(Blocks.SPONGE).noOcclusion()); - } - - @Override - public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { - if (absorbWater(world, pos)) { - world.setBlockAndUpdate(pos, EndBlocks.MENGER_SPONGE_WET.defaultBlockState()); - } - } - - @Override - public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - if (absorbWater(world, pos)) { - return EndBlocks.MENGER_SPONGE_WET.defaultBlockState(); - } - return state; - } - - private boolean absorbWater(LevelAccessor world, BlockPos pos) { - Queue> queue = Lists.newLinkedList(); - queue.add(new Tuple<>(pos, 0)); - int i = 0; - - while (!queue.isEmpty()) { - Tuple pair = queue.poll(); - BlockPos blockPos = pair.getA(); - int j = pair.getB(); - - for (Direction direction : Direction.values()) { - BlockPos blockPos2 = blockPos.relative(direction); - BlockState blockState = world.getBlockState(blockPos2); - FluidState fluidState = world.getFluidState(blockPos2); - Material material = blockState.getMaterial(); - if (fluidState.is(FluidTags.WATER)) { - if (blockState.getBlock() instanceof BucketPickup && ((BucketPickup) blockState.getBlock()).takeLiquid(world, blockPos2, blockState) != Fluids.EMPTY) { - ++i; - if (j < 6) { - queue.add(new Tuple<>(blockPos2, j + 1)); - } - } else if (blockState.getBlock() instanceof LiquidBlock) { - world.setBlock(blockPos2, Blocks.AIR.defaultBlockState(), 3); - ++i; - if (j < 6) { - queue.add(new Tuple<>(blockPos2, j + 1)); - } - } else if (material == Material.WATER_PLANT || material == Material.REPLACEABLE_WATER_PLANT) { - BlockEntity blockEntity = blockState.getBlock().isEntityBlock() ? world.getBlockEntity(blockPos2) : null; - dropResources(blockState, world, blockPos2, blockEntity); - world.setBlock(blockPos2, Blocks.AIR.defaultBlockState(), 3); - ++i; - if (j < 6) { - queue.add(new Tuple<>(blockPos2, j + 1)); - } - } - } - } - - if (i > 64) { - break; - } - } - - return i > 0; - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } -} diff --git a/src/main/java/ru/betterend/blocks/MengerSpongeWetBlock.java b/src/main/java/ru/betterend/blocks/MengerSpongeWetBlock.java deleted file mode 100644 index 0908d9f3..00000000 --- a/src/main/java/ru/betterend/blocks/MengerSpongeWetBlock.java +++ /dev/null @@ -1,107 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.GameRules; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import ru.bclib.blocks.BaseBlockNotFull; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.BlocksHelper; -import ru.betterend.registry.EndBlocks; - -@SuppressWarnings("deprecation") -public class MengerSpongeWetBlock extends BaseBlockNotFull implements IRenderTyped { - public MengerSpongeWetBlock() { - super(FabricBlockSettings.copyOf(Blocks.WET_SPONGE).noOcclusion()); - } - - @Override - public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { - if (world.dimensionType().ultraWarm()) { - world.setBlock(pos, EndBlocks.MENGER_SPONGE.defaultBlockState(), 3); - world.levelEvent(2009, pos, 0); - world.playSound(null, pos, SoundEvents.FIRE_EXTINGUISH, SoundSource.BLOCKS, 1.0F, (1.0F + world.getRandom().nextFloat() * 0.2F) * 0.7F); - } - } - - @Override - @Environment(EnvType.CLIENT) - public void animateTick(BlockState state, Level world, BlockPos pos, Random random) { - Direction direction = Direction.getRandom(random); - if (direction != Direction.UP) { - BlockPos blockPos = pos.relative(direction); - BlockState blockState = world.getBlockState(blockPos); - if (!state.canOcclude() || !blockState.isFaceSturdy(world, blockPos, direction.getOpposite())) { - double x = pos.getX(); - double y = pos.getY(); - double z = pos.getZ(); - if (direction == Direction.DOWN) { - y -= 0.05; - x += random.nextDouble(); - z += random.nextDouble(); - } - else { - y += random.nextDouble() * 0.8; - if (direction.getAxis() == Direction.Axis.X) { - z += random.nextDouble(); - if (direction == Direction.EAST) { - ++x; - } - else { - x += 0.05; - } - } - else { - x += random.nextDouble(); - if (direction == Direction.SOUTH) { - ++z; - } - else { - z += 0.05; - } - } - } - - world.addParticle(ParticleTypes.DRIPPING_WATER, x, y, z, 0, 0, 0); - } - } - } - - @Override - public void playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) { - BlocksHelper.setWithUpdate(world, pos, Blocks.AIR); - if (!world.isClientSide()) { - world.levelEvent(2001, pos, getId(state)); - } - if (world.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS) && (player == null || !player.isCreative())) { - ItemEntity drop = new ItemEntity(world, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, new ItemStack(this)); - world.addFreshEntity(drop); - } - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - @Override - public FluidState getFluidState(BlockState state) { - return Fluids.WATER.getSource(false); - } -} diff --git a/src/main/java/ru/betterend/blocks/MissingTileBlock.java b/src/main/java/ru/betterend/blocks/MissingTileBlock.java deleted file mode 100644 index 7a516557..00000000 --- a/src/main/java/ru/betterend/blocks/MissingTileBlock.java +++ /dev/null @@ -1,11 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.world.level.block.Blocks; -import ru.bclib.blocks.BaseBlock; - -public class MissingTileBlock extends BaseBlock { - public MissingTileBlock() { - super(FabricBlockSettings.copyOf(Blocks.END_STONE)); - } -} diff --git a/src/main/java/ru/betterend/blocks/MossyDragonBoneBlock.java b/src/main/java/ru/betterend/blocks/MossyDragonBoneBlock.java deleted file mode 100644 index b7d3e7e1..00000000 --- a/src/main/java/ru/betterend/blocks/MossyDragonBoneBlock.java +++ /dev/null @@ -1,59 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; -import java.util.Random; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.Enchantments; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.SnowLayerBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.lighting.LayerLightEngine; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import ru.bclib.blocks.BaseRotatedPillarBlock; -import ru.betterend.registry.EndBlocks; - -@SuppressWarnings("deprecation") -public class MossyDragonBoneBlock extends BaseRotatedPillarBlock { - public MossyDragonBoneBlock() { - super(FabricBlockSettings.copyOf(Blocks.BONE_BLOCK).hardness(0.5F).randomTicks()); - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - ItemStack tool = builder.getParameter(LootContextParams.TOOL); - if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) { - return Collections.singletonList(new ItemStack(this)); - } - return Collections.singletonList(new ItemStack(EndBlocks.DRAGON_BONE_BLOCK)); - } - - @Override - public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) { - if (random.nextInt(16) == 0 && !canSurvive(state, world, pos)) { - world.setBlockAndUpdate(pos, Blocks.BONE_BLOCK.defaultBlockState().setValue(AXIS, state.getValue(AXIS))); - } - } - - @Override - public boolean canSurvive(BlockState state, LevelReader worldView, BlockPos pos) { - BlockPos blockPos = pos.above(); - BlockState blockState = worldView.getBlockState(blockPos); - if (blockState.is(Blocks.SNOW) && blockState.getValue(SnowLayerBlock.LAYERS) == 1) { - return true; - } else if (blockState.getFluidState().getAmount() == 8) { - return false; - } else { - int i = LayerLightEngine.getLightBlockInto(worldView, state, pos, blockState, blockPos, Direction.UP, blockState.getLightBlock(worldView, blockPos)); - return i < 5; - } - } -} diff --git a/src/main/java/ru/betterend/blocks/MossyGlowshroomCapBlock.java b/src/main/java/ru/betterend/blocks/MossyGlowshroomCapBlock.java deleted file mode 100644 index 982d4cf6..00000000 --- a/src/main/java/ru/betterend/blocks/MossyGlowshroomCapBlock.java +++ /dev/null @@ -1,30 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.material.Material; -import ru.bclib.blocks.BaseBlock; -import ru.betterend.registry.EndBlocks; - -public class MossyGlowshroomCapBlock extends BaseBlock { - public static final BooleanProperty TRANSITION = EndBlockProperties.TRANSITION; - - public MossyGlowshroomCapBlock() { - super(FabricBlockSettings.of(Material.WOOD).breakByTool(FabricToolTags.AXES).sound(SoundType.WOOD)); - this.registerDefaultState(this.stateDefinition.any().setValue(TRANSITION, false)); - } - - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - return this.defaultBlockState().setValue(TRANSITION, EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(ctx.getLevel().getBlockState(ctx.getClickedPos().below()))); - } - - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - builder.add(TRANSITION); - } -} diff --git a/src/main/java/ru/betterend/blocks/MossyGlowshroomSaplingBlock.java b/src/main/java/ru/betterend/blocks/MossyGlowshroomSaplingBlock.java deleted file mode 100644 index da75416d..00000000 --- a/src/main/java/ru/betterend/blocks/MossyGlowshroomSaplingBlock.java +++ /dev/null @@ -1,26 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.feature.Feature; -import ru.bclib.blocks.FeatureSaplingBlock; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; - -public class MossyGlowshroomSaplingBlock extends FeatureSaplingBlock { - - public MossyGlowshroomSaplingBlock() { - super(7); - } - - @Override - protected Feature getFeature() { - return EndFeatures.MOSSY_GLOWSHROOM.getFeature(); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - return world.getBlockState(pos.below()).is(EndBlocks.END_MOSS) || world.getBlockState(pos.below()).is(EndBlocks.END_MYCELIUM); - } -} diff --git a/src/main/java/ru/betterend/blocks/MossyObsidian.java b/src/main/java/ru/betterend/blocks/MossyObsidian.java deleted file mode 100644 index d3423fdf..00000000 --- a/src/main/java/ru/betterend/blocks/MossyObsidian.java +++ /dev/null @@ -1,56 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; -import java.util.Random; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.Enchantments; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.SnowLayerBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.lighting.LayerLightEngine; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import ru.bclib.blocks.BaseBlock; - -public class MossyObsidian extends BaseBlock { - public MossyObsidian() { - super(FabricBlockSettings.copyOf(Blocks.OBSIDIAN).hardness(3).randomTicks()); - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - ItemStack tool = builder.getParameter(LootContextParams.TOOL); - if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) { - return Collections.singletonList(new ItemStack(this)); - } - return Collections.singletonList(new ItemStack(Blocks.OBSIDIAN)); - } - - @Override - public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) { - if (random.nextInt(16) == 0 && !canSurvive(state, world, pos)) { - world.setBlockAndUpdate(pos, Blocks.OBSIDIAN.defaultBlockState()); - } - } - - public boolean canSurvive(BlockState state, LevelReader worldView, BlockPos pos) { - BlockPos blockPos = pos.above(); - BlockState blockState = worldView.getBlockState(blockPos); - if (blockState.is(Blocks.SNOW) && (Integer)blockState.getValue(SnowLayerBlock.LAYERS) == 1) { - return true; - } else if (blockState.getFluidState().getAmount() == 8) { - return false; - } else { - int i = LayerLightEngine.getLightBlockInto(worldView, state, pos, blockState, blockPos, Direction.UP, blockState.getLightBlock(worldView, blockPos)); - return i < 5; - } - } -} diff --git a/src/main/java/ru/betterend/blocks/MurkweedBlock.java b/src/main/java/ru/betterend/blocks/MurkweedBlock.java deleted file mode 100644 index cd7ec961..00000000 --- a/src/main/java/ru/betterend/blocks/MurkweedBlock.java +++ /dev/null @@ -1,47 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.core.BlockPos; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.effect.MobEffects; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.pathfinder.PathComputationType; -import ru.betterend.blocks.basis.EndPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class MurkweedBlock extends EndPlantBlock { - @Override - @Environment(EnvType.CLIENT) - public void animateTick(BlockState state, Level world, BlockPos pos, Random random) { - double x = pos.getX() + random.nextDouble(); - double y = pos.getY() + random.nextDouble() * 0.5 + 0.5; - double z = pos.getZ() + random.nextDouble(); - double v = random.nextDouble() * 0.1; - world.addParticle(ParticleTypes.ENTITY_EFFECT, x, y, z, v, v, v); - } - - @Override - public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { - if (entity instanceof LivingEntity && !((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS)) { - ((LivingEntity) entity).addEffect(new MobEffectInstance(MobEffects.BLINDNESS, 50)); - } - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.SHADOW_GRASS); - } - - @Override - public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { - return false; - } -} diff --git a/src/main/java/ru/betterend/blocks/NeedlegrassBlock.java b/src/main/java/ru/betterend/blocks/NeedlegrassBlock.java deleted file mode 100644 index 57807754..00000000 --- a/src/main/java/ru/betterend/blocks/NeedlegrassBlock.java +++ /dev/null @@ -1,54 +0,0 @@ -package ru.betterend.blocks; - -import java.util.List; - -import com.google.common.collect.Lists; - -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.Enchantments; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.pathfinder.PathComputationType; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import ru.bclib.util.MHelper; -import ru.betterend.blocks.basis.EndPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class NeedlegrassBlock extends EndPlantBlock { - @Override - public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { - if (entity instanceof LivingEntity) { - entity.hurt(DamageSource.CACTUS, 0.1F); - } - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - ItemStack tool = builder.getParameter(LootContextParams.TOOL); - if (tool != null && tool.getItem().is(FabricToolTags.SHEARS) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) { - return Lists.newArrayList(new ItemStack(this)); - } - else { - return Lists.newArrayList(new ItemStack(Items.STICK, MHelper.randRange(0, 2, MHelper.RANDOM))); - } - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.SHADOW_GRASS); - } - - @Override - public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { - return false; - } -} diff --git a/src/main/java/ru/betterend/blocks/NeonCactusBlock.java b/src/main/java/ru/betterend/blocks/NeonCactusBlock.java deleted file mode 100644 index 2d1d9acd..00000000 --- a/src/main/java/ru/betterend/blocks/NeonCactusBlock.java +++ /dev/null @@ -1,11 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.world.level.block.Blocks; -import ru.bclib.blocks.BaseRotatedPillarBlock; - -public class NeonCactusBlock extends BaseRotatedPillarBlock { - public NeonCactusBlock() { - super(FabricBlockSettings.copyOf(Blocks.CACTUS).luminance(15)); - } -} diff --git a/src/main/java/ru/betterend/blocks/NeonCactusPlantBlock.java b/src/main/java/ru/betterend/blocks/NeonCactusPlantBlock.java deleted file mode 100644 index 568ea567..00000000 --- a/src/main/java/ru/betterend/blocks/NeonCactusPlantBlock.java +++ /dev/null @@ -1,399 +0,0 @@ -package ru.betterend.blocks; - -import java.util.EnumMap; -import java.util.List; -import java.util.Random; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Direction.Axis; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.SimpleWaterloggedBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.pathfinder.PathComputationType; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BaseBlockNotFull; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.blocks.EndBlockProperties.CactusBottom; -import ru.betterend.registry.EndBlocks; - -@SuppressWarnings("deprecation") -public class NeonCactusPlantBlock extends BaseBlockNotFull implements SimpleWaterloggedBlock, IRenderTyped { - public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; - public static final EnumProperty CACTUS_BOTTOM = EndBlockProperties.CACTUS_BOTTOM; - public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; - public static final DirectionProperty FACING = BlockStateProperties.FACING; - - private static final EnumMap BIG_SHAPES_OPEN = Maps.newEnumMap(Direction.class); - private static final EnumMap MEDIUM_SHAPES_OPEN = Maps.newEnumMap(Direction.class); - private static final EnumMap SMALL_SHAPES_OPEN = Maps.newEnumMap(Direction.class); - private static final EnumMap BIG_SHAPES = Maps.newEnumMap(Axis.class); - private static final EnumMap MEDIUM_SHAPES = Maps.newEnumMap(Axis.class); - private static final EnumMap SMALL_SHAPES = Maps.newEnumMap(Axis.class); - private static final int MAX_LENGTH = 12; - - public NeonCactusPlantBlock() { - super(FabricBlockSettings.copyOf(Blocks.CACTUS).luminance(15).randomTicks()); - registerDefaultState(defaultBlockState().setValue(WATERLOGGED, false).setValue(FACING, Direction.UP).setValue(SHAPE, TripleShape.TOP)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(SHAPE, CACTUS_BOTTOM, WATERLOGGED, FACING); - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - LevelAccessor world = ctx.getLevel(); - BlockPos pos = ctx.getClickedPos(); - Direction dir = ctx.getClickedFace(); - BlockState down = world.getBlockState(pos.relative(dir.getOpposite())); - BlockState state = this.defaultBlockState().setValue(WATERLOGGED, world.getFluidState(pos).getType() == Fluids.WATER).setValue(FACING, ctx.getClickedFace()); - if (down.is(Blocks.END_STONE) || down.is(EndBlocks.ENDSTONE_DUST)) { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.SAND); - } - else if (down.is(EndBlocks.END_MOSS)) { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.MOSS); - } - else { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.EMPTY); - } - return state; - } - - @Override - public BlockState rotate(BlockState state, Rotation rotation) { - return BlocksHelper.rotateHorizontal(state, rotation, FACING); - } - - @Override - public BlockState mirror(BlockState state, Mirror mirror) { - return BlocksHelper.mirrorHorizontal(state, mirror, FACING); - } - - @Override - public FluidState getFluidState(BlockState state) { - return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); - } - - @Override - public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) { - world.getBlockTicks().scheduleTick(pos, this, 2); - if (state.getValue(WATERLOGGED)) { - world.getLiquidTicks().scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); - } - Direction dir = state.getValue(FACING); - BlockState downState = world.getBlockState(pos.relative(dir.getOpposite())); - if (downState.is(Blocks.END_STONE) || downState.is(EndBlocks.ENDSTONE_DUST)) { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.SAND); - } - else if (downState.is(EndBlocks.END_MOSS)) { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.MOSS); - } - else { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.EMPTY); - } - return state; - } - - @Override - public void tick(BlockState blockState, ServerLevel serverLevel, BlockPos blockPos, Random random) { - if (!blockState.canSurvive(serverLevel, blockPos)) { - serverLevel.destroyBlock(blockPos, true, null, 1); - } - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - TripleShape shape = state.getValue(SHAPE); - Direction dir = state.getValue(FACING); - BlockState next = view.getBlockState(pos.relative(dir)); - if (next.is(this)) { - Axis axis = dir.getAxis(); - if (shape == TripleShape.BOTTOM) { - return BIG_SHAPES.get(axis); - } - return shape == TripleShape.MIDDLE ? MEDIUM_SHAPES.get(axis) : SMALL_SHAPES.get(axis); - } - else { - if (shape == TripleShape.BOTTOM) { - return BIG_SHAPES_OPEN.get(dir); - } - return shape == TripleShape.MIDDLE ? MEDIUM_SHAPES_OPEN.get(dir) : SMALL_SHAPES_OPEN.get(dir); - } - } - - @Override - public boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { - Direction dir = state.getValue(FACING); - BlockPos supportPos = pos.relative(dir.getOpposite()); - BlockState support = level.getBlockState(supportPos); - return support.is(this) || support.isFaceSturdy(level, supportPos, dir); - } - - @Override - public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) { - if (!this.canSurvive(state, world, pos) || random.nextInt(8) > 0) { - return; - } - Direction dir = state.getValue(FACING); - if (!world.isEmptyBlock(pos.relative(dir))) { - return; - } - int length = getLength(state, world, pos, MAX_LENGTH); - if (length < 0 || length > MAX_LENGTH - 1) { - return; - } - if (dir.getAxis().isHorizontal()) { - int horizontal = getHorizontal(state, world, pos, 2); - if (horizontal > random.nextInt(2)) { - dir = Direction.UP; - if (!world.getBlockState(pos.above()).isAir()) { - return; - } - } - } - else if (length > 1 && world.getBlockState(pos.relative(dir.getOpposite())).is(this)) { - Direction side = getSideDirection(world, pos, state, dir, random); - BlockPos sidePos = pos.relative(side); - if (world.isEmptyBlock(sidePos)) { - BlockState placement = state.setValue(SHAPE, TripleShape.TOP).setValue(CACTUS_BOTTOM, CactusBottom.EMPTY).setValue(WATERLOGGED, false).setValue(FACING, side); - BlocksHelper.setWithoutUpdate(world, sidePos, placement); - } - } - BlockState placement = state.setValue(SHAPE, TripleShape.TOP).setValue(CACTUS_BOTTOM, CactusBottom.EMPTY).setValue(WATERLOGGED, false).setValue(FACING, dir); - BlocksHelper.setWithoutUpdate(world, pos.relative(dir), placement); - mutateStem(placement, world, pos, MAX_LENGTH); - } - - public void growPlant(WorldGenLevel world, BlockPos pos, Random random) { - growPlant(world, pos, random, MHelper.randRange(MAX_LENGTH >> 1, MAX_LENGTH, random)); - } - - public void growPlant(WorldGenLevel world, BlockPos pos, Random random, int iterations) { - BlockState state = defaultBlockState(); - BlockState downState = world.getBlockState(pos.below()); - if (downState.is(Blocks.END_STONE) || downState.is(EndBlocks.ENDSTONE_DUST)) { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.SAND); - } - else if (downState.is(EndBlocks.END_MOSS)) { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.MOSS); - } - else { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.EMPTY); - } - BlocksHelper.setWithoutUpdate(world, pos, state); - List ends = Lists.newArrayList(pos.mutable()); - for (int i = 0; i < iterations; i++) { - int count = ends.size(); - for (int n = 0; n < count; n++) { - if (!growIteration(world, ends.get(n), random, ends, i)) { - ends.remove(n); - count--; - n--; - } - } - } - } - - private boolean growIteration(WorldGenLevel world, MutableBlockPos pos, Random random, List ends, int length) { - BlockState state = world.getBlockState(pos); - if (!state.is(this)) { - return false; - } - Direction dir = state.getValue(FACING); - if (!world.isEmptyBlock(pos.relative(dir))) { - return false; - } - if (dir.getAxis().isHorizontal()) { - int horizontal = getHorizontal(state, world, pos, 2); - if (horizontal > random.nextInt(2)) { - dir = Direction.UP; - if (!world.getBlockState(pos.above()).isAir()) { - return false; - } - } - } - else if (length > 1 && world.getBlockState(pos.below()).is(this)) { - Direction side = getSideDirection(world, pos, state, dir, random); - BlockPos sidePos = pos.relative(side); - if (world.isEmptyBlock(sidePos)) { - BlockState placement = state.setValue(SHAPE, TripleShape.TOP).setValue(CACTUS_BOTTOM, CactusBottom.EMPTY).setValue(WATERLOGGED, false).setValue(FACING, side); - BlocksHelper.setWithoutUpdate(world, sidePos, placement); - ends.add(sidePos.mutable()); - } - } - BlockState placement = state.setValue(SHAPE, TripleShape.TOP).setValue(CACTUS_BOTTOM, CactusBottom.EMPTY).setValue(WATERLOGGED, false).setValue(FACING, dir); - BlocksHelper.setWithoutUpdate(world, pos.relative(dir), placement); - mutateStem(placement, world, pos, MAX_LENGTH); - pos.move(dir); - return true; - } - - private Direction getSideDirection(WorldGenLevel world, BlockPos pos, BlockState iterState, Direction dir, Random random) { - MutableBlockPos iterPos = pos.mutable(); - Direction startDir = dir; - Direction lastDir = null; - while (iterState.is(this) && startDir.getAxis().isVertical()) { - startDir = iterState.getValue(FACING); - if (lastDir == null) { - for (Direction side: BlocksHelper.HORIZONTAL) { - BlockState sideState = world.getBlockState(iterPos.relative(side)); - if (sideState.is(this)) { - Direction sideDir = sideState.getValue(FACING); - if (sideDir != side) { - continue; - } - lastDir = sideDir; - } - } - } - iterPos.move(dir); - iterState = world.getBlockState(iterPos); - } - - Direction side = lastDir == null ? BlocksHelper.randomHorizontal(random) : lastDir.getClockWise(); - if (side.getOpposite() == startDir) { - side = side.getOpposite(); - } - return side; - } - - @Override - public boolean isPathfindable(BlockState blockState, BlockGetter blockGetter, BlockPos blockPos, PathComputationType pathComputationType) { - return false; - } - - @Override - public void entityInside(BlockState blockState, Level level, BlockPos blockPos, Entity entity) { - entity.hurt(DamageSource.CACTUS, 1.0F); - } - - private int getLength(BlockState state, ServerLevel world, BlockPos pos, int max) { - int length = 0; - Direction dir = state.getValue(FACING).getOpposite(); - MutableBlockPos mut = new MutableBlockPos().set(pos); - for (int i = 0; i < max; i++) { - mut.move(dir); - state = world.getBlockState(mut); - if (!state.is(this)) { - if (!state.is(TagAPI.END_GROUND)) { - length = -1; - } - break; - } - dir = state.getValue(FACING).getOpposite(); - length ++; - } - return length; - } - - private int getHorizontal(BlockState state, WorldGenLevel world, BlockPos pos, int max) { - int count = 0; - Direction dir = state.getValue(FACING).getOpposite(); - MutableBlockPos mut = new MutableBlockPos().set(pos); - for (int i = 0; i < max; i++) { - mut.move(dir); - state = world.getBlockState(mut); - if (!state.is(this)) { - break; - } - dir = state.getValue(FACING).getOpposite(); - if (dir.getStepY() != 0) { - break; - } - count ++; - } - return count; - } - - private void mutateStem(BlockState state, WorldGenLevel world, BlockPos pos, int max) { - Direction dir = state.getValue(FACING).getOpposite(); - MutableBlockPos mut = new MutableBlockPos().set(pos); - for (int i = 0; i < max; i++) { - mut.move(dir); - state = world.getBlockState(mut); - if (!state.is(this)) { - return; - } - int size = (i + 2) * 3 / max; - int src = state.getValue(SHAPE).getIndex(); - dir = state.getValue(FACING).getOpposite(); - if (src < size) { - TripleShape shape = TripleShape.fromIndex(size); - BlocksHelper.setWithoutUpdate(world, mut, state.setValue(SHAPE, shape)); - } - } - } - - static { - BIG_SHAPES.put(Axis.X, Block.box(0, 2, 2, 16, 14, 14)); - BIG_SHAPES.put(Axis.Y, Block.box(2, 0, 2, 14, 16, 14)); - BIG_SHAPES.put(Axis.Z, Block.box(2, 2, 0, 14, 14, 16)); - - MEDIUM_SHAPES.put(Axis.X, Block.box(0, 3, 3, 16, 13, 13)); - MEDIUM_SHAPES.put(Axis.Y, Block.box(3, 0, 3, 13, 16, 13)); - MEDIUM_SHAPES.put(Axis.Z, Block.box(3, 3, 0, 13, 13, 16)); - - SMALL_SHAPES.put(Axis.X, Block.box(0, 4, 4, 16, 12, 12)); - SMALL_SHAPES.put(Axis.Y, Block.box(4, 0, 4, 12, 16, 12)); - SMALL_SHAPES.put(Axis.Z, Block.box(4, 4, 0, 12, 12, 16)); - - BIG_SHAPES_OPEN.put(Direction.UP, Block.box(2, 0, 2, 14, 14, 14)); - BIG_SHAPES_OPEN.put(Direction.DOWN, Block.box(2, 2, 2, 14, 16, 14)); - BIG_SHAPES_OPEN.put(Direction.NORTH, Block.box(2, 2, 2, 14, 14, 16)); - BIG_SHAPES_OPEN.put(Direction.SOUTH, Block.box(2, 2, 0, 14, 14, 14)); - BIG_SHAPES_OPEN.put(Direction.WEST, Block.box(2, 2, 2, 16, 14, 14)); - BIG_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 2, 2, 14, 14, 14)); - - MEDIUM_SHAPES_OPEN.put(Direction.UP, Block.box(3, 0, 3, 13, 13, 13)); - MEDIUM_SHAPES_OPEN.put(Direction.DOWN, Block.box(3, 3, 3, 13, 16, 13)); - MEDIUM_SHAPES_OPEN.put(Direction.NORTH, Block.box(3, 3, 3, 13, 13, 16)); - MEDIUM_SHAPES_OPEN.put(Direction.SOUTH, Block.box(3, 3, 0, 13, 13, 13)); - MEDIUM_SHAPES_OPEN.put(Direction.WEST, Block.box(3, 3, 3, 16, 13, 13)); - MEDIUM_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 3, 3, 13, 13, 13)); - - SMALL_SHAPES_OPEN.put(Direction.UP, Block.box(4, 0, 4, 12, 12, 12)); - SMALL_SHAPES_OPEN.put(Direction.DOWN, Block.box(4, 4, 4, 12, 16, 12)); - SMALL_SHAPES_OPEN.put(Direction.NORTH, Block.box(4, 4, 4, 12, 12, 16)); - SMALL_SHAPES_OPEN.put(Direction.SOUTH, Block.box(4, 4, 0, 12, 12, 12)); - SMALL_SHAPES_OPEN.put(Direction.WEST, Block.box(4, 4, 4, 16, 12, 12)); - SMALL_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 4, 4, 12, 12, 12)); - } -} diff --git a/src/main/java/ru/betterend/blocks/PedestalVanilla.java b/src/main/java/ru/betterend/blocks/PedestalVanilla.java deleted file mode 100644 index 77eafd9d..00000000 --- a/src/main/java/ru/betterend/blocks/PedestalVanilla.java +++ /dev/null @@ -1,32 +0,0 @@ -package ru.betterend.blocks; - -import java.util.HashMap; -import java.util.Map; - -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.Block; -import ru.betterend.blocks.basis.PedestalBlock; - -public class PedestalVanilla extends PedestalBlock { - - public PedestalVanilla(Block parent) { - super(parent); - } - - @Override - protected Map createTexturesMap() { - ResourceLocation blockId = Registry.BLOCK.getKey(parent); - String name = blockId.getPath().replace("_block", ""); - return new HashMap() { - private static final long serialVersionUID = 1L; - { - put("%mod%", blockId.getNamespace() ); - put("%top%", "polished_" + name); - put("%base%", "polished_" + name); - put("%pillar%", name + "_pillar"); - put("%bottom%", "polished_" + name); - } - }; - } -} diff --git a/src/main/java/ru/betterend/blocks/PondAnemoneBlock.java b/src/main/java/ru/betterend/blocks/PondAnemoneBlock.java deleted file mode 100644 index 8a485ed2..00000000 --- a/src/main/java/ru/betterend/blocks/PondAnemoneBlock.java +++ /dev/null @@ -1,61 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.betterend.blocks.basis.EndUnderwaterPlantBlock; - -public class PondAnemoneBlock extends EndUnderwaterPlantBlock { - private static final VoxelShape SHAPE = Block.box(2, 0, 2, 14, 14, 14); - - public PondAnemoneBlock() { - super(FabricBlockSettings.of(Material.WATER_PLANT) - .breakByTool(FabricToolTags.SHEARS) - .breakByHand(true) - .luminance(13) - .sound(SoundType.CORAL_BLOCK) - .noCollission()); - } - - @Override - public BlockBehaviour.OffsetType getOffsetType() { - return BlockBehaviour.OffsetType.NONE; - } - - @Environment(EnvType.CLIENT) - public void animateTick(BlockState state, Level world, BlockPos pos, Random random) { - double x = pos.getX() + random.nextDouble(); - double y = pos.getY() + random.nextDouble() * 0.5F + 0.5F; - double z = pos.getZ() + random.nextDouble(); - world.addParticle(ParticleTypes.BUBBLE, x, y, z, 0.0D, 0.0D, 0.0D); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return SHAPE; - } - - @Override - public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { - return false; - } - - @Override - public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) { - return false; - } -} diff --git a/src/main/java/ru/betterend/blocks/PythadendronSaplingBlock.java b/src/main/java/ru/betterend/blocks/PythadendronSaplingBlock.java deleted file mode 100644 index 1f01907e..00000000 --- a/src/main/java/ru/betterend/blocks/PythadendronSaplingBlock.java +++ /dev/null @@ -1,25 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.feature.Feature; -import ru.bclib.blocks.FeatureSaplingBlock; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; - -public class PythadendronSaplingBlock extends FeatureSaplingBlock { - public PythadendronSaplingBlock() { - super(); - } - - @Override - protected Feature getFeature() { - return EndFeatures.PYTHADENDRON_TREE.getFeature(); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - return world.getBlockState(pos.below()).is(EndBlocks.CHORUS_NYLIUM); - } -} diff --git a/src/main/java/ru/betterend/blocks/RespawnObeliskBlock.java b/src/main/java/ru/betterend/blocks/RespawnObeliskBlock.java deleted file mode 100644 index 48b5e923..00000000 --- a/src/main/java/ru/betterend/blocks/RespawnObeliskBlock.java +++ /dev/null @@ -1,203 +0,0 @@ -package ru.betterend.blocks; - -import java.util.List; - -import org.jetbrains.annotations.Nullable; - -import com.google.common.collect.Lists; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.client.color.block.BlockColor; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IColorProvider; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.ColorUtil; -import ru.betterend.particle.InfusionParticleType; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class RespawnObeliskBlock extends BaseBlock implements IColorProvider, IRenderTyped { - private static final VoxelShape VOXEL_SHAPE_BOTTOM = Block.box(1, 0, 1, 15, 16, 15); - private static final VoxelShape VOXEL_SHAPE_MIDDLE_TOP = Block.box(2, 0, 2, 14, 16, 14); - - public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; - - public RespawnObeliskBlock() { - super(FabricBlockSettings.copyOf(Blocks.END_STONE).luminance((state) -> { - return (state.getValue(SHAPE) == TripleShape.BOTTOM) ? 0 : 15; - })); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return (state.getValue(SHAPE) == TripleShape.BOTTOM) ? VOXEL_SHAPE_BOTTOM : VOXEL_SHAPE_MIDDLE_TOP; - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(SHAPE); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - for (int i = 0; i < 3; i++) { - if (!world.getBlockState(pos.above(i)).getMaterial().isReplaceable()) { - return false; - } - } - return true; - } - - @Override - public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) { - state = this.defaultBlockState(); - BlocksHelper.setWithUpdate(world, pos, state.setValue(SHAPE, TripleShape.BOTTOM)); - BlocksHelper.setWithUpdate(world, pos.above(), state.setValue(SHAPE, TripleShape.MIDDLE)); - BlocksHelper.setWithUpdate(world, pos.above(2), state.setValue(SHAPE, TripleShape.TOP)); - } - - @Override - public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - TripleShape shape = state.getValue(SHAPE); - if (shape == TripleShape.BOTTOM) { - if (world.getBlockState(pos.above()).is(this)) { - return state; - } - else { - return Blocks.AIR.defaultBlockState(); - } - } - else if (shape == TripleShape.MIDDLE) { - if (world.getBlockState(pos.above()).is(this) && world.getBlockState(pos.below()).is(this)) { - return state; - } - else { - return Blocks.AIR.defaultBlockState(); - } - } - else { - if (world.getBlockState(pos.below()).is(this)) { - return state; - } - else { - return Blocks.AIR.defaultBlockState(); - } - } - } - - @Override - public void playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) { - if (player.isCreative()) { - TripleShape shape = state.getValue(SHAPE); - if (shape == TripleShape.MIDDLE) { - BlocksHelper.setWithUpdate(world, pos.below(), Blocks.AIR); - } - else if (shape == TripleShape.TOP) { - BlocksHelper.setWithUpdate(world, pos.below(2), Blocks.AIR); - } - } - super.playerWillDestroy(world, pos, state, player); - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - if (state.getValue(SHAPE) == TripleShape.BOTTOM) { - return Lists.newArrayList(new ItemStack(this)); - } - else { - return Lists.newArrayList(); - } - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.TRANSLUCENT; - } - - @Override - public BlockColor getProvider() { - return ((IColorProvider) EndBlocks.AURORA_CRYSTAL).getProvider(); - } - - @Override - public ItemColor getItemProvider() { - return (stack, tintIndex) -> { - return ColorUtil.color(255, 255, 255); - }; - } - - @Override - public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { - ItemStack itemStack = player.getItemInHand(hand); - boolean canActivate = itemStack.getItem() == EndItems.AMBER_GEM && itemStack.getCount() > 5; - if (hand != InteractionHand.MAIN_HAND || !canActivate) { - if (!world.isClientSide && !(itemStack.getItem() instanceof BlockItem) && !player.isCreative()) { - ServerPlayer serverPlayerEntity = (ServerPlayer) player; - serverPlayerEntity.displayClientMessage(new TranslatableComponent("message.betterend.fail_spawn"), true); - } - return InteractionResult.FAIL; - } - else if (!world.isClientSide) { - ServerPlayer serverPlayerEntity = (ServerPlayer) player; - serverPlayerEntity.setRespawnPosition(world.dimension(), pos, 0.0F, false, false); - serverPlayerEntity.displayClientMessage(new TranslatableComponent("message.betterend.set_spawn"), true); - double px = pos.getX() + 0.5; - double py = pos.getY() + 0.5; - double pz = pos.getZ() + 0.5; - InfusionParticleType particle = new InfusionParticleType(new ItemStack(EndItems.AMBER_GEM)); - if (world instanceof ServerLevel) { - double py1 = py; - double py2 = py - 0.2; - if (state.getValue(SHAPE) == TripleShape.BOTTOM) { - py1 += 1; - py2 += 2; - } - else if (state.getValue(SHAPE) == TripleShape.MIDDLE) { - py1 += 0; - py2 += 1; - } - else { - py1 -= 2; - } - ((ServerLevel) world).sendParticles(particle, px, py1, pz, 20, 0.14, 0.5, 0.14, 0.1); - ((ServerLevel) world).sendParticles(particle, px, py2, pz, 20, 0.14, 0.3, 0.14, 0.1); - } - world.playSound(null, px, py, py, SoundEvents.RESPAWN_ANCHOR_SET_SPAWN, SoundSource.BLOCKS, 1F, 1F); - if (!player.isCreative()) { - itemStack.shrink(6); - } - } - return player.isCreative() ? InteractionResult.PASS : InteractionResult.sidedSuccess(world.isClientSide); - } -} diff --git a/src/main/java/ru/betterend/blocks/RunedFlavolite.java b/src/main/java/ru/betterend/blocks/RunedFlavolite.java deleted file mode 100644 index 9cae1cea..00000000 --- a/src/main/java/ru/betterend/blocks/RunedFlavolite.java +++ /dev/null @@ -1,52 +0,0 @@ -package ru.betterend.blocks; - -import java.util.List; - -import com.google.common.collect.Lists; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Explosion; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.storage.loot.LootContext; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.util.BlocksHelper; -import ru.betterend.registry.EndBlocks; - -public class RunedFlavolite extends BaseBlock { - public static final BooleanProperty ACTIVATED = BlockProperties.ACTIVE; - - public RunedFlavolite(boolean unbreakable) { - super(FabricBlockSettings.copyOf(EndBlocks.FLAVOLITE.polished) - .strength( - unbreakable ? -1 : 1, - unbreakable ? Blocks.BEDROCK.getExplosionResistance() : Blocks.OBSIDIAN.getExplosionResistance() - ).luminance(state -> { - return state.getValue(ACTIVATED) ? 8 : 0; - })); - this.registerDefaultState(stateDefinition.any().setValue(ACTIVATED, false)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(ACTIVATED); - } - - @Override - public boolean dropFromExplosion(Explosion explosion) { - return !BlocksHelper.isInvulnerableUnsafe(this.defaultBlockState()); - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - if (BlocksHelper.isInvulnerableUnsafe(this.defaultBlockState())) { - return Lists.newArrayList(); - } - return super.getDrops(state, builder); - } -} diff --git a/src/main/java/ru/betterend/blocks/ShadowBerryBlock.java b/src/main/java/ru/betterend/blocks/ShadowBerryBlock.java deleted file mode 100644 index 997a8f85..00000000 --- a/src/main/java/ru/betterend/blocks/ShadowBerryBlock.java +++ /dev/null @@ -1,24 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BaseCropBlock; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class ShadowBerryBlock extends BaseCropBlock { - private static final VoxelShape SHAPE = Block.box(1, 0, 1, 15, 8, 15); - - public ShadowBerryBlock() { - super(EndItems.SHADOW_BERRY_RAW, EndBlocks.SHADOW_GRASS); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return SHAPE; - } -} diff --git a/src/main/java/ru/betterend/blocks/ShadowGrassBlock.java b/src/main/java/ru/betterend/blocks/ShadowGrassBlock.java deleted file mode 100644 index 99740b04..00000000 --- a/src/main/java/ru/betterend/blocks/ShadowGrassBlock.java +++ /dev/null @@ -1,26 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.MaterialColor; -import ru.betterend.blocks.basis.EndTerrainBlock; -import ru.betterend.registry.EndParticles; - -public class ShadowGrassBlock extends EndTerrainBlock { - public ShadowGrassBlock() { - super(MaterialColor.COLOR_BLACK); - } - - @Environment(EnvType.CLIENT) - public void animateTick(BlockState state, Level world, BlockPos pos, Random random) { - super.animateTick(state, world, pos, random); - if (random.nextInt(32) == 0) { - world.addParticle(EndParticles.BLACK_SPORE, (double) pos.getX() + random.nextDouble(), (double) pos.getY() + 1.1D, (double) pos.getZ() + random.nextDouble(), 0.0D, 0.0D, 0.0D); - } - } -} diff --git a/src/main/java/ru/betterend/blocks/SilkMothHiveBlock.java b/src/main/java/ru/betterend/blocks/SilkMothHiveBlock.java deleted file mode 100644 index a769f1a3..00000000 --- a/src/main/java/ru/betterend/blocks/SilkMothHiveBlock.java +++ /dev/null @@ -1,114 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.Vec3; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.entity.SilkMothEntity; -import ru.betterend.registry.EndEntities; -import ru.betterend.registry.EndItems; - -public class SilkMothHiveBlock extends BaseBlock { - public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; - public static final IntegerProperty FULLNESS = EndBlockProperties.FULLNESS; - - public SilkMothHiveBlock() { - super(FabricBlockSettings.of(Material.WOOD).breakByHand(true).hardness(0.5F).resistance(0.1F).sound(SoundType.WOOL).noOcclusion().randomTicks()); - this.registerDefaultState(defaultBlockState().setValue(FULLNESS, 0)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(FACING, FULLNESS); - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - Direction dir = ctx.getHorizontalDirection().getOpposite(); - return this.defaultBlockState().setValue(FACING, dir); - } - - @Override - public BlockState rotate(BlockState state, Rotation rotation) { - return BlocksHelper.rotateHorizontal(state, rotation, FACING); - } - - @Override - public BlockState mirror(BlockState state, Mirror mirror) { - return BlocksHelper.mirrorHorizontal(state, mirror, FACING); - } - - @Override - public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) { - Direction dir = state.getValue(FACING); - BlockPos spawn = pos.relative(dir); - if (!world.getBlockState(spawn).isAir()) { - return; - } - int count = world.getEntities(EndEntities.SILK_MOTH, new AABB(pos).inflate(16), (entity) -> { return true; }).size(); - if (count > 6) { - return; - } - SilkMothEntity moth = new SilkMothEntity(EndEntities.SILK_MOTH, world); - moth.moveTo(spawn.getX() + 0.5, spawn.getY() + 0.5, spawn.getZ() + 0.5, dir.toYRot(), 0); - moth.setDeltaMovement(new Vec3(dir.getStepX() * 0.4, 0, dir.getStepZ() * 0.4)); - moth.setHive(world, pos); - world.addFreshEntity(moth); - world.playSound(null, pos, SoundEvents.BEEHIVE_EXIT, SoundSource.BLOCKS, 1, 1); - } - - @Override - public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { - if (hand == InteractionHand.MAIN_HAND) { - ItemStack stack = player.getMainHandItem(); - if (stack.getItem().is(FabricToolTags.SHEARS) && state.getValue(FULLNESS) == 3) { - BlocksHelper.setWithUpdate(world, pos, state.setValue(FULLNESS, 0)); - Direction dir = state.getValue(FACING); - double px = pos.getX() + dir.getStepX() + 0.5; - double py = pos.getY() + dir.getStepY() + 0.5; - double pz = pos.getZ() + dir.getStepZ() + 0.5; - ItemStack drop = new ItemStack(EndItems.SILK_FIBER, MHelper.randRange(8, 16, world.getRandom())); - ItemEntity entity = new ItemEntity(world, px, py, pz, drop); - world.addFreshEntity(entity); - if (world.getRandom().nextInt(4) == 0) { - drop = new ItemStack(EndItems.SILK_MOTH_MATRIX); - entity = new ItemEntity(world, px, py, pz, drop); - world.addFreshEntity(entity); - } - if (!player.isCreative()) { - stack.setDamageValue(stack.getDamageValue() + 1); - } - return InteractionResult.SUCCESS; - } - } - return InteractionResult.FAIL; - } -} diff --git a/src/main/java/ru/betterend/blocks/SilkMothNestBlock.java b/src/main/java/ru/betterend/blocks/SilkMothNestBlock.java deleted file mode 100644 index 2d13649d..00000000 --- a/src/main/java/ru/betterend/blocks/SilkMothNestBlock.java +++ /dev/null @@ -1,173 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; -import java.util.Random; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.tags.BlockTags; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.Vec3; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.entity.SilkMothEntity; -import ru.betterend.registry.EndEntities; -import ru.betterend.registry.EndItems; - -public class SilkMothNestBlock extends BaseBlock implements IRenderTyped { - public static final BooleanProperty ACTIVE = EndBlockProperties.ACTIVE; - public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; - public static final IntegerProperty FULLNESS = EndBlockProperties.FULLNESS; - private static final VoxelShape TOP = box(6, 0, 6, 10, 16, 10); - private static final VoxelShape BOTTOM = box(0, 0, 0, 16, 16, 16); - - public SilkMothNestBlock() { - super(FabricBlockSettings.of(Material.WOOL).hardness(0.5F).resistance(0.1F).sound(SoundType.WOOL).noOcclusion().randomTicks()); - this.registerDefaultState(defaultBlockState().setValue(ACTIVE, true).setValue(FULLNESS, 0)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(ACTIVE, FACING, FULLNESS); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return state.getValue(ACTIVE) ? BOTTOM : TOP; - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - Direction dir = ctx.getHorizontalDirection().getOpposite(); - return this.defaultBlockState().setValue(FACING, dir); - } - - @Override - public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - if (!state.getValue(ACTIVE)) { - if (canSupportCenter(world, pos.above(), Direction.DOWN) || world.getBlockState(pos.above()).is(BlockTags.LEAVES)) { - return state; - } - else { - return Blocks.AIR.defaultBlockState(); - } - } - return state; - } - - @Override - public BlockState rotate(BlockState state, Rotation rotation) { - return BlocksHelper.rotateHorizontal(state, rotation, FACING); - } - - @Override - public BlockState mirror(BlockState state, Mirror mirror) { - return BlocksHelper.mirrorHorizontal(state, mirror, FACING); - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - return state.getValue(ACTIVE) ? Collections.singletonList(new ItemStack(this)) : Collections.emptyList(); - } - - @Override - public void playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) { - if (!state.getValue(ACTIVE) && player.isCreative()) { - BlocksHelper.setWithUpdate(world, pos.below(), Blocks.AIR); - } - BlockState up = world.getBlockState(pos.above()); - if (up.is(this) && !up.getValue(ACTIVE)) { - BlocksHelper.setWithUpdate(world, pos.above(), Blocks.AIR); - } - super.playerWillDestroy(world, pos, state, player); - } - - @Override - public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) { - if (!state.getValue(ACTIVE)) { - return; - } - if (random.nextBoolean()) { - return; - } - Direction dir = state.getValue(FACING); - BlockPos spawn = pos.relative(dir); - if (!world.getBlockState(spawn).isAir()) { - return; - } - int count = world.getEntities(EndEntities.SILK_MOTH, new AABB(pos).inflate(16), (entity) -> { return true; }).size(); - if (count > 6) { - return; - } - SilkMothEntity moth = new SilkMothEntity(EndEntities.SILK_MOTH, world); - moth.moveTo(spawn.getX() + 0.5, spawn.getY() + 0.5, spawn.getZ() + 0.5, dir.toYRot(), 0); - moth.setDeltaMovement(new Vec3(dir.getStepX() * 0.4, 0, dir.getStepZ() * 0.4)); - moth.setHive(world, pos); - world.addFreshEntity(moth); - world.playSound(null, pos, SoundEvents.BEEHIVE_EXIT, SoundSource.BLOCKS, 1, 1); - } - - @Override - public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { - if (hand == InteractionHand.MAIN_HAND) { - ItemStack stack = player.getMainHandItem(); - if (stack.getItem().is(FabricToolTags.SHEARS) && state.getValue(ACTIVE) && state.getValue(FULLNESS) == 3) { - BlocksHelper.setWithUpdate(world, pos, state.setValue(FULLNESS, 0)); - Direction dir = state.getValue(FACING); - double px = pos.getX() + dir.getStepX() + 0.5; - double py = pos.getY() + dir.getStepY() + 0.5; - double pz = pos.getZ() + dir.getStepZ() + 0.5; - ItemStack drop = new ItemStack(EndItems.SILK_FIBER, MHelper.randRange(1, 4, world.getRandom())); - ItemEntity entity = new ItemEntity(world, px, py, pz, drop); - world.addFreshEntity(entity); - drop = new ItemStack(EndItems.SILK_MOTH_MATRIX, MHelper.randRange(1, 3, world.getRandom())); - entity = new ItemEntity(world, px, py, pz, drop); - world.addFreshEntity(entity); - if (!player.isCreative()) { - stack.setDamageValue(stack.getDamageValue() + 1); - } - return InteractionResult.SUCCESS; - } - } - return InteractionResult.FAIL; - } -} diff --git a/src/main/java/ru/betterend/blocks/SmallAmaranitaBlock.java b/src/main/java/ru/betterend/blocks/SmallAmaranitaBlock.java deleted file mode 100644 index 2bc6059b..00000000 --- a/src/main/java/ru/betterend/blocks/SmallAmaranitaBlock.java +++ /dev/null @@ -1,78 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.Vec3; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.util.BlocksHelper; -import ru.betterend.blocks.basis.EndPlantBlock; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; - -public class SmallAmaranitaBlock extends EndPlantBlock { - private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 10, 12); - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.SANGNUM) || state.is(EndBlocks.MOSSY_OBSIDIAN) || state.is(EndBlocks.MOSSY_DRAGON_BONE); - } - - @Override - public void performBonemeal(ServerLevel world, Random random, BlockPos pos, BlockState state) { - BlockPos bigPos = growBig(world, pos); - if (bigPos != null) { - if (EndFeatures.GIGANTIC_AMARANITA.getFeature().place(world, null, random, bigPos, null)) { - replaceMushroom(world, bigPos); - replaceMushroom(world, bigPos.south()); - replaceMushroom(world, bigPos.east()); - replaceMushroom(world, bigPos.south().east()); - } - return; - } - EndFeatures.LARGE_AMARANITA.getFeature().place(world, null, random, pos, null); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - Vec3 vec3d = state.getOffset(view, pos); - return SHAPE.move(vec3d.x, vec3d.y, vec3d.z); - } - - private BlockPos growBig(ServerLevel world, BlockPos pos) { - for (int x = -1; x < 2; x++) { - for (int z = -1; z < 2; z++) { - BlockPos p = pos.offset(x, 0, z); - if (checkFrame(world, p)) { - return p; - } - } - } - return null; - } - - private boolean checkFrame(ServerLevel world, BlockPos pos) { - return world.getBlockState(pos).is(this) && - world.getBlockState(pos.south()).is(this) && - world.getBlockState(pos.east()).is(this) && - world.getBlockState(pos.south().east()).is(this); - } - - private void replaceMushroom(ServerLevel world, BlockPos pos) { - if (world.getBlockState(pos).is(this)) { - BlocksHelper.setWithUpdate(world, pos, Blocks.AIR); - } - } - - @Override - public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) { - return random.nextInt(8) == 0; - } -} diff --git a/src/main/java/ru/betterend/blocks/SmallJellyshroomBlock.java b/src/main/java/ru/betterend/blocks/SmallJellyshroomBlock.java deleted file mode 100644 index 60aac3b5..00000000 --- a/src/main/java/ru/betterend/blocks/SmallJellyshroomBlock.java +++ /dev/null @@ -1,104 +0,0 @@ -package ru.betterend.blocks; - -import java.util.EnumMap; -import java.util.List; -import java.util.Random; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.Enchantments; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.BonemealableBlock; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BaseAttachedBlock; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.BlocksHelper; -import ru.betterend.registry.EndFeatures; - -public class SmallJellyshroomBlock extends BaseAttachedBlock implements IRenderTyped, BonemealableBlock { - private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(Direction.class); - - public SmallJellyshroomBlock() { - super(FabricBlockSettings.of(Material.PLANT) - .breakByTool(FabricToolTags.SHEARS) - .breakByHand(true) - .sound(SoundType.NETHER_WART) - .noCollission()); - } - - @Override - @SuppressWarnings("deprecation") - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return BOUNDING_SHAPES.get(state.getValue(FACING)); - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - ItemStack tool = builder.getParameter(LootContextParams.TOOL); - if (tool != null && tool.getItem().is(FabricToolTags.SHEARS) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) { - return Lists.newArrayList(new ItemStack(this)); - } - else { - return Lists.newArrayList(); - } - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - Direction direction = state.getValue(FACING); - BlockPos blockPos = pos.relative(direction.getOpposite()); - BlockState support = world.getBlockState(blockPos); - return canSupportCenter(world, blockPos, direction) && support.canOcclude() && support.getLightEmission() == 0; - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - static { - BOUNDING_SHAPES.put(Direction.UP, Block.box(3, 0, 3, 13, 16, 13)); - BOUNDING_SHAPES.put(Direction.DOWN, Block.box(3, 0, 3, 13, 16, 13)); - BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.0, 0.0, 0.5, 1.0, 1.0, 1.0)); - BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 0.5)); - BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.5, 0.0, 0.0, 1.0, 1.0, 1.0)); - BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.0, 0.0, 0.5, 1.0, 1.0)); - } - - @Override - public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { - return state.getValue(FACING) == Direction.UP && world.getBlockState(pos.below()).is(TagAPI.END_GROUND); - } - - @Override - public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) { - return random.nextInt(16) == 0; - } - - @Override - public void performBonemeal(ServerLevel world, Random random, BlockPos pos, BlockState state) { - BlocksHelper.setWithUpdate(world, pos, Blocks.AIR); - EndFeatures.JELLYSHROOM.getFeature().place(world, null, random, pos, null); - } -} diff --git a/src/main/java/ru/betterend/blocks/SmaragdantCrystalBlock.java b/src/main/java/ru/betterend/blocks/SmaragdantCrystalBlock.java deleted file mode 100644 index c99d5e79..00000000 --- a/src/main/java/ru/betterend/blocks/SmaragdantCrystalBlock.java +++ /dev/null @@ -1,19 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.material.Material; -import ru.bclib.blocks.BaseRotatedPillarBlock; - -public class SmaragdantCrystalBlock extends BaseRotatedPillarBlock { - public SmaragdantCrystalBlock() { - super(FabricBlockSettings.of(Material.GLASS) - .breakByTool(FabricToolTags.PICKAXES) - .luminance(15) - .hardness(1F) - .resistance(1F) - .noOcclusion() - .sound(SoundType.GLASS)); - } -} diff --git a/src/main/java/ru/betterend/blocks/SmaragdantCrystalShardBlock.java b/src/main/java/ru/betterend/blocks/SmaragdantCrystalShardBlock.java deleted file mode 100644 index a4bb26d2..00000000 --- a/src/main/java/ru/betterend/blocks/SmaragdantCrystalShardBlock.java +++ /dev/null @@ -1,108 +0,0 @@ -package ru.betterend.blocks; - -import java.util.EnumMap; - -import com.google.common.collect.Maps; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.LiquidBlockContainer; -import net.minecraft.world.level.block.SimpleWaterloggedBlock; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.material.MaterialColor; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BaseAttachedBlock; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; - -@SuppressWarnings("deprecation") -public class SmaragdantCrystalShardBlock extends BaseAttachedBlock implements IRenderTyped, SimpleWaterloggedBlock, LiquidBlockContainer { - private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(Direction.class); - public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; - - public SmaragdantCrystalShardBlock() { - super(FabricBlockSettings.of(Material.STONE) - .materialColor(MaterialColor.COLOR_GREEN) - .breakByTool(FabricToolTags.PICKAXES) - .luminance(15) - .sound(SoundType.GLASS) - .requiresCorrectToolForDrops() - .noCollission()); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - super.createBlockStateDefinition(stateManager); - stateManager.add(WATERLOGGED); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - @Override - public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { - return !state.getValue(WATERLOGGED); - } - - @Override - public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) { - return !state.getValue(WATERLOGGED); - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - BlockState state = super.getStateForPlacement(ctx); - if (state != null) { - LevelReader worldView = ctx.getLevel(); - BlockPos blockPos = ctx.getClickedPos(); - boolean water = worldView.getFluidState(blockPos).getType() == Fluids.WATER; - return state.setValue(WATERLOGGED, water); - } - return null; - } - - @Override - public FluidState getFluidState(BlockState state) { - return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : Fluids.EMPTY.defaultFluidState(); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return BOUNDING_SHAPES.get(state.getValue(FACING)); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - Direction direction = state.getValue(FACING); - BlockPos blockPos = pos.relative(direction.getOpposite()); - return world.getBlockState(blockPos).isFaceSturdy(world, blockPos, direction); - } - - static { - BOUNDING_SHAPES.put(Direction.UP, Shapes.box(0.125, 0.0, 0.125, 0.875F, 0.875F, 0.875F)); - BOUNDING_SHAPES.put(Direction.DOWN, Shapes.box(0.125, 0.125, 0.125, 0.875F, 1.0, 0.875F)); - BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.125, 0.125, 0.125, 0.875F, 0.875F, 1.0)); - BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.125, 0.125, 0.0, 0.875F, 0.875F, 0.875F)); - BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.125, 0.125, 0.125, 1.0, 0.875F, 0.875F)); - BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.125, 0.125, 0.875F, 0.875F, 0.875F)); - } -} diff --git a/src/main/java/ru/betterend/blocks/SulphurCrystalBlock.java b/src/main/java/ru/betterend/blocks/SulphurCrystalBlock.java deleted file mode 100644 index 7d6c0727..00000000 --- a/src/main/java/ru/betterend/blocks/SulphurCrystalBlock.java +++ /dev/null @@ -1,122 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.EnumMap; -import java.util.List; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.LiquidBlockContainer; -import net.minecraft.world.level.block.SimpleWaterloggedBlock; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.material.MaterialColor; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BaseAttachedBlock; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.MHelper; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -@SuppressWarnings("deprecation") -public class SulphurCrystalBlock extends BaseAttachedBlock implements IRenderTyped, SimpleWaterloggedBlock, LiquidBlockContainer { - private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(Direction.class); - public static final IntegerProperty AGE = IntegerProperty.create("age", 0, 2); - public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; - - public SulphurCrystalBlock() { - super(FabricBlockSettings.of(Material.STONE) - .materialColor(MaterialColor.COLOR_YELLOW) - .breakByTool(FabricToolTags.PICKAXES) - .sound(SoundType.GLASS) - .requiresCorrectToolForDrops() - .noCollission()); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - super.createBlockStateDefinition(stateManager); - stateManager.add(AGE, WATERLOGGED); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - return state.getValue(AGE) < 2 ? Collections.emptyList() : Lists.newArrayList(new ItemStack(EndItems.CRYSTALLINE_SULPHUR, MHelper.randRange(1, 3, MHelper.RANDOM))); - } - - @Override - public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { - return !state.getValue(WATERLOGGED); - } - - @Override - public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) { - return !state.getValue(WATERLOGGED); - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - BlockState state = super.getStateForPlacement(ctx); - if (state != null) { - LevelReader worldView = ctx.getLevel(); - BlockPos blockPos = ctx.getClickedPos(); - boolean water = worldView.getFluidState(blockPos).getType() == Fluids.WATER; - return state.setValue(WATERLOGGED, water); - } - return null; - } - - @Override - public FluidState getFluidState(BlockState state) { - return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : Fluids.EMPTY.defaultFluidState(); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return BOUNDING_SHAPES.get(state.getValue(FACING)); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - Direction direction = state.getValue(FACING); - BlockPos blockPos = pos.relative(direction.getOpposite()); - return world.getBlockState(blockPos).is(EndBlocks.BRIMSTONE); - } - - static { - BOUNDING_SHAPES.put(Direction.UP, Shapes.box(0.125, 0.0, 0.125, 0.875F, 0.5, 0.875F)); - BOUNDING_SHAPES.put(Direction.DOWN, Shapes.box(0.125, 0.5, 0.125, 0.875F, 1.0, 0.875F)); - BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.125, 0.125, 0.5, 0.875F, 0.875F, 1.0)); - BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.125, 0.125, 0.0, 0.875F, 0.875F, 0.5)); - BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.5, 0.125, 0.125, 1.0, 0.875F, 0.875F)); - BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.125, 0.125, 0.5, 0.875F, 0.875F)); - } -} diff --git a/src/main/java/ru/betterend/blocks/TenaneaFlowersBlock.java b/src/main/java/ru/betterend/blocks/TenaneaFlowersBlock.java deleted file mode 100644 index 775878b6..00000000 --- a/src/main/java/ru/betterend/blocks/TenaneaFlowersBlock.java +++ /dev/null @@ -1,82 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.color.block.BlockColor; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Vec3i; -import net.minecraft.util.Mth; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BaseVineBlock; -import ru.bclib.interfaces.IColorProvider; -import ru.bclib.util.ColorUtil; -import ru.bclib.util.MHelper; -import ru.betterend.registry.EndParticles; - -public class TenaneaFlowersBlock extends BaseVineBlock implements IColorProvider { - public static final Vec3i[] COLORS; - - public TenaneaFlowersBlock() { - super(15); - } - - @Override - public BlockColor getProvider() { - return (state, world, pos, tintIndex) -> { - if (pos == null) { - pos = BlockPos.ZERO; - }; - long i = (MHelper.getRandom(pos.getX(), pos.getZ()) & 63) + pos.getY(); - double delta = i * 0.1; - int index = MHelper.floor(delta); - int index2 = (index + 1) & 3; - delta -= index; - index &= 3; - - Vec3i color1 = COLORS[index]; - Vec3i color2 = COLORS[index2]; - - int r = MHelper.floor(Mth.lerp(delta, color1.getX(), color2.getX())); - int g = MHelper.floor(Mth.lerp(delta, color1.getY(), color2.getY())); - int b = MHelper.floor(Mth.lerp(delta, color1.getZ(), color2.getZ())); - float[] hsb = ColorUtil.RGBtoHSB(r, g, b, new float[3]); - - return ColorUtil.HSBtoRGB(hsb[0], MHelper.max(0.5F, hsb[1]), hsb[2]); - }; - } - - @Override - public ItemColor getItemProvider() { - return (stack, tintIndex) -> ColorUtil.color(255, 255, 255); - } - - @Override - public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) { - return false; - } - - @Environment(EnvType.CLIENT) - public void animateTick(BlockState state, Level world, BlockPos pos, Random random) { - super.animateTick(state, world, pos, random); - if (random.nextInt(32) == 0) { - double x = (double) pos.getX() + random.nextGaussian() + 0.5; - double z = (double) pos.getZ() + random.nextGaussian() + 0.5; - double y = (double) pos.getY() + random.nextDouble(); - world.addParticle(EndParticles.TENANEA_PETAL, x, y, z, 0, 0, 0); - } - } - - static { - COLORS = new Vec3i[] { - new Vec3i(250, 111, 222), - new Vec3i(167, 89, 255), - new Vec3i(120, 207, 239), - new Vec3i(255, 87, 182) - }; - } -} diff --git a/src/main/java/ru/betterend/blocks/TenaneaSaplingBlock.java b/src/main/java/ru/betterend/blocks/TenaneaSaplingBlock.java deleted file mode 100644 index 9928dcc6..00000000 --- a/src/main/java/ru/betterend/blocks/TenaneaSaplingBlock.java +++ /dev/null @@ -1,25 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.feature.Feature; -import ru.bclib.blocks.FeatureSaplingBlock; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; - -public class TenaneaSaplingBlock extends FeatureSaplingBlock { - public TenaneaSaplingBlock() { - super(); - } - - @Override - protected Feature getFeature() { - return EndFeatures.TENANEA.getFeature(); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - return world.getBlockState(pos.below()).is(EndBlocks.PINK_MOSS); - } -} diff --git a/src/main/java/ru/betterend/blocks/TerrainPlantBlock.java b/src/main/java/ru/betterend/blocks/TerrainPlantBlock.java deleted file mode 100644 index 090b3b15..00000000 --- a/src/main/java/ru/betterend/blocks/TerrainPlantBlock.java +++ /dev/null @@ -1,24 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import ru.betterend.blocks.basis.EndPlantBlock; - -public class TerrainPlantBlock extends EndPlantBlock { - private final Block[] ground; - - public TerrainPlantBlock(Block... ground) { - super(true); - this.ground = ground; - } - - @Override - protected boolean isTerrain(BlockState state) { - for (Block block: ground) { - if (state.is(block)) { - return true; - } - } - return false; - } -} diff --git a/src/main/java/ru/betterend/blocks/TwistedUmbrellaMossBlock.java b/src/main/java/ru/betterend/blocks/TwistedUmbrellaMossBlock.java deleted file mode 100644 index 9fc3ffa2..00000000 --- a/src/main/java/ru/betterend/blocks/TwistedUmbrellaMossBlock.java +++ /dev/null @@ -1,49 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BaseDoublePlantBlock; -import ru.bclib.util.BlocksHelper; -import ru.betterend.blocks.basis.EndPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class TwistedUmbrellaMossBlock extends EndPlantBlock { - public TwistedUmbrellaMossBlock() { - super(11); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.END_MOSS) || state.is(EndBlocks.END_MYCELIUM) || state.is(EndBlocks.JUNGLE_MOSS); - } - - @Environment(EnvType.CLIENT) - public boolean hasEmissiveLighting(BlockGetter world, BlockPos pos) { - return true; - } - - @Environment(EnvType.CLIENT) - public float getAmbientOcclusionLightLevel(BlockGetter world, BlockPos pos) { - return 1F; - } - - @Override - public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) { - return world.isEmptyBlock(pos.above()); - } - - @Override - public void performBonemeal(ServerLevel world, Random random, BlockPos pos, BlockState state) { - int rot = world.random.nextInt(4); - BlockState bs = EndBlocks.TWISTED_UMBRELLA_MOSS_TALL.defaultBlockState().setValue(BaseDoublePlantBlock.ROTATION, rot); - BlocksHelper.setWithoutUpdate(world, pos, bs); - BlocksHelper.setWithoutUpdate(world, pos.above(), bs.setValue(BaseDoublePlantBlock.TOP, true)); - } -} diff --git a/src/main/java/ru/betterend/blocks/TwistedUmbrellaMossTallBlock.java b/src/main/java/ru/betterend/blocks/TwistedUmbrellaMossTallBlock.java deleted file mode 100644 index b33c8235..00000000 --- a/src/main/java/ru/betterend/blocks/TwistedUmbrellaMossTallBlock.java +++ /dev/null @@ -1,28 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BaseDoublePlantBlock; -import ru.betterend.registry.EndBlocks; - -public class TwistedUmbrellaMossTallBlock extends BaseDoublePlantBlock { - public TwistedUmbrellaMossTallBlock() { - super(12); - } - - @Override - public void performBonemeal(ServerLevel world, Random random, BlockPos pos, BlockState state) { - ItemEntity item = new ItemEntity(world, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, new ItemStack(EndBlocks.TWISTED_UMBRELLA_MOSS)); - world.addFreshEntity(item); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.END_MOSS) || state.is(EndBlocks.END_MYCELIUM) || state.is(EndBlocks.JUNGLE_MOSS); - } -} diff --git a/src/main/java/ru/betterend/blocks/UmbrellaMossBlock.java b/src/main/java/ru/betterend/blocks/UmbrellaMossBlock.java deleted file mode 100644 index 44525319..00000000 --- a/src/main/java/ru/betterend/blocks/UmbrellaMossBlock.java +++ /dev/null @@ -1,49 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BaseDoublePlantBlock; -import ru.bclib.util.BlocksHelper; -import ru.betterend.blocks.basis.EndPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class UmbrellaMossBlock extends EndPlantBlock { - public UmbrellaMossBlock() { - super(11); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.END_MOSS) || state.is(EndBlocks.END_MYCELIUM) || state.is(EndBlocks.JUNGLE_MOSS); - } - - @Environment(EnvType.CLIENT) - public boolean hasEmissiveLighting(BlockGetter world, BlockPos pos) { - return true; - } - - @Environment(EnvType.CLIENT) - public float getAmbientOcclusionLightLevel(BlockGetter world, BlockPos pos) { - return 1F; - } - - @Override - public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) { - return world.isEmptyBlock(pos.above()); - } - - @Override - public void performBonemeal(ServerLevel world, Random random, BlockPos pos, BlockState state) { - int rot = world.random.nextInt(4); - BlockState bs = EndBlocks.UMBRELLA_MOSS_TALL.defaultBlockState().setValue(BaseDoublePlantBlock.ROTATION, rot); - BlocksHelper.setWithoutUpdate(world, pos, bs); - BlocksHelper.setWithoutUpdate(world, pos.above(), bs.setValue(BaseDoublePlantBlock.TOP, true)); - } -} diff --git a/src/main/java/ru/betterend/blocks/UmbrellaMossTallBlock.java b/src/main/java/ru/betterend/blocks/UmbrellaMossTallBlock.java deleted file mode 100644 index 18d15ee2..00000000 --- a/src/main/java/ru/betterend/blocks/UmbrellaMossTallBlock.java +++ /dev/null @@ -1,28 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BaseDoublePlantBlock; -import ru.betterend.registry.EndBlocks; - -public class UmbrellaMossTallBlock extends BaseDoublePlantBlock { - public UmbrellaMossTallBlock() { - super(12); - } - - @Override - public void performBonemeal(ServerLevel world, Random random, BlockPos pos, BlockState state) { - ItemEntity item = new ItemEntity(world, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, new ItemStack(EndBlocks.UMBRELLA_MOSS)); - world.addFreshEntity(item); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(EndBlocks.END_MOSS) || state.is(EndBlocks.END_MYCELIUM) || state.is(EndBlocks.JUNGLE_MOSS); - } -} diff --git a/src/main/java/ru/betterend/blocks/UmbrellaTreeClusterBlock.java b/src/main/java/ru/betterend/blocks/UmbrellaTreeClusterBlock.java deleted file mode 100644 index a8d3dcb0..00000000 --- a/src/main/java/ru/betterend/blocks/UmbrellaTreeClusterBlock.java +++ /dev/null @@ -1,56 +0,0 @@ -package ru.betterend.blocks; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.material.MaterialColor; -import net.minecraft.world.phys.BlockHitResult; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.util.BlocksHelper; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class UmbrellaTreeClusterBlock extends BaseBlock { - public static final BooleanProperty NATURAL = BlockProperties.NATURAL; - - public UmbrellaTreeClusterBlock() { - super(FabricBlockSettings.copyOf(Blocks.NETHER_WART_BLOCK) - .materialColor(MaterialColor.COLOR_PURPLE) - .luminance(15)); - registerDefaultState(stateDefinition.any().setValue(NATURAL, false)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(NATURAL); - } - - @Override - public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { - ItemStack stack = player.getMainHandItem(); - if (stack.getItem() == Items.GLASS_BOTTLE) { - if (!player.isCreative()) { - stack.shrink(1); - } - stack = new ItemStack(EndItems.UMBRELLA_CLUSTER_JUICE); - player.addItem(stack); - world.playLocalSound(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, SoundEvents.BOTTLE_FILL, SoundSource.BLOCKS, 1, 1, false); - BlocksHelper.setWithUpdate(world, pos, EndBlocks.UMBRELLA_TREE_CLUSTER_EMPTY.defaultBlockState().setValue(NATURAL, state.getValue(NATURAL))); - return InteractionResult.SUCCESS; - } - return InteractionResult.FAIL; - } -} diff --git a/src/main/java/ru/betterend/blocks/UmbrellaTreeClusterEmptyBlock.java b/src/main/java/ru/betterend/blocks/UmbrellaTreeClusterEmptyBlock.java deleted file mode 100644 index d6569aa3..00000000 --- a/src/main/java/ru/betterend/blocks/UmbrellaTreeClusterEmptyBlock.java +++ /dev/null @@ -1,39 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.util.BlocksHelper; -import ru.betterend.registry.EndBlocks; - -public class UmbrellaTreeClusterEmptyBlock extends BaseBlock { - public static final BooleanProperty NATURAL = EndBlockProperties.NATURAL; - - public UmbrellaTreeClusterEmptyBlock() { - super(FabricBlockSettings.copyOf(Blocks.NETHER_WART_BLOCK) - .materialColor(MaterialColor.COLOR_PURPLE) - .randomTicks()); - registerDefaultState(stateDefinition.any().setValue(NATURAL, false)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(NATURAL); - } - - @Override - public void tick(BlockState state, ServerLevel world, BlockPos pos, Random random) { - if (state.getValue(NATURAL) && random.nextInt(16) == 0) { - BlocksHelper.setWithUpdate(world, pos, EndBlocks.UMBRELLA_TREE_CLUSTER.defaultBlockState().setValue(UmbrellaTreeClusterBlock.NATURAL, true)); - } - } -} diff --git a/src/main/java/ru/betterend/blocks/UmbrellaTreeMembraneBlock.java b/src/main/java/ru/betterend/blocks/UmbrellaTreeMembraneBlock.java deleted file mode 100644 index 67ad0a06..00000000 --- a/src/main/java/ru/betterend/blocks/UmbrellaTreeMembraneBlock.java +++ /dev/null @@ -1,87 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Collections; -import java.util.List; - -import com.google.common.collect.Lists; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.SlimeBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import net.minecraft.world.level.storage.loot.LootContext; -import ru.bclib.client.models.BlockModelProvider; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.MHelper; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class UmbrellaTreeMembraneBlock extends SlimeBlock implements IRenderTyped, BlockModelProvider { - public static final IntegerProperty COLOR = EndBlockProperties.COLOR; - private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(0); - - public UmbrellaTreeMembraneBlock() { - super(FabricBlockSettings.copyOf(Blocks.SLIME_BLOCK)); - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - double px = ctx.getClickedPos().getX() * 0.1; - double py = ctx.getClickedPos().getY() * 0.1; - double pz = ctx.getClickedPos().getZ() * 0.1; - return this.defaultBlockState().setValue(COLOR, MHelper.floor(NOISE.eval(px, py, pz) * 3.5 + 4)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(COLOR); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.TRANSLUCENT; - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - if (state.getValue(COLOR) > 0) { - return Lists.newArrayList(new ItemStack(this)); - } - else { - return MHelper.RANDOM.nextInt(4) == 0 ? Lists.newArrayList(new ItemStack(EndBlocks.UMBRELLA_TREE_SAPLING)) : Collections.emptyList(); - } - } - - @Override - public boolean propagatesSkylightDown(BlockState state, BlockGetter world, BlockPos pos) { - return state.getValue(COLOR) > 0; - } - - @Environment(EnvType.CLIENT) - public boolean skipRendering(BlockState state, BlockState stateFrom, Direction direction) { - if (state.getValue(COLOR) > 0) { - return super.skipRendering(state, stateFrom, direction); - } - else { - return false; - } - } - - @Override - public BlockModel getItemModel(ResourceLocation resourceLocation) { - return getBlockModel(resourceLocation, defaultBlockState()); - } -} diff --git a/src/main/java/ru/betterend/blocks/UmbrellaTreeSaplingBlock.java b/src/main/java/ru/betterend/blocks/UmbrellaTreeSaplingBlock.java deleted file mode 100644 index 652b0b83..00000000 --- a/src/main/java/ru/betterend/blocks/UmbrellaTreeSaplingBlock.java +++ /dev/null @@ -1,31 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.feature.Feature; -import ru.bclib.blocks.FeatureSaplingBlock; -import ru.bclib.client.render.BCLRenderLayer; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; - -public class UmbrellaTreeSaplingBlock extends FeatureSaplingBlock { - public UmbrellaTreeSaplingBlock() { - super(); - } - - @Override - protected Feature getFeature() { - return EndFeatures.UMBRELLA_TREE.getFeature(); - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - return world.getBlockState(pos.below()).is(EndBlocks.JUNGLE_MOSS); - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.TRANSLUCENT; - } -} diff --git a/src/main/java/ru/betterend/blocks/VanillaBlockProperties.java b/src/main/java/ru/betterend/blocks/VanillaBlockProperties.java deleted file mode 100644 index 1afa178f..00000000 --- a/src/main/java/ru/betterend/blocks/VanillaBlockProperties.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.betterend.blocks; - -import net.minecraft.world.level.block.state.properties.BooleanProperty; - -public class VanillaBlockProperties { - public static final BooleanProperty ROOTS = BooleanProperty.create("roots"); -} diff --git a/src/main/java/ru/betterend/blocks/VentBubbleColumnBlock.java b/src/main/java/ru/betterend/blocks/VentBubbleColumnBlock.java deleted file mode 100644 index e58333b7..00000000 --- a/src/main/java/ru/betterend/blocks/VentBubbleColumnBlock.java +++ /dev/null @@ -1,123 +0,0 @@ -package ru.betterend.blocks; - -import java.util.Random; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.BucketPickup; -import net.minecraft.world.level.block.LiquidBlockContainer; -import net.minecraft.world.level.block.RenderShape; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.util.BlocksHelper; -import ru.betterend.registry.EndBlocks; - -public class VentBubbleColumnBlock extends Block implements BucketPickup, LiquidBlockContainer { - public VentBubbleColumnBlock() { - super(FabricBlockSettings.of(Material.BUBBLE_COLUMN).noOcclusion().noCollission().noDrops()); - } - - @Override - public Fluid takeLiquid(LevelAccessor world, BlockPos pos, BlockState state) { - world.setBlock(pos, Blocks.AIR.defaultBlockState(), 11); - return Fluids.WATER; - } - - @Override - public RenderShape getRenderShape(BlockState state) { - return RenderShape.INVISIBLE; - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - BlockState blockState = world.getBlockState(pos.below()); - return blockState.is(this) || blockState.is(EndBlocks.HYDROTHERMAL_VENT); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { - return Shapes.empty(); - } - - @Override - public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) { - if (!state.canSurvive(world, pos)) { - return Blocks.WATER.defaultBlockState(); - } - else { - BlockPos up = pos.above(); - if (world.getBlockState(up).is(Blocks.WATER)) { - BlocksHelper.setWithoutUpdate(world, up, this); - world.getBlockTicks().scheduleTick(up, this, 5); - } - } - return state; - } - - @Environment(EnvType.CLIENT) - public void animateTick(BlockState state, Level world, BlockPos pos, Random random) { - if (random.nextInt(4) == 0) { - double px = pos.getX() + random.nextDouble(); - double py = pos.getY() + random.nextDouble(); - double pz = pos.getZ() + random.nextDouble(); - world.addAlwaysVisibleParticle(ParticleTypes.BUBBLE_COLUMN_UP, px, py, pz, 0, 0.04, 0); - } - if (random.nextInt(200) == 0) { - world.playLocalSound(pos.getX(), pos.getY(), pos.getZ(), SoundEvents.BUBBLE_COLUMN_UPWARDS_AMBIENT, SoundSource.BLOCKS, 0.2F + random.nextFloat() * 0.2F, 0.9F + random.nextFloat() * 0.15F, false); - } - } - - @Environment(EnvType.CLIENT) - public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { - BlockState blockState = world.getBlockState(pos.above()); - if (blockState.isAir()) { - entity.onAboveBubbleCol(false); - if (!world.isClientSide) { - ServerLevel serverWorld = (ServerLevel) world; - - for (int i = 0; i < 2; ++i) { - serverWorld.sendParticles(ParticleTypes.SPLASH, (double) pos.getX() + world.random.nextDouble(), (double) (pos.getY() + 1), (double) pos.getZ() + world.random.nextDouble(), 1, 0.0D, 0.0D, 0.0D, 1.0D); - serverWorld.sendParticles(ParticleTypes.BUBBLE, (double) pos.getX() + world.random.nextDouble(), (double) (pos.getY() + 1), (double) pos.getZ() + world.random.nextDouble(), 1, 0.0D, 0.01D, 0.0D, 0.2D); - } - } - } - else { - entity.onInsideBubbleColumn(false); - } - } - - @Override - public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { - return false; - } - - @Override - public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) { - return false; - } - - @Override - public FluidState getFluidState(BlockState state) { - return Fluids.WATER.getSource(false); - } -} diff --git a/src/main/java/ru/betterend/blocks/basis/EndAnvilBlock.java b/src/main/java/ru/betterend/blocks/basis/EndAnvilBlock.java deleted file mode 100644 index 893bbf2f..00000000 --- a/src/main/java/ru/betterend/blocks/basis/EndAnvilBlock.java +++ /dev/null @@ -1,120 +0,0 @@ -package ru.betterend.blocks.basis; - -import java.util.List; -import java.util.Objects; - -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.block.AnvilBlock; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import net.minecraft.world.level.material.MaterialColor; -import net.minecraft.world.level.storage.loot.LootContext; -import ru.bclib.blocks.BaseAnvilBlock; -import ru.betterend.blocks.complex.MetalMaterial; -import ru.betterend.item.EndAnvilItem; - -public class EndAnvilBlock extends BaseAnvilBlock { - - protected final int level; - protected IntegerProperty durability; - protected MetalMaterial metalMaterial; - protected int maxDurability; - - public EndAnvilBlock(MaterialColor color, int level) { - super(color); - this.level = level; - } - - public EndAnvilBlock(MetalMaterial metalMaterial, MaterialColor color, int level) { - this(color, level); - this.metalMaterial = metalMaterial; - } - - public int getDurability(BlockState blockState) { - Block anvilBlock = blockState.getBlock(); - if (anvilBlock instanceof EndAnvilBlock) { - blockState.getValue(durability); - } - return 0; - } - - public IntegerProperty getDurability() { - if (durability == null) { - this.maxDurability = 5; - this.durability = IntegerProperty.create("durability", 0, maxDurability); - } - return durability; - } - - public int getMaxDurability() { - return maxDurability; - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - List drops = super.getDrops(state, builder); - ItemStack itemStack = drops.get(0); - itemStack.getOrCreateTag().putInt(EndAnvilItem.DURABILITY, state.getValue(durability)); - return drops; - } - - @Override - @SuppressWarnings("deprecation") - public Item asItem() { - if (metalMaterial != null) { - return metalMaterial.anvilItem; - } - return Item.byBlock(this); - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext blockPlaceContext) { - return Objects.requireNonNull(super.getStateForPlacement(blockPlaceContext)).setValue(durability, maxDurability); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - builder.add(getDurability()); - } - - public int getCraftingLevel() { - return level; - } - - public static BlockState applyDamage(BlockState blockState) { - Block anvilBlock = blockState.getBlock(); - if (anvilBlock instanceof EndAnvilBlock) { - EndAnvilBlock endAnvilBlock = (EndAnvilBlock) anvilBlock; - IntegerProperty durability = endAnvilBlock.getDurability(); - int damage = blockState.getValue(durability) - 1; - if (damage > 0) { - return blockState.setValue(durability, damage); - } - int maxDurability = endAnvilBlock.getMaxDurability(); - blockState = blockState.setValue(durability, maxDurability); - } - return getDamagedState(blockState); - } - - private static BlockState getDamagedState(BlockState fallingState) { - Block anvilBlock = fallingState.getBlock(); - if (anvilBlock instanceof EndAnvilBlock) { - IntegerProperty destructionProperty = EndAnvilBlock.DESTRUCTION; - int destruction = fallingState.getValue(destructionProperty) + 1; - if (destructionProperty.getPossibleValues().contains(destruction)) { - try { - return fallingState.setValue(destructionProperty, destruction); - } catch (Exception ex) { - return null; - } - } - return null; - } - return AnvilBlock.damage(fallingState); - } -} diff --git a/src/main/java/ru/betterend/blocks/basis/EndLanternBlock.java b/src/main/java/ru/betterend/blocks/basis/EndLanternBlock.java deleted file mode 100644 index f66fa6dc..00000000 --- a/src/main/java/ru/betterend/blocks/basis/EndLanternBlock.java +++ /dev/null @@ -1,135 +0,0 @@ -package ru.betterend.blocks.basis; - -import java.util.Map; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.client.resources.model.UnbakedModel; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.LiquidBlockContainer; -import net.minecraft.world.level.block.SimpleWaterloggedBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import ru.bclib.blocks.BaseBlockNotFull; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.client.models.ModelsHelper; - -@SuppressWarnings("deprecation") -public class EndLanternBlock extends BaseBlockNotFull implements SimpleWaterloggedBlock, LiquidBlockContainer { - public static final BooleanProperty IS_FLOOR = BlockProperties.IS_FLOOR; - public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; - - public EndLanternBlock(Block source) { - this(FabricBlockSettings.copyOf(source).luminance(15).noOcclusion()); - } - - public EndLanternBlock(Properties settings) { - super(settings.noOcclusion()); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(IS_FLOOR, WATERLOGGED); - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - LevelReader worldView = ctx.getLevel(); - BlockPos blockPos = ctx.getClickedPos(); - Direction dir = ctx.getClickedFace(); - boolean water = worldView.getFluidState(blockPos).getType() == Fluids.WATER; - if (dir != Direction.DOWN && dir != Direction.UP) { - if (canSupportCenter(worldView, blockPos.above(), Direction.DOWN)) { - return defaultBlockState().setValue(IS_FLOOR, false).setValue(WATERLOGGED, water); - } - else if (canSupportCenter(worldView, blockPos.below(), Direction.UP)) { - return defaultBlockState().setValue(IS_FLOOR, true).setValue(WATERLOGGED, water); - } - else { - return null; - } - } - else if (dir == Direction.DOWN) { - if (canSupportCenter(worldView, blockPos.above(), Direction.DOWN)) { - return defaultBlockState().setValue(IS_FLOOR, false).setValue(WATERLOGGED, water); - } - else if (canSupportCenter(worldView, blockPos.below(), Direction.UP)) { - return defaultBlockState().setValue(IS_FLOOR, true).setValue(WATERLOGGED, water); - } - else { - return null; - } - } - else { - if (canSupportCenter(worldView, blockPos.below(), Direction.UP)) { - return defaultBlockState().setValue(IS_FLOOR, true).setValue(WATERLOGGED, water); - } - else if (canSupportCenter(worldView, blockPos.above(), Direction.DOWN)) { - return defaultBlockState().setValue(IS_FLOOR, false).setValue(WATERLOGGED, water); - } - else { - return null; - } - } - } - - @Override - public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { - if (state.getValue(IS_FLOOR)) { - return canSupportCenter(world, pos.below(), Direction.UP); - } - else { - return canSupportCenter(world, pos.above(), Direction.DOWN); - } - } - - @Override - public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - Boolean water = state.getValue(WATERLOGGED); - if (water) { - world.getLiquidTicks().scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); - } - if (!canSurvive(state, world, pos)) { - return water ? Blocks.WATER.defaultBlockState() : Blocks.AIR.defaultBlockState(); - } - else { - return state; - } - } - - @Override - public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { - return false; - } - - @Override - public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) { - return false; - } - - @Override - public FluidState getFluidState(BlockState state) { - return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : Fluids.EMPTY.defaultFluidState(); - } - - @Override - public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map modelCache) { - String floor = blockState.getValue(IS_FLOOR) ? "_floor" : ""; - ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), - "block/" + stateId.getPath() + floor); - registerBlockModel(stateId, modelId, blockState, modelCache); - return ModelsHelper.createBlockSimple(modelId); - } -} diff --git a/src/main/java/ru/betterend/blocks/basis/EndPlantBlock.java b/src/main/java/ru/betterend/blocks/basis/EndPlantBlock.java deleted file mode 100644 index 9219a55f..00000000 --- a/src/main/java/ru/betterend/blocks/basis/EndPlantBlock.java +++ /dev/null @@ -1,33 +0,0 @@ -package ru.betterend.blocks.basis; - -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BasePlantBlock; - -public class EndPlantBlock extends BasePlantBlock { - - public EndPlantBlock() { - this(false); - } - - public EndPlantBlock(int light) { - this(false, light); - } - - public EndPlantBlock(boolean replaceable) { - super(replaceable); - } - - public EndPlantBlock(boolean replaceable, int light) { - super(replaceable, light); - } - - public EndPlantBlock(Properties settings) { - super(settings); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(TagAPI.END_GROUND); - } -} diff --git a/src/main/java/ru/betterend/blocks/basis/EndPlantWithAgeBlock.java b/src/main/java/ru/betterend/blocks/basis/EndPlantWithAgeBlock.java deleted file mode 100644 index c3d2045b..00000000 --- a/src/main/java/ru/betterend/blocks/basis/EndPlantWithAgeBlock.java +++ /dev/null @@ -1,19 +0,0 @@ -package ru.betterend.blocks.basis; - -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BasePlantWithAgeBlock; - -public abstract class EndPlantWithAgeBlock extends BasePlantWithAgeBlock { - - public EndPlantWithAgeBlock() {} - - public EndPlantWithAgeBlock(Properties settings) { - super(settings); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(TagAPI.END_GROUND); - } -} diff --git a/src/main/java/ru/betterend/blocks/basis/EndTerrainBlock.java b/src/main/java/ru/betterend/blocks/basis/EndTerrainBlock.java deleted file mode 100644 index 80af5145..00000000 --- a/src/main/java/ru/betterend/blocks/basis/EndTerrainBlock.java +++ /dev/null @@ -1,11 +0,0 @@ -package ru.betterend.blocks.basis; - -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.blocks.BaseTerrainBlock; - -public class EndTerrainBlock extends BaseTerrainBlock { - public EndTerrainBlock(MaterialColor color) { - super(Blocks.END_STONE, color); - } -} diff --git a/src/main/java/ru/betterend/blocks/basis/EndTripleTerrain.java b/src/main/java/ru/betterend/blocks/basis/EndTripleTerrain.java deleted file mode 100644 index f47bbe88..00000000 --- a/src/main/java/ru/betterend/blocks/basis/EndTripleTerrain.java +++ /dev/null @@ -1,12 +0,0 @@ -package ru.betterend.blocks.basis; - -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.blocks.TripleTerrainBlock; - -public class EndTripleTerrain extends TripleTerrainBlock { - - public EndTripleTerrain(MaterialColor color) { - super(Blocks.END_STONE, color); - } -} diff --git a/src/main/java/ru/betterend/blocks/basis/EndUnderwaterPlantBlock.java b/src/main/java/ru/betterend/blocks/basis/EndUnderwaterPlantBlock.java deleted file mode 100644 index 747095d2..00000000 --- a/src/main/java/ru/betterend/blocks/basis/EndUnderwaterPlantBlock.java +++ /dev/null @@ -1,23 +0,0 @@ -package ru.betterend.blocks.basis; - -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.UnderwaterPlantBlock; - -public class EndUnderwaterPlantBlock extends UnderwaterPlantBlock { - - public EndUnderwaterPlantBlock() {} - - public EndUnderwaterPlantBlock(int light) { - super(light); - } - - public EndUnderwaterPlantBlock(Properties settings) { - super(settings); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(TagAPI.END_GROUND); - } -} diff --git a/src/main/java/ru/betterend/blocks/basis/EndUnderwaterWallPlantBlock.java b/src/main/java/ru/betterend/blocks/basis/EndUnderwaterWallPlantBlock.java deleted file mode 100644 index 59bb034d..00000000 --- a/src/main/java/ru/betterend/blocks/basis/EndUnderwaterWallPlantBlock.java +++ /dev/null @@ -1,23 +0,0 @@ -package ru.betterend.blocks.basis; - -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BaseUnderwaterWallPlantBlock; - -public class EndUnderwaterWallPlantBlock extends BaseUnderwaterWallPlantBlock { - - public EndUnderwaterWallPlantBlock() {} - - public EndUnderwaterWallPlantBlock(int light) { - super(light); - } - - public EndUnderwaterWallPlantBlock(Properties settings) { - super(settings); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(TagAPI.END_GROUND); - } -} diff --git a/src/main/java/ru/betterend/blocks/basis/EndWallMushroom.java b/src/main/java/ru/betterend/blocks/basis/EndWallMushroom.java deleted file mode 100644 index fed2b359..00000000 --- a/src/main/java/ru/betterend/blocks/basis/EndWallMushroom.java +++ /dev/null @@ -1,17 +0,0 @@ -package ru.betterend.blocks.basis; - -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.WallMushroomBlock; - -public class EndWallMushroom extends WallMushroomBlock { - - public EndWallMushroom(int light) { - super(light); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(TagAPI.END_GROUND); - } -} diff --git a/src/main/java/ru/betterend/blocks/basis/EndWallPlantBlock.java b/src/main/java/ru/betterend/blocks/basis/EndWallPlantBlock.java deleted file mode 100644 index 35288cbf..00000000 --- a/src/main/java/ru/betterend/blocks/basis/EndWallPlantBlock.java +++ /dev/null @@ -1,22 +0,0 @@ -package ru.betterend.blocks.basis; - -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BaseWallPlantBlock; - -public class EndWallPlantBlock extends BaseWallPlantBlock { - public EndWallPlantBlock() {} - - public EndWallPlantBlock(int light) { - super(light); - } - - public EndWallPlantBlock(Properties settings) { - super(settings); - } - - @Override - protected boolean isTerrain(BlockState state) { - return state.is(TagAPI.END_GROUND); - } -} diff --git a/src/main/java/ru/betterend/blocks/basis/FurBlock.java b/src/main/java/ru/betterend/blocks/basis/FurBlock.java deleted file mode 100644 index 0514f5b5..00000000 --- a/src/main/java/ru/betterend/blocks/basis/FurBlock.java +++ /dev/null @@ -1,89 +0,0 @@ -package ru.betterend.blocks.basis; - -import java.util.EnumMap; -import java.util.List; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.Enchantments; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.ItemLike; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BaseAttachedBlock; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.MHelper; - -public class FurBlock extends BaseAttachedBlock implements IRenderTyped { - private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(Direction.class); - private final ItemLike drop; - private final int dropChance; - - public FurBlock(ItemLike drop, int light, int dropChance, boolean wet) { - super(FabricBlockSettings.of(Material.REPLACEABLE_PLANT) - .breakByTool(FabricToolTags.SHEARS) - .breakByHand(true) - .luminance(light) - .sound(wet ? SoundType.WET_GRASS : SoundType.GRASS) - .noCollission()); - this.drop = drop; - this.dropChance = dropChance; - } - - public FurBlock(ItemLike drop, int dropChance) { - super(FabricBlockSettings.of(Material.REPLACEABLE_PLANT) - .breakByTool(FabricToolTags.SHEARS) - .breakByHand(true) - .sound(SoundType.GRASS) - .noCollission()); - this.drop = drop; - this.dropChance = dropChance; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return BOUNDING_SHAPES.get(state.getValue(FACING)); - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - ItemStack tool = builder.getParameter(LootContextParams.TOOL); - if (tool != null && tool.getItem().is(FabricToolTags.SHEARS) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) { - return Lists.newArrayList(new ItemStack(this)); - } - else if (dropChance < 1 || MHelper.RANDOM.nextInt(dropChance) == 0) { - return Lists.newArrayList(new ItemStack(drop)); - } - else { - return Lists.newArrayList(); - } - } - - @Override - public BCLRenderLayer getRenderLayer() { - return BCLRenderLayer.CUTOUT; - } - - static { - BOUNDING_SHAPES.put(Direction.UP, Shapes.box(0.0, 0.0, 0.0, 1.0, 0.5, 1.0)); - BOUNDING_SHAPES.put(Direction.DOWN, Shapes.box(0.0, 0.5, 0.0, 1.0, 1.0, 1.0)); - BOUNDING_SHAPES.put(Direction.NORTH, Shapes.box(0.0, 0.0, 0.5, 1.0, 1.0, 1.0)); - BOUNDING_SHAPES.put(Direction.SOUTH, Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0, 0.5)); - BOUNDING_SHAPES.put(Direction.WEST, Shapes.box(0.5, 0.0, 0.0, 1.0, 1.0, 1.0)); - BOUNDING_SHAPES.put(Direction.EAST, Shapes.box(0.0, 0.0, 0.0, 0.5, 1.0, 1.0)); - } -} diff --git a/src/main/java/ru/betterend/blocks/basis/PedestalBlock.java b/src/main/java/ru/betterend/blocks/basis/PedestalBlock.java deleted file mode 100644 index 886e8435..00000000 --- a/src/main/java/ru/betterend/blocks/basis/PedestalBlock.java +++ /dev/null @@ -1,445 +0,0 @@ -package ru.betterend.blocks.basis; - -import java.awt.Point; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import org.jetbrains.annotations.Nullable; - -import com.google.common.collect.Lists; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.resources.model.UnbakedModel; -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.BlockTags; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.blocks.BaseBlockNotFull; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.client.models.ModelsHelper; -import ru.betterend.blocks.EndBlockProperties; -import ru.betterend.blocks.EndBlockProperties.PedestalState; -import ru.betterend.blocks.InfusionPedestal; -import ru.betterend.blocks.entities.InfusionPedestalEntity; -import ru.betterend.blocks.entities.PedestalBlockEntity; -import ru.betterend.client.models.Patterns; -import ru.betterend.registry.EndBlocks; -import ru.betterend.rituals.InfusionRitual; - -@SuppressWarnings({"deprecation"}) -public class PedestalBlock extends BaseBlockNotFull implements EntityBlock { - public final static EnumProperty STATE = EndBlockProperties.PEDESTAL_STATE; - public static final BooleanProperty HAS_ITEM = EndBlockProperties.HAS_ITEM; - public static final BooleanProperty HAS_LIGHT = BlockProperties.HAS_LIGHT; - - private static final VoxelShape SHAPE_DEFAULT; - private static final VoxelShape SHAPE_COLUMN; - private static final VoxelShape SHAPE_PILLAR; - private static final VoxelShape SHAPE_PEDESTAL_TOP; - private static final VoxelShape SHAPE_COLUMN_TOP; - private static final VoxelShape SHAPE_BOTTOM; - - /** - * - * Register new Pedestal block with Better End mod id. - * - * @param name pedestal name - * @param source source block - * @return new Pedestal block with Better End id. - */ - public static Block registerPedestal(String name, Block source) { - return EndBlocks.registerBlock(name, new PedestalBlock(source)); - } - - /** - * - * Register new Pedestal block with specified mod id. - * - * @param id pedestal id - * @param source source block - * @return new Pedestal block with specified id. - */ - public static Block registerPedestal(ResourceLocation id, Block source) { - return EndBlocks.registerBlock(id, new PedestalBlock(source)); - } - - protected final Block parent; - protected float height = 1.0F; - - public PedestalBlock(Block parent) { - super(FabricBlockSettings.copyOf(parent).luminance(state -> state.getValue(HAS_LIGHT) ? 12 : 0)); - this.registerDefaultState(stateDefinition.any().setValue(STATE, PedestalState.DEFAULT).setValue(HAS_ITEM, false).setValue(HAS_LIGHT, false)); - this.parent = parent; - } - - public float getHeight(BlockState state) { - if (state.getBlock() instanceof PedestalBlock && state.getValue(STATE) == PedestalState.PEDESTAL_TOP) { - return this.height - 0.2F; - } - return this.height; - } - - @Override - @Deprecated - public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { - if (world.isClientSide || !state.is(this)) return InteractionResult.CONSUME; - if (!isPlaceable(state)) { - return InteractionResult.PASS; - } - BlockEntity blockEntity = world.getBlockEntity(pos); - if (blockEntity instanceof PedestalBlockEntity) { - PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity; - if (pedestal.isEmpty()) { - ItemStack itemStack = player.getItemInHand(hand); - if (itemStack.isEmpty()) return InteractionResult.CONSUME; - pedestal.setItem(0, itemStack); - checkRitual(world, pos); - return InteractionResult.SUCCESS; - } else { - ItemStack itemStack = pedestal.getItem(0); - if (player.addItem(itemStack)) { - pedestal.removeItemNoUpdate(0); - checkRitual(world, pos); - return InteractionResult.SUCCESS; - } - return InteractionResult.FAIL; - } - } - return InteractionResult.PASS; - } - - @Override - public void destroy(LevelAccessor levelAccessor, BlockPos blockPos, BlockState blockState) { - MutableBlockPos posMutable = new MutableBlockPos(); - for (Point point: InfusionRitual.getMap()) { - posMutable.set(blockPos).move(point.x, 0, point.y); - BlockState state = levelAccessor.getBlockState(posMutable); - if (state.getBlock() instanceof InfusionPedestal) { - BlockEntity blockEntity = levelAccessor.getBlockEntity(posMutable); - if (blockEntity instanceof InfusionPedestalEntity) { - InfusionPedestalEntity pedestal = (InfusionPedestalEntity) blockEntity; - if (pedestal.hasRitual()) { - pedestal.getRitual().markDirty(); - } - } - break; - } - } - } - - public void checkRitual(Level world, BlockPos pos) { - MutableBlockPos posMutable = new MutableBlockPos(); - for (Point point: InfusionRitual.getMap()) { - posMutable.set(pos).move(point.x, 0, point.y); - BlockState state = world.getBlockState(posMutable); - if (state.getBlock() instanceof InfusionPedestal) { - ((InfusionPedestal) state.getBlock()).checkRitual(world, posMutable); - break; - } - } - } - - @Override - @Nullable - public BlockState getStateForPlacement(BlockPlaceContext context) { - Level world = context.getLevel(); - BlockPos pos = context.getClickedPos(); - BlockState upState = world.getBlockState(pos.above()); - BlockState downState = world.getBlockState(pos.below()); - boolean upSideSolid = upState.isFaceSturdy(world, pos.above(), Direction.DOWN) || upState.is(BlockTags.WALLS); - boolean hasPedestalOver = upState.getBlock() instanceof PedestalBlock; - boolean hasPedestalUnder = downState.getBlock() instanceof PedestalBlock; - if (!hasPedestalOver && hasPedestalUnder && upSideSolid) { - return defaultBlockState().setValue(STATE, PedestalState.COLUMN_TOP); - } else if (!hasPedestalOver && !hasPedestalUnder && upSideSolid) { - return defaultBlockState().setValue(STATE, PedestalState.COLUMN); - } else if (hasPedestalUnder && hasPedestalOver) { - return defaultBlockState().setValue(STATE, PedestalState.PILLAR); - } else if (hasPedestalUnder) { - return defaultBlockState().setValue(STATE, PedestalState.PEDESTAL_TOP); - } else if (hasPedestalOver) { - return defaultBlockState().setValue(STATE, PedestalState.BOTTOM); - } - return defaultBlockState(); - } - - @Override - @Deprecated - public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) { - BlockState updated = getUpdatedState(state, direction, newState, world, pos, posFrom); - if (!updated.is(this)) return updated; - if (!isPlaceable(updated)) { - moveStoredStack(world, updated, pos); - } - return updated; - } - - private BlockState getUpdatedState(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) { - if (!state.is(this)) return state.updateShape(direction, newState, world, pos, posFrom); - if (direction != Direction.UP && direction != Direction.DOWN) return state; - BlockState upState = world.getBlockState(pos.above()); - BlockState downState = world.getBlockState(pos.below()); - boolean upSideSolid = upState.isFaceSturdy(world, pos.above(), Direction.DOWN) || upState.is(BlockTags.WALLS); - boolean hasPedestalOver = upState.getBlock() instanceof PedestalBlock; - boolean hasPedestalUnder = downState.getBlock() instanceof PedestalBlock; - if (direction == Direction.UP) { - upSideSolid = newState.isFaceSturdy(world, posFrom, Direction.DOWN) || newState.is(BlockTags.WALLS); - hasPedestalOver = newState.getBlock() instanceof PedestalBlock; - } else { - hasPedestalUnder = newState.getBlock() instanceof PedestalBlock; - } - BlockState updatedState; - if (!hasPedestalOver && hasPedestalUnder && upSideSolid) { - updatedState = state.setValue(STATE, PedestalState.COLUMN_TOP); - } else if (!hasPedestalOver && !hasPedestalUnder && upSideSolid) { - updatedState = state.setValue(STATE, PedestalState.COLUMN); - } else if (hasPedestalUnder && hasPedestalOver) { - updatedState = state.setValue(STATE, PedestalState.PILLAR); - } else if (hasPedestalUnder) { - updatedState = state.setValue(STATE, PedestalState.PEDESTAL_TOP); - } else if (hasPedestalOver) { - updatedState = state.setValue(STATE, PedestalState.BOTTOM); - } else { - updatedState = state.setValue(STATE, PedestalState.DEFAULT); - } - if (!isPlaceable(updatedState)) { - updatedState = updatedState.setValue(HAS_ITEM, false).setValue(HAS_LIGHT, false); - } - return updatedState; - } - - @Override - public List getDrops(BlockState state, LootContext.Builder builder) { - List drop = Lists.newArrayList(super.getDrops(state, builder)); - if (state.is(this)) { - if (isPlaceable(state)) { - BlockEntity blockEntity = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY); - if (blockEntity instanceof PedestalBlockEntity) { - PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity; - if (!pedestal.isEmpty()) { - drop.add(pedestal.getItem(0)); - } - } - } else { - return drop; - } - } - return drop; - } - - private void moveStoredStack(LevelAccessor world, BlockState state, BlockPos pos) { - BlockEntity blockEntity = world.getBlockEntity(pos); - if (blockEntity instanceof PedestalBlockEntity && state.is(this)) { - PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity; - ItemStack stack = pedestal.removeItemNoUpdate(0); - if (!stack.isEmpty()) { - moveStoredStack(blockEntity, world, stack, pos.above()); - } - } - } - - private void moveStoredStack(BlockEntity blockEntity, LevelAccessor world, ItemStack stack, BlockPos pos) { - BlockState state = world.getBlockState(pos); - if (!state.is(this)) { - dropStoredStack(blockEntity, stack, pos); - } else if (state.getValue(STATE).equals(PedestalState.PILLAR)) { - moveStoredStack(blockEntity, world, stack, pos.above()); - } else if (!isPlaceable(state)) { - dropStoredStack(blockEntity, stack, pos); - } else if (blockEntity instanceof PedestalBlockEntity) { - PedestalBlockEntity pedestal = (PedestalBlockEntity) blockEntity; - if (pedestal.isEmpty()) { - pedestal.setItem(0, stack); - } else { - dropStoredStack(blockEntity, stack, pos); - } - } else { - dropStoredStack(blockEntity, stack, pos); - } - } - - private void dropStoredStack(BlockEntity blockEntity, ItemStack stack, BlockPos pos) { - if (blockEntity != null && blockEntity.getLevel() != null) { - Level world = blockEntity.getLevel(); - Block.popResource(world, getDropPos(world, pos), stack); - } - } - - private BlockPos getDropPos(LevelAccessor world, BlockPos pos) { - BlockPos dropPos; - if (world.getBlockState(pos).isAir()) { - return pos; - } - if (world.getBlockState(pos.above()).isAir()) { - return pos.above(); - } - for(int i = 2; i < Direction.values().length; i++) { - dropPos = pos.relative(Direction.from3DDataValue(i)); - if (world.getBlockState(dropPos).isAir()) { - return dropPos.immutable(); - } - } - return getDropPos(world, pos.above()); - } - - public boolean isPlaceable(BlockState state) { - if (!state.is(this)) return false; - PedestalState currentState = state.getValue(STATE); - return currentState == PedestalState.DEFAULT || - currentState == PedestalState.PEDESTAL_TOP; - } - - @Override - @Deprecated - public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { - if (state.is(this)) { - switch(state.getValue(STATE)) { - case BOTTOM: { - return SHAPE_BOTTOM; - } - case PEDESTAL_TOP: { - return SHAPE_PEDESTAL_TOP; - } - case COLUMN_TOP: { - return SHAPE_COLUMN_TOP; - } - case PILLAR: { - return SHAPE_PILLAR; - } - case COLUMN: { - return SHAPE_COLUMN; - } - default: { - return SHAPE_DEFAULT; - } - } - } - return super.getShape(state, world, pos, context); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(STATE, HAS_ITEM, HAS_LIGHT); - } - - @Override - public BlockEntity newBlockEntity(BlockGetter world) { - return new PedestalBlockEntity(); - } - - public boolean hasUniqueEntity() { - return false; - } - - @Override - @Deprecated - public boolean hasAnalogOutputSignal(BlockState state) { - return state.getBlock() instanceof PedestalBlock; - } - - @Override - @Deprecated - public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) { - return state.getValue(HAS_ITEM) ? 15 : 0; - } - - @Override - public BlockModel getItemModel(ResourceLocation blockId) { - return getBlockModel(blockId, defaultBlockState()); - } - - @Override - public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { - Map textures = createTexturesMap(); - PedestalState state = blockState.getValue(STATE); - Optional pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_DEFAULT, textures); - switch (state) { - case COLUMN_TOP: - pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_COLUMN_TOP, textures); - break; - case COLUMN: - pattern = Patterns.createJson(Patterns.BLOKC_PEDESTAL_COLUMN, textures); - break; - case PEDESTAL_TOP: - pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_TOP, textures); - break; - case BOTTOM: - pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_BOTTOM, textures); - break; - case PILLAR: - pattern = Patterns.createJson(Patterns.BLOCK_PEDESTAL_PILLAR, textures); - break; - default: break; - } - return ModelsHelper.fromPattern(pattern); - } - - @Override - public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map modelCache) { - PedestalState state = blockState.getValue(STATE); - ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), - "block/" + stateId.getPath() + "_" + state); - registerBlockModel(stateId, modelId, blockState, modelCache); - return ModelsHelper.createBlockSimple(modelId); - } - - protected Map createTexturesMap() { - ResourceLocation blockId = Registry.BLOCK.getKey(parent); - String name = blockId.getPath(); - return new HashMap() { - private static final long serialVersionUID = 1L; - { - put("%mod%", blockId.getNamespace() ); - put("%top%", name + "_top"); - put("%base%", name + "_base"); - put("%pillar%", name + "_pillar"); - put("%bottom%", name + "_bottom"); - } - }; - } - - static { - VoxelShape basinUp = Block.box(2, 3, 2, 14, 4, 14); - VoxelShape basinDown = Block.box(0, 0, 0, 16, 3, 16); - VoxelShape columnTopUp = Block.box(1, 14, 1, 15, 16, 15); - VoxelShape columnTopDown = Block.box(2, 13, 2, 14, 14, 14); - VoxelShape pedestalTop = Block.box(1, 8, 1, 15, 10, 15); - VoxelShape pedestalDefault = Block.box(1, 12, 1, 15, 14, 15); - VoxelShape pillar = Block.box(3, 0, 3, 13, 8, 13); - VoxelShape pillarDefault = Block.box(3, 0, 3, 13, 12, 13); - VoxelShape columnTop = Shapes.or(columnTopDown, columnTopUp); - VoxelShape basin = Shapes.or(basinDown, basinUp); - SHAPE_PILLAR = Block.box(3, 0, 3, 13, 16, 13); - SHAPE_DEFAULT = Shapes.or(basin, pillarDefault, pedestalDefault); - SHAPE_PEDESTAL_TOP = Shapes.or(pillar, pedestalTop); - SHAPE_COLUMN_TOP = Shapes.or(SHAPE_PILLAR, columnTop); - SHAPE_COLUMN = Shapes.or(basin, SHAPE_PILLAR, columnTop); - SHAPE_BOTTOM = Shapes.or(basin, SHAPE_PILLAR); - } -} diff --git a/src/main/java/ru/betterend/blocks/basis/StoneLanternBlock.java b/src/main/java/ru/betterend/blocks/basis/StoneLanternBlock.java deleted file mode 100644 index b7319079..00000000 --- a/src/main/java/ru/betterend/blocks/basis/StoneLanternBlock.java +++ /dev/null @@ -1,54 +0,0 @@ -package ru.betterend.blocks.basis; - -import java.util.Optional; - -import org.jetbrains.annotations.Nullable; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.client.color.block.BlockColor; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.client.models.ModelsHelper; -import ru.bclib.interfaces.IColorProvider; -import ru.betterend.client.models.Patterns; -import ru.betterend.registry.EndBlocks; - -public class StoneLanternBlock extends EndLanternBlock implements IColorProvider { - private static final VoxelShape SHAPE_CEIL = Block.box(3, 1, 3, 13, 16, 13); - private static final VoxelShape SHAPE_FLOOR = Block.box(3, 0, 3, 13, 15, 13); - - public StoneLanternBlock(Block source) { - super(FabricBlockSettings.copyOf(source).luminance(15)); - } - - @Override - public BlockColor getProvider() { - return ((IColorProvider) EndBlocks.AURORA_CRYSTAL).getProvider(); - } - - @Override - public ItemColor getItemProvider() { - return ((IColorProvider) EndBlocks.AURORA_CRYSTAL).getItemProvider(); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - return state.getValue(IS_FLOOR) ? SHAPE_FLOOR : SHAPE_CEIL; - } - - @Override - public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) { - String blockName = resourceLocation.getPath(); - Optional pattern = blockState.getValue(IS_FLOOR) ? - Patterns.createJson(Patterns.BLOCK_STONE_LANTERN_FLOOR, blockName, blockName) : - Patterns.createJson(Patterns.BLOCK_STONE_LANTERN_CEIL, blockName, blockName); - return ModelsHelper.fromPattern(pattern); - } -} diff --git a/src/main/java/ru/betterend/blocks/complex/ColoredMaterial.java b/src/main/java/ru/betterend/blocks/complex/ColoredMaterial.java deleted file mode 100644 index 9ae68e51..00000000 --- a/src/main/java/ru/betterend/blocks/complex/ColoredMaterial.java +++ /dev/null @@ -1,62 +0,0 @@ -package ru.betterend.blocks.complex; - -import java.util.Map; -import java.util.function.Function; - -import com.google.common.collect.Maps; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.Registry; -import net.minecraft.world.item.DyeColor; -import net.minecraft.world.item.DyeItem; -import net.minecraft.world.level.ItemLike; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.recipes.GridRecipe; -import ru.bclib.util.BlocksHelper; -import ru.betterend.BetterEnd; -import ru.betterend.config.Configs; -import ru.betterend.registry.EndBlocks; - -public class ColoredMaterial { - private static final Map DYES = Maps.newHashMap(); - private static final Map COLORS = Maps.newHashMap(); - private final Map colors = Maps.newHashMap(); - - public ColoredMaterial(Function constructor, Block source, boolean craftEight) { - this(constructor, source, COLORS, DYES, craftEight); - } - - public ColoredMaterial(Function constructor, Block source, Map colors, Map dyes, boolean craftEight) { - String id = Registry.BLOCK.getKey(source).getPath(); - colors.forEach((color, name) -> { - String blockName = id + "_" + name; - Block block = constructor.apply(FabricBlockSettings.copyOf(source).materialColor(MaterialColor.COLOR_BLACK)); - EndBlocks.registerBlock(blockName, block); - if (craftEight) { - GridRecipe.make(BetterEnd.MOD_ID, blockName, block).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(8).setShape("###", "#D#", "###").addMaterial('#', source).addMaterial('D', dyes.get(color)).build(); - } - else { - GridRecipe.make(BetterEnd.MOD_ID, blockName, block).checkConfig(Configs.RECIPE_CONFIG).setList("#D").addMaterial('#', source).addMaterial('D', dyes.get(color)).build(); - } - this.colors.put(color, block); - BlocksHelper.addBlockColor(block, color); - }); - } - - public Block getByColor(DyeColor color) { - return colors.get(color.getMaterialColor().col); - } - - public Block getByColor(int color) { - return colors.get(color); - } - - static { - for (DyeColor color: DyeColor.values()) { - int colorRGB = color.getMaterialColor().col; - COLORS.put(colorRGB, color.getName()); - DYES.put(colorRGB, DyeItem.byColor(color)); - } - } -} diff --git a/src/main/java/ru/betterend/blocks/complex/CrystalSubblocksMaterial.java b/src/main/java/ru/betterend/blocks/complex/CrystalSubblocksMaterial.java deleted file mode 100644 index 1e82ff4c..00000000 --- a/src/main/java/ru/betterend/blocks/complex/CrystalSubblocksMaterial.java +++ /dev/null @@ -1,74 +0,0 @@ -package ru.betterend.blocks.complex; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.tags.BlockTags; -import net.minecraft.tags.ItemTags; -import net.minecraft.world.level.block.Block; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.blocks.BaseRotatedPillarBlock; -import ru.bclib.blocks.BaseSlabBlock; -import ru.bclib.blocks.BaseStairsBlock; -import ru.bclib.blocks.BaseWallBlock; -import ru.bclib.recipes.GridRecipe; -import ru.bclib.util.TagHelper; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.EndPedestal; -import ru.betterend.config.Configs; -import ru.betterend.recipe.CraftingRecipes; -import ru.betterend.registry.EndBlocks; - -public class CrystalSubblocksMaterial { - public final Block polished; - public final Block tiles; - public final Block pillar; - public final Block stairs; - public final Block slab; - public final Block wall; - public final Block pedestal; - public final Block bricks; - public final Block brick_stairs; - public final Block brick_slab; - public final Block brick_wall; - - public CrystalSubblocksMaterial(String name, Block source) { - FabricBlockSettings material = FabricBlockSettings.copyOf(source); - polished = EndBlocks.registerBlock(name + "_polished", new BaseBlock(material)); - tiles = EndBlocks.registerBlock(name + "_tiles", new BaseBlock(material)); - pillar = EndBlocks.registerBlock(name + "_pillar", new BaseRotatedPillarBlock(material)); - stairs = EndBlocks.registerBlock(name + "_stairs", new BaseStairsBlock(source)); - slab = EndBlocks.registerBlock(name + "_slab", new BaseSlabBlock(source)); - wall = EndBlocks.registerBlock(name + "_wall", new BaseWallBlock(source)); - pedestal = EndBlocks.registerBlock(name + "_pedestal", new EndPedestal(source)); - bricks = EndBlocks.registerBlock(name + "_bricks", new BaseBlock(material)); - brick_stairs = EndBlocks.registerBlock(name + "_bricks_stairs", new BaseStairsBlock(bricks)); - brick_slab = EndBlocks.registerBlock(name + "_bricks_slab", new BaseSlabBlock(bricks)); - brick_wall = EndBlocks.registerBlock(name + "_bricks_wall", new BaseWallBlock(bricks)); - - // Recipes // - GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks", bricks).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setShape("##", "##").addMaterial('#', source).setGroup("end_bricks").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_polished", polished).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setShape("##", "##").addMaterial('#', bricks).setGroup("end_tile").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_tiles", tiles).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setShape("##", "##").addMaterial('#', polished).setGroup("end_small_tile").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_pillar", pillar).checkConfig(Configs.RECIPE_CONFIG).setShape("#", "#").addMaterial('#', slab).setGroup("end_pillar").build(); - - GridRecipe.make(BetterEnd.MOD_ID, name + "_stairs", stairs).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setShape("# ", "## ", "###").addMaterial('#', source).setGroup("end_stone_stairs").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_slab", slab).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(6).setShape("###").addMaterial('#', source).setGroup("end_stone_slabs").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks_stairs", brick_stairs).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setShape("# ", "## ", "###").addMaterial('#', bricks).setGroup("end_stone_stairs").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks_slab", brick_slab).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(6).setShape("###").addMaterial('#', bricks).setGroup("end_stone_slabs").build(); - - GridRecipe.make(BetterEnd.MOD_ID, name + "_wall", wall).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(6).setShape("###", "###").addMaterial('#', source).setGroup("end_wall").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks_wall", brick_wall).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(6).setShape("###", "###").addMaterial('#', bricks).setGroup("end_wall").build(); - - CraftingRecipes.registerPedestal(name + "_pedestal", pedestal, slab, pillar); - - // Item Tags // - TagHelper.addTag(ItemTags.SLABS, slab, brick_slab); - TagHelper.addTag(ItemTags.STONE_BRICKS, bricks); - TagHelper.addTag(ItemTags.STONE_CRAFTING_MATERIALS, source); - TagHelper.addTag(ItemTags.STONE_TOOL_MATERIALS, source); - - // Block Tags // - TagHelper.addTag(BlockTags.STONE_BRICKS, bricks); - TagHelper.addTag(BlockTags.WALLS, wall, brick_wall); - TagHelper.addTag(BlockTags.SLABS, slab, brick_slab); - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/blocks/complex/MetalMaterial.java b/src/main/java/ru/betterend/blocks/complex/MetalMaterial.java deleted file mode 100644 index 4f5577bd..00000000 --- a/src/main/java/ru/betterend/blocks/complex/MetalMaterial.java +++ /dev/null @@ -1,217 +0,0 @@ -package ru.betterend.blocks.complex; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.tags.BlockTags; -import net.minecraft.tags.ItemTags; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.item.ArmorMaterial; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.Item.Properties; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.Tier; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.blocks.BaseChainBlock; -import ru.bclib.blocks.BaseDoorBlock; -import ru.bclib.blocks.BaseMetalBarsBlock; -import ru.bclib.blocks.BaseSlabBlock; -import ru.bclib.blocks.BaseStairsBlock; -import ru.bclib.blocks.BaseTrapdoorBlock; -import ru.bclib.blocks.WoodenPressurePlateBlock; -import ru.bclib.items.ModelProviderItem; -import ru.bclib.items.tool.BaseAxeItem; -import ru.bclib.items.tool.BaseHoeItem; -import ru.bclib.items.tool.BasePickaxeItem; -import ru.bclib.items.tool.BaseShovelItem; -import ru.bclib.items.tool.BaseSwordItem; -import ru.bclib.recipes.FurnaceRecipe; -import ru.bclib.recipes.GridRecipe; -import ru.bclib.recipes.SmithingTableRecipe; -import ru.bclib.util.TagHelper; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.BulbVineLanternBlock; -import ru.betterend.blocks.BulbVineLanternColoredBlock; -import ru.betterend.blocks.ChandelierBlock; -import ru.betterend.blocks.basis.EndAnvilBlock; -import ru.betterend.config.Configs; -import ru.betterend.item.EndAnvilItem; -import ru.betterend.item.EndArmorItem; -import ru.betterend.item.tool.EndHammerItem; -import ru.betterend.recipe.builders.AlloyingRecipe; -import ru.betterend.recipe.builders.AnvilRecipe; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; -import ru.betterend.registry.EndTags; - -public class MetalMaterial { - public final Block ore; - public final Block block; - public final Block tile; - public final Block bars; - public final Block pressurePlate; - public final Block door; - public final Block trapdoor; - public final Block chain; - public final Block stairs; - public final Block slab; - - public final Block chandelier; - public final Block bulb_lantern; - public final ColoredMaterial bulb_lantern_colored; - - public final Block anvilBlock; - public final Item anvilItem; - - public final Item nugget; - public final Item ingot; - - public final Item shovelHead; - public final Item pickaxeHead; - public final Item axeHead; - public final Item hoeHead; - public final Item swordBlade; - public final Item swordHandle; - - public final Item shovel; - public final Item sword; - public final Item pickaxe; - public final Item axe; - public final Item hoe; - public final Item hammer; - - public final Item forgedPlate; - public final Item helmet; - public final Item chestplate; - public final Item leggings; - public final Item boots; - - public static MetalMaterial makeNormal(String name, MaterialColor color, Tier material, ArmorMaterial armor) { - return new MetalMaterial(name, true, FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).materialColor(color), EndItems.makeEndItemSettings(), material, armor); - } - - public static MetalMaterial makeNormal(String name, MaterialColor color, float hardness, float resistance, Tier material, ArmorMaterial armor) { - return new MetalMaterial(name, true, FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).materialColor(color).hardness(hardness).resistance(resistance), EndItems.makeEndItemSettings(), material, armor); - } - - public static MetalMaterial makeOreless(String name, MaterialColor color, Tier material, ArmorMaterial armor) { - return new MetalMaterial(name, false, FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).materialColor(color), EndItems.makeEndItemSettings(), material, armor); - } - - public static MetalMaterial makeOreless(String name, MaterialColor color, float hardness, float resistance, Tier material, ArmorMaterial armor) { - return new MetalMaterial(name, false, FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).materialColor(color).hardness(hardness).resistance(resistance), EndItems.makeEndItemSettings(), material, armor); - } - - private MetalMaterial(String name, boolean hasOre, FabricBlockSettings settings, Properties itemSettings, Tier material, ArmorMaterial armor) { - BlockBehaviour.Properties lanternProperties = FabricBlockSettings.copyOf(settings).hardness(1).resistance(1).luminance(15).sound(SoundType.LANTERN); - final int level = material.getLevel(); - - ore = hasOre ? EndBlocks.registerBlock(name + "_ore", new BaseBlock(FabricBlockSettings.copyOf(Blocks.END_STONE))) : null; - block = EndBlocks.registerBlock(name + "_block", new BaseBlock(settings)); - tile = EndBlocks.registerBlock(name + "_tile", new BaseBlock(settings)); - stairs = EndBlocks.registerBlock(name + "_stairs", new BaseStairsBlock(tile)); - slab = EndBlocks.registerBlock(name + "_slab", new BaseSlabBlock(tile)); - door = EndBlocks.registerBlock(name + "_door", new BaseDoorBlock(block)); - trapdoor = EndBlocks.registerBlock(name + "_trapdoor", new BaseTrapdoorBlock(block)); - bars = EndBlocks.registerBlock(name + "_bars", new BaseMetalBarsBlock(block)); - chain = EndBlocks.registerBlock(name + "_chain", new BaseChainBlock(block.defaultMaterialColor())); - pressurePlate = EndBlocks.registerBlock(name + "_plate", new WoodenPressurePlateBlock(block)); - - chandelier = EndBlocks.registerBlock(name + "_chandelier", new ChandelierBlock(block)); - bulb_lantern = EndBlocks.registerBlock(name + "_bulb_lantern", new BulbVineLanternBlock(lanternProperties)); - bulb_lantern_colored = new ColoredMaterial(BulbVineLanternColoredBlock::new, bulb_lantern, false); - - nugget = EndItems.registerEndItem(name + "_nugget", new ModelProviderItem(itemSettings)); - ingot = EndItems.registerEndItem(name + "_ingot", new ModelProviderItem(itemSettings)); - - shovelHead = EndItems.registerEndItem(name + "_shovel_head"); - pickaxeHead = EndItems.registerEndItem(name + "_pickaxe_head"); - axeHead = EndItems.registerEndItem(name + "_axe_head"); - hoeHead = EndItems.registerEndItem(name + "_hoe_head"); - swordBlade = EndItems.registerEndItem(name + "_sword_blade"); - swordHandle = EndItems.registerEndItem(name + "_sword_handle"); - - shovel = EndItems.registerEndTool(name + "_shovel", new BaseShovelItem(material, 1.5F, -3.0F, itemSettings)); - sword = EndItems.registerEndTool(name + "_sword", new BaseSwordItem(material, 3, -2.4F, itemSettings)); - pickaxe = EndItems.registerEndTool(name + "_pickaxe", new BasePickaxeItem(material, 1, -2.8F, itemSettings)); - axe = EndItems.registerEndTool(name + "_axe", new BaseAxeItem(material, 6.0F, -3.0F, itemSettings)); - hoe = EndItems.registerEndTool(name + "_hoe", new BaseHoeItem(material, -3, 0.0F, itemSettings)); - hammer = EndItems.registerEndTool(name + "_hammer", new EndHammerItem(material, 5.0F, -3.2F, 0.3D, itemSettings)); - - forgedPlate = EndItems.registerEndItem(name + "_forged_plate"); - helmet = EndItems.registerEndItem(name + "_helmet", new EndArmorItem(armor, EquipmentSlot.HEAD, itemSettings)); - chestplate = EndItems.registerEndItem(name + "_chestplate", new EndArmorItem(armor, EquipmentSlot.CHEST, itemSettings)); - leggings = EndItems.registerEndItem(name + "_leggings", new EndArmorItem(armor, EquipmentSlot.LEGS, itemSettings)); - boots = EndItems.registerEndItem(name + "_boots", new EndArmorItem(armor, EquipmentSlot.FEET, itemSettings)); - - anvilBlock = EndBlocks.registerBlock(name + "_anvil", new EndAnvilBlock(this, block.defaultMaterialColor(), level)); - anvilItem = EndItems.registerEndItem(name + "_anvil_item", new EndAnvilItem(anvilBlock)); - - if (hasOre) { - FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_ingot_furnace", ore, ingot).checkConfig(Configs.RECIPE_CONFIG).setGroup("end_ingot").buildWithBlasting(); - AlloyingRecipe.Builder.create(name + "_ingot_alloy").setInput(ore, ore).setOutput(ingot, 3).setExpiriense(2.1F).build(); - } - - // Basic recipes - GridRecipe.make(BetterEnd.MOD_ID, name + "_ingot_from_nuggets", ingot).checkConfig(Configs.RECIPE_CONFIG).setShape("###", "###", "###").addMaterial('#', nugget).setGroup("end_metal_ingots_nug").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_nuggets_from_ingot", nugget).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(9).setList("#").addMaterial('#', ingot).setGroup("end_metal_nuggets_ing").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_block", block).checkConfig(Configs.RECIPE_CONFIG).setShape("###", "###", "###").addMaterial('#', ingot).setGroup("end_metal_blocks").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_ingot_from_block", ingot).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(9).setList("#").addMaterial('#', block).setGroup("end_metal_ingots").build(); - - // Block recipes - GridRecipe.make(BetterEnd.MOD_ID, name + "_tile", tile).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setShape("##", "##").addMaterial('#', block).setGroup("end_metal_tiles").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_bars", bars).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(16).setShape("###", "###").addMaterial('#', ingot).setGroup("end_metal_bars").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_pressure_plate", pressurePlate).checkConfig(Configs.RECIPE_CONFIG).setShape("##").addMaterial('#', ingot).setGroup("end_metal_plates").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_door", door).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(3).setShape("##", "##", "##").addMaterial('#', ingot).setGroup("end_metal_doors").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_trapdoor", trapdoor).checkConfig(Configs.RECIPE_CONFIG).setShape("##", "##").addMaterial('#', ingot).setGroup("end_metal_trapdoors").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_stairs", stairs).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setShape("# ", "## ", "###").addMaterial('#', block, tile).setGroup("end_metal_stairs").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_slab", slab).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(6).setShape("###").addMaterial('#', block, tile).setGroup("end_metal_slabs").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_chain", chain).checkConfig(Configs.RECIPE_CONFIG).setShape("N", "#", "N").addMaterial('#', ingot).addMaterial('N', nugget).setGroup("end_metal_chain").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_anvil", anvilBlock).checkConfig(Configs.RECIPE_CONFIG).setShape("###", " I ", "III").addMaterial('#', block, tile).addMaterial('I', ingot).setGroup("end_metal_anvil").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_bulb_lantern", bulb_lantern).checkConfig(Configs.RECIPE_CONFIG).setShape("C", "I", "#").addMaterial('C', chain).addMaterial('I', ingot).addMaterial('#', EndItems.GLOWING_BULB).build(); - - GridRecipe.make(BetterEnd.MOD_ID, name + "_chandelier", chandelier).checkConfig(Configs.RECIPE_CONFIG).setShape("I#I", " # ").addMaterial('#', ingot).addMaterial('I', EndItems.LUMECORN_ROD).setGroup("end_metal_chandelier").build(); - - // Tools & armor into nuggets - FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_axe_nugget", axe, nugget).checkConfig(Configs.RECIPE_CONFIG).setGroup("end_nugget").buildWithBlasting(); - FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_hoe_nugget", hoe, nugget).checkConfig(Configs.RECIPE_CONFIG).setGroup("end_nugget").buildWithBlasting(); - FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_pickaxe_nugget", pickaxe, nugget).checkConfig(Configs.RECIPE_CONFIG).setGroup("end_nugget").buildWithBlasting(); - FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_sword_nugget", sword, nugget).checkConfig(Configs.RECIPE_CONFIG).setGroup("end_nugget").buildWithBlasting(); - FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_hammer_nugget", hammer, nugget).checkConfig(Configs.RECIPE_CONFIG).setGroup("end_nugget").buildWithBlasting(); - FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_helmet_nugget", helmet, nugget).checkConfig(Configs.RECIPE_CONFIG).setGroup("end_nugget").buildWithBlasting(); - FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_chestplate_nugget", chestplate, nugget).checkConfig(Configs.RECIPE_CONFIG).setGroup("end_nugget").buildWithBlasting(); - FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_leggings_nugget", leggings, nugget).checkConfig(Configs.RECIPE_CONFIG).setGroup("end_nugget").buildWithBlasting(); - FurnaceRecipe.make(BetterEnd.MOD_ID, name + "_boots_nugget", boots, nugget).checkConfig(Configs.RECIPE_CONFIG).setGroup("end_nugget").buildWithBlasting(); - - // Tool parts from ingots - AnvilRecipe.Builder.create(name + "_shovel_head").setInput(ingot).setOutput(shovelHead).setAnvilLevel(level).setToolLevel(level).setDamage(level).build(); - AnvilRecipe.Builder.create(name + "_pickaxe_head").setInput(ingot).setInputCount(3).setOutput(pickaxeHead).setAnvilLevel(level).setToolLevel(level).setDamage(level).build(); - AnvilRecipe.Builder.create(name + "_axe_head").setInput(ingot).setInputCount(3).setOutput(axeHead).setAnvilLevel(level).setToolLevel(level).setDamage(level).build(); - AnvilRecipe.Builder.create(name + "_hoe_head").setInput(ingot).setInputCount(2).setOutput(hoeHead).setAnvilLevel(level).setToolLevel(level).setDamage(level).build(); - AnvilRecipe.Builder.create(name + "_sword_blade").setInput(ingot).setOutput(swordBlade).setAnvilLevel(level).setToolLevel(level).setDamage(level).build(); - AnvilRecipe.Builder.create(name + "_forged_plate").setInput(ingot).setOutput(forgedPlate).setAnvilLevel(level).setToolLevel(level).setDamage(level).build(); - - // Tools from parts - SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_hammer").checkConfig(Configs.RECIPE_CONFIG).setResult(hammer).setBase(block).setAddition(Items.STICK).build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_axe").checkConfig(Configs.RECIPE_CONFIG).setResult(axe).setBase(axeHead).setAddition(Items.STICK).build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_pickaxe").checkConfig(Configs.RECIPE_CONFIG).setResult(pickaxe).setBase(pickaxeHead).setAddition(Items.STICK).build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_hoe").checkConfig(Configs.RECIPE_CONFIG).setResult(hoe).setBase(hoeHead).setAddition(Items.STICK).build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_sword_handle").checkConfig(Configs.RECIPE_CONFIG).setResult(swordHandle).setBase(ingot).setAddition(Items.STICK).build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_sword").checkConfig(Configs.RECIPE_CONFIG).setResult(sword).setBase(swordBlade).setAddition(swordHandle).build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, name + "_shovel").checkConfig(Configs.RECIPE_CONFIG).setResult(shovel).setBase(shovelHead).setAddition(Items.STICK).build(); - - // Armor crafting - GridRecipe.make(BetterEnd.MOD_ID, name + "_helmet", helmet).checkConfig(Configs.RECIPE_CONFIG).setShape("###", "# #").addMaterial('#', forgedPlate).setGroup("end_metal_helmets").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_chestplate", chestplate).checkConfig(Configs.RECIPE_CONFIG).setShape("# #", "###", "###").addMaterial('#', forgedPlate).setGroup("end_metal_chestplates").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_leggings", leggings).checkConfig(Configs.RECIPE_CONFIG).setShape("###", "# #", "# #").addMaterial('#', forgedPlate).setGroup("end_metal_leggings").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_boots", boots).checkConfig(Configs.RECIPE_CONFIG).setShape("# #", "# #").addMaterial('#', forgedPlate).setGroup("end_metal_boots").build(); - - TagHelper.addTag(BlockTags.ANVIL, anvilBlock); - TagHelper.addTag(BlockTags.BEACON_BASE_BLOCKS, block); - TagHelper.addTag(ItemTags.BEACON_PAYMENT_ITEMS, ingot); - TagHelper.addTag(EndTags.DRAGON_IMMUNE, ore, bars); - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/blocks/complex/StoneMaterial.java b/src/main/java/ru/betterend/blocks/complex/StoneMaterial.java deleted file mode 100644 index 125c391e..00000000 --- a/src/main/java/ru/betterend/blocks/complex/StoneMaterial.java +++ /dev/null @@ -1,106 +0,0 @@ -package ru.betterend.blocks.complex; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.tags.BlockTags; -import net.minecraft.tags.ItemTags; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.blocks.BaseFurnaceBlock; -import ru.bclib.blocks.BaseRotatedPillarBlock; -import ru.bclib.blocks.BaseSlabBlock; -import ru.bclib.blocks.BaseStairsBlock; -import ru.bclib.blocks.BaseStoneButtonBlock; -import ru.bclib.blocks.BaseWallBlock; -import ru.bclib.blocks.StonePressurePlateBlock; -import ru.bclib.recipes.GridRecipe; -import ru.bclib.util.TagHelper; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.EndPedestal; -import ru.betterend.blocks.basis.StoneLanternBlock; -import ru.betterend.config.Configs; -import ru.betterend.recipe.CraftingRecipes; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class StoneMaterial { - public final Block stone; - - public final Block polished; - public final Block tiles; - public final Block pillar; - public final Block stairs; - public final Block slab; - public final Block wall; - public final Block button; - public final Block pressure_plate; - public final Block pedestal; - public final Block lantern; - - public final Block bricks; - public final Block brick_stairs; - public final Block brick_slab; - public final Block brick_wall; - public final Block furnace; - - public StoneMaterial(String name, MaterialColor color) { - FabricBlockSettings material = FabricBlockSettings.copyOf(Blocks.END_STONE).materialColor(color); - - stone = EndBlocks.registerBlock(name, new BaseBlock(material)); - polished = EndBlocks.registerBlock(name + "_polished", new BaseBlock(material)); - tiles = EndBlocks.registerBlock(name + "_tiles", new BaseBlock(material)); - pillar = EndBlocks.registerBlock(name + "_pillar", new BaseRotatedPillarBlock(material)); - stairs = EndBlocks.registerBlock(name + "_stairs", new BaseStairsBlock(stone)); - slab = EndBlocks.registerBlock(name + "_slab", new BaseSlabBlock(stone)); - wall = EndBlocks.registerBlock(name + "_wall", new BaseWallBlock(stone)); - button = EndBlocks.registerBlock(name + "_button", new BaseStoneButtonBlock(stone)); - pressure_plate = EndBlocks.registerBlock(name + "_plate", new StonePressurePlateBlock(stone)); - pedestal = EndBlocks.registerBlock(name + "_pedestal", new EndPedestal(stone)); - lantern = EndBlocks.registerBlock(name + "_lantern", new StoneLanternBlock(stone)); - - bricks = EndBlocks.registerBlock(name + "_bricks", new BaseBlock(material)); - brick_stairs = EndBlocks.registerBlock(name + "_bricks_stairs", new BaseStairsBlock(bricks)); - brick_slab = EndBlocks.registerBlock(name + "_bricks_slab", new BaseSlabBlock(bricks)); - brick_wall = EndBlocks.registerBlock(name + "_bricks_wall", new BaseWallBlock(bricks)); - furnace = EndBlocks.registerBlock(name + "_furnace", new BaseFurnaceBlock(bricks)); - - // Recipes // - GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks", bricks).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setShape("##", "##").addMaterial('#', stone).setGroup("end_bricks").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_polished", polished).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setShape("##", "##").addMaterial('#', bricks).setGroup("end_tile").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_tiles", tiles).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setShape("##", "##").addMaterial('#', polished).setGroup("end_small_tile").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_pillar", pillar).checkConfig(Configs.RECIPE_CONFIG).setShape("#", "#").addMaterial('#', slab).setGroup("end_pillar").build(); - - GridRecipe.make(BetterEnd.MOD_ID, name + "_stairs", stairs).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setShape("# ", "## ", "###").addMaterial('#', stone).setGroup("end_stone_stairs").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_slab", slab).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(6).setShape("###").addMaterial('#', stone).setGroup("end_stone_slabs").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks_stairs", brick_stairs).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setShape("# ", "## ", "###").addMaterial('#', bricks).setGroup("end_stone_stairs").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks_slab", brick_slab).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(6).setShape("###").addMaterial('#', bricks).setGroup("end_stone_slabs").build(); - - GridRecipe.make(BetterEnd.MOD_ID, name + "_wall", wall).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(6).setShape("###", "###").addMaterial('#', stone).setGroup("end_wall").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_bricks_wall", brick_wall).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(6).setShape("###", "###").addMaterial('#', bricks).setGroup("end_wall").build(); - - GridRecipe.make(BetterEnd.MOD_ID, name + "_button", button).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', stone).setGroup("end_stone_buttons").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_pressure_plate", pressure_plate).checkConfig(Configs.RECIPE_CONFIG).setShape("##").addMaterial('#', stone).setGroup("end_stone_plates").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_lantern", lantern).checkConfig(Configs.RECIPE_CONFIG).setShape("S", "#", "S").addMaterial('#', EndItems.CRYSTAL_SHARDS).addMaterial('S', slab, brick_slab).setGroup("end_stone_lanterns").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_furnace", furnace).checkConfig(Configs.RECIPE_CONFIG).setShape("###", "# #", "###").addMaterial('#', stone).setGroup("end_stone_furnaces").build(); - - CraftingRecipes.registerPedestal(name + "_pedestal", pedestal, slab, pillar); - - // Item Tags // - TagHelper.addTag(ItemTags.SLABS, slab, brick_slab); - TagHelper.addTag(ItemTags.STONE_BRICKS, bricks); - TagHelper.addTag(ItemTags.STONE_CRAFTING_MATERIALS, stone); - TagHelper.addTag(ItemTags.STONE_TOOL_MATERIALS, stone); - TagHelper.addTag(TagAPI.FURNACES, furnace); - - // Block Tags // - TagHelper.addTag(BlockTags.STONE_BRICKS, bricks); - TagHelper.addTag(BlockTags.WALLS, wall, brick_wall); - TagHelper.addTag(BlockTags.SLABS, slab, brick_slab); - TagHelper.addTags(pressure_plate, BlockTags.PRESSURE_PLATES, BlockTags.STONE_PRESSURE_PLATES); - TagHelper.addTag(TagAPI.END_STONES, stone); - - TagHelper.addTag(TagAPI.DRAGON_IMMUNE, stone, stairs, slab, wall); - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/blocks/complex/WoodenMaterial.java b/src/main/java/ru/betterend/blocks/complex/WoodenMaterial.java deleted file mode 100644 index c42dc9e9..00000000 --- a/src/main/java/ru/betterend/blocks/complex/WoodenMaterial.java +++ /dev/null @@ -1,186 +0,0 @@ -package ru.betterend.blocks.complex; - -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.fabricmc.fabric.api.registry.FlammableBlockRegistry; -import net.minecraft.tags.BlockTags; -import net.minecraft.tags.ItemTags; -import net.minecraft.tags.Tag; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BaseBarkBlock; -import ru.bclib.blocks.BaseBarrelBlock; -import ru.bclib.blocks.BaseBlock; -import ru.bclib.blocks.BaseBookshelfBlock; -import ru.bclib.blocks.BaseComposterBlock; -import ru.bclib.blocks.BaseCraftingTableBlock; -import ru.bclib.blocks.BaseDoorBlock; -import ru.bclib.blocks.BaseFenceBlock; -import ru.bclib.blocks.BaseGateBlock; -import ru.bclib.blocks.BaseLadderBlock; -import ru.bclib.blocks.BaseRotatedPillarBlock; -import ru.bclib.blocks.BaseSignBlock; -import ru.bclib.blocks.BaseSlabBlock; -import ru.bclib.blocks.BaseStairsBlock; -import ru.bclib.blocks.BaseStripableLogBlock; -import ru.bclib.blocks.BaseTrapdoorBlock; -import ru.bclib.blocks.BaseWoodenButtonBlock; -import ru.bclib.blocks.StripableBarkBlock; -import ru.bclib.blocks.WoodenPressurePlateBlock; -import ru.bclib.recipes.GridRecipe; -import ru.bclib.util.TagHelper; -import ru.betterend.BetterEnd; -import ru.betterend.config.Configs; -import ru.betterend.registry.EndBlocks; - -public class WoodenMaterial { - public final Block log; - public final Block bark; - - public final Block log_stripped; - public final Block bark_stripped; - - public final Block planks; - - public final Block stairs; - public final Block slab; - public final Block fence; - public final Block gate; - public final Block button; - public final Block pressurePlate; - public final Block trapdoor; - public final Block door; - - public final Block craftingTable; - public final Block ladder; - public final Block sign; - - public final Block chest; - public final Block barrel; - public final Block shelf; - public final Block composter; - - public final Tag.Named logBlockTag; - public final Tag.Named logItemTag; - - public WoodenMaterial(String name, MaterialColor woodColor, MaterialColor planksColor) { - FabricBlockSettings materialPlanks = FabricBlockSettings.copyOf(Blocks.OAK_PLANKS).materialColor(planksColor); - - log_stripped = EndBlocks.registerBlock(name + "_stripped_log", new BaseRotatedPillarBlock(materialPlanks)); - bark_stripped = EndBlocks.registerBlock(name + "_stripped_bark", new BaseBarkBlock(materialPlanks)); - - log = EndBlocks.registerBlock(name + "_log", new BaseStripableLogBlock(woodColor, log_stripped)); - bark = EndBlocks.registerBlock(name + "_bark", new StripableBarkBlock(woodColor, bark_stripped)); - - planks = EndBlocks.registerBlock(name + "_planks", new BaseBlock(materialPlanks)); - stairs = EndBlocks.registerBlock(name + "_stairs", new BaseStairsBlock(planks)); - slab = EndBlocks.registerBlock(name + "_slab", new BaseSlabBlock(planks)); - fence = EndBlocks.registerBlock(name + "_fence", new BaseFenceBlock(planks)); - gate = EndBlocks.registerBlock(name + "_gate", new BaseGateBlock(planks)); - button = EndBlocks.registerBlock(name + "_button", new BaseWoodenButtonBlock(planks)); - pressurePlate = EndBlocks.registerBlock(name + "_plate", new WoodenPressurePlateBlock(planks)); - trapdoor = EndBlocks.registerBlock(name + "_trapdoor", new BaseTrapdoorBlock(planks)); - door = EndBlocks.registerBlock(name + "_door", new BaseDoorBlock(planks)); - - craftingTable = EndBlocks.registerBlock(name + "_crafting_table", new BaseCraftingTableBlock(planks)); - ladder = EndBlocks.registerBlock(name + "_ladder", new BaseLadderBlock(planks)); - sign = EndBlocks.registerBlock(name + "_sign", new BaseSignBlock(planks)); - - chest = EndBlocks.registerBlock(name + "_chest", new BaseFenceBlock(planks)); - barrel = EndBlocks.registerBlock(name + "_barrel", new BaseBarrelBlock(planks)); - shelf = EndBlocks.registerBlock(name + "_bookshelf", new BaseBookshelfBlock(planks)); - composter = EndBlocks.registerBlock(name + "_composter", new BaseComposterBlock(planks)); - - // Recipes // - GridRecipe.make(BetterEnd.MOD_ID, name + "_planks", planks).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setList("#").addMaterial('#', log, bark, log_stripped, bark_stripped).setGroup("end_planks").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_stairs", stairs).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setShape("# ", "## ", "###").addMaterial('#', planks).setGroup("end_planks_stairs").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_slab", slab).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(6).setShape("###").addMaterial('#', planks).setGroup("end_planks_slabs").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_fence", fence).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(3).setShape("#I#", "#I#").addMaterial('#', planks).addMaterial('I', Items.STICK).setGroup("end_planks_fences").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_gate", gate).checkConfig(Configs.RECIPE_CONFIG).setShape("I#I", "I#I").addMaterial('#', planks).addMaterial('I', Items.STICK).setGroup("end_planks_gates").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_button", button).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', planks).setGroup("end_planks_buttons").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_pressure_plate", pressurePlate).checkConfig(Configs.RECIPE_CONFIG).setShape("##").addMaterial('#', planks).setGroup("end_planks_plates").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_trapdoor", trapdoor).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(2).setShape("###", "###").addMaterial('#', planks).setGroup("end_trapdoors").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_door", door).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(3).setShape("##", "##", "##").addMaterial('#', planks).setGroup("end_doors").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_crafting_table", craftingTable).checkConfig(Configs.RECIPE_CONFIG).setShape("##", "##").addMaterial('#', planks).setGroup("end_tables").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_ladder", ladder).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(3).setShape("I I", "I#I", "I I").addMaterial('#', planks).addMaterial('I', Items.STICK).setGroup("end_ladders").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_sign", sign).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(3).setShape("###", "###", " I ").addMaterial('#', planks).addMaterial('I', Items.STICK).setGroup("end_signs").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_chest", chest).checkConfig(Configs.RECIPE_CONFIG).setShape("###", "# #", "###").addMaterial('#', planks).setGroup("end_chests").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_barrel", barrel).checkConfig(Configs.RECIPE_CONFIG).setShape("#S#", "# #", "#S#").addMaterial('#', planks).addMaterial('S', slab).setGroup("end_barrels").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_bookshelf", shelf).checkConfig(Configs.RECIPE_CONFIG).setShape("###", "PPP", "###").addMaterial('#', planks).addMaterial('P', Items.BOOK).setGroup("end_bookshelves").build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_bark", bark).checkConfig(Configs.RECIPE_CONFIG).setShape("##", "##").addMaterial('#', log).setOutputCount(3).build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_log", log).checkConfig(Configs.RECIPE_CONFIG).setShape("##", "##").addMaterial('#', bark).setOutputCount(3).build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_composter", composter).checkConfig(Configs.RECIPE_CONFIG).setShape("# #", "# #", "###").addMaterial('#', slab).build(); - GridRecipe.make(BetterEnd.MOD_ID, name + "_shulker", Items.SHULKER_BOX).checkConfig(Configs.RECIPE_CONFIG).setShape("S", "#", "S").addMaterial('S', Items.SHULKER_SHELL).addMaterial('#', chest).build(); - - // Item Tags // - TagHelper.addTag(ItemTags.PLANKS, planks); - TagHelper.addTag(ItemTags.WOODEN_PRESSURE_PLATES, pressurePlate); - TagHelper.addTag(ItemTags.LOGS, log, bark, log_stripped, bark_stripped); - TagHelper.addTag(ItemTags.LOGS_THAT_BURN, log, bark, log_stripped, bark_stripped); - - TagHelper.addTags(button, ItemTags.WOODEN_BUTTONS, ItemTags.BUTTONS); - TagHelper.addTags(door, ItemTags.WOODEN_DOORS, ItemTags.DOORS); - TagHelper.addTags(fence, ItemTags.WOODEN_FENCES, ItemTags.FENCES); - TagHelper.addTags(slab, ItemTags.WOODEN_SLABS, ItemTags.SLABS); - TagHelper.addTags(stairs, ItemTags.WOODEN_STAIRS, ItemTags.STAIRS); - TagHelper.addTags(trapdoor, ItemTags.WOODEN_TRAPDOORS, ItemTags.TRAPDOORS); - TagHelper.addTag(TagAPI.ITEM_CHEST, chest); - - // Block Tags // - TagHelper.addTag(BlockTags.PLANKS, planks); - TagHelper.addTag(BlockTags.CLIMBABLE, ladder); - TagHelper.addTag(BlockTags.LOGS, log, bark, log_stripped, bark_stripped); - TagHelper.addTag(BlockTags.LOGS_THAT_BURN, log, bark, log_stripped, bark_stripped); - - TagHelper.addTags(button, BlockTags.WOODEN_BUTTONS, BlockTags.BUTTONS); - TagHelper.addTags(door, BlockTags.WOODEN_DOORS, BlockTags.DOORS); - TagHelper.addTags(fence, BlockTags.WOODEN_FENCES, BlockTags.FENCES); - TagHelper.addTags(slab, BlockTags.WOODEN_SLABS, BlockTags.SLABS); - TagHelper.addTags(stairs, BlockTags.WOODEN_STAIRS, BlockTags.STAIRS); - TagHelper.addTags(trapdoor, BlockTags.WOODEN_TRAPDOORS, BlockTags.TRAPDOORS); - TagHelper.addTag(TagAPI.BOOKSHELVES, shelf); - TagHelper.addTag(TagAPI.BLOCK_CHEST, chest); - - logBlockTag = TagAPI.makeBlockTag(BetterEnd.MOD_ID, name + "_logs"); - logItemTag = TagAPI.makeItemTag(BetterEnd.MOD_ID, name + "_logs"); - TagHelper.addTag(logBlockTag, log_stripped, bark_stripped, log, bark); - TagHelper.addTag(logItemTag, log_stripped, bark_stripped, log, bark); - - FlammableBlockRegistry.getDefaultInstance().add(log, 5, 5); - FlammableBlockRegistry.getDefaultInstance().add(bark, 5, 5); - FlammableBlockRegistry.getDefaultInstance().add(log_stripped, 5, 5); - FlammableBlockRegistry.getDefaultInstance().add(bark_stripped, 5, 5); - - FlammableBlockRegistry.getDefaultInstance().add(planks, 5, 20); - FlammableBlockRegistry.getDefaultInstance().add(stairs, 5, 20); - FlammableBlockRegistry.getDefaultInstance().add(slab, 5, 20); - - FlammableBlockRegistry.getDefaultInstance().add(fence, 5, 20); - FlammableBlockRegistry.getDefaultInstance().add(gate, 5, 20); - FlammableBlockRegistry.getDefaultInstance().add(button, 5, 20); - FlammableBlockRegistry.getDefaultInstance().add(pressurePlate, 5, 20); - FlammableBlockRegistry.getDefaultInstance().add(trapdoor, 5, 20); - FlammableBlockRegistry.getDefaultInstance().add(door, 5, 20); - - FlammableBlockRegistry.getDefaultInstance().add(craftingTable, 5, 20); - FlammableBlockRegistry.getDefaultInstance().add(ladder, 5, 20); - FlammableBlockRegistry.getDefaultInstance().add(sign, 5, 20); - - FlammableBlockRegistry.getDefaultInstance().add(chest, 5, 20); - FlammableBlockRegistry.getDefaultInstance().add(barrel, 5, 20); - FlammableBlockRegistry.getDefaultInstance().add(shelf, 5, 20); - FlammableBlockRegistry.getDefaultInstance().add(composter, 5, 20); - } - - public boolean isTreeLog(Block block) { - return block == log || block == bark; - } - - public boolean isTreeLog(BlockState state) { - return isTreeLog(state.getBlock()); - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/blocks/entities/BlockEntityHydrothermalVent.java b/src/main/java/ru/betterend/blocks/entities/BlockEntityHydrothermalVent.java deleted file mode 100644 index ecce043d..00000000 --- a/src/main/java/ru/betterend/blocks/entities/BlockEntityHydrothermalVent.java +++ /dev/null @@ -1,73 +0,0 @@ -package ru.betterend.blocks.entities; - -import java.util.List; - -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.ElytraItem; -import net.minecraft.world.item.Item; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.TickableBlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; -import ru.betterend.blocks.HydrothermalVentBlock; -import ru.betterend.interfaces.FallFlyingItem; -import ru.betterend.registry.EndBlockEntities; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndParticles; - -public class BlockEntityHydrothermalVent extends BlockEntity implements TickableBlockEntity { - - private final static Vec3 POSITIVE_Y = new Vec3(0.0f, 1.0f, 0.0f); - - public BlockEntityHydrothermalVent() { - super(EndBlockEntities.HYDROTHERMAL_VENT); - } - - @Override - public void tick() { - if (level != null) { - BlockState state = getBlockState(); - if (state.is(EndBlocks.HYDROTHERMAL_VENT)) { - boolean active = state.getValue(HydrothermalVentBlock.ACTIVATED); - if (active && level.random.nextInt(20) == 0) { - double x = worldPosition.getX() + level.random.nextDouble(); - double y = worldPosition.getY() + 0.9 + level.random.nextDouble() * 0.3; - double z = worldPosition.getZ() + level.random.nextDouble(); - if (state.getValue(HydrothermalVentBlock.WATERLOGGED)) { - level.addParticle(EndParticles.GEYSER_PARTICLE, x, y, z, 0, 0, 0); - } else { - level.addParticle(ParticleTypes.BUBBLE, x, y, z, 0, 0, 0); - } - } - MutableBlockPos mutable = worldPosition.mutable().move(Direction.UP); - int height = active ? 85 : 25; - AABB box = new AABB(mutable.offset(-1, 0, -1), mutable.offset(1, height, 1)); - List entities = level.getEntitiesOfClass(LivingEntity.class, box); - if (entities.size() > 0) { - while (mutable.getY() < box.maxY) { - BlockState blockState = level.getBlockState(mutable); - if (blockState.isSolidRender(level, mutable)) break; - if (blockState.isAir()) { - double mult = active ? 3.0 : 5.0; - float force = (float) ((1.0 - (mutable.getY() / box.maxY)) / mult); - entities.stream().filter(entity -> (int) entity.getY() == mutable.getY() && - hasElytra(entity) && entity.isFallFlying()) - .forEach(entity -> entity.moveRelative(force, POSITIVE_Y)); - } - mutable.move(Direction.UP); - } - } - } - } - } - - private boolean hasElytra(LivingEntity entity) { - Item item = entity.getItemBySlot(EquipmentSlot.CHEST).getItem(); - return item instanceof ElytraItem || item instanceof FallFlyingItem; - } -} diff --git a/src/main/java/ru/betterend/blocks/entities/EndStoneSmelterBlockEntity.java b/src/main/java/ru/betterend/blocks/entities/EndStoneSmelterBlockEntity.java deleted file mode 100644 index 49516b35..00000000 --- a/src/main/java/ru/betterend/blocks/entities/EndStoneSmelterBlockEntity.java +++ /dev/null @@ -1,461 +0,0 @@ -package ru.betterend.blocks.entities; - -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import net.fabricmc.fabric.api.registry.FuelRegistry; -import net.minecraft.core.Direction; -import net.minecraft.core.NonNullList; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Mth; -import net.minecraft.world.ContainerHelper; -import net.minecraft.world.WorldlyContainer; -import net.minecraft.world.entity.ExperienceOrb; -import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.entity.player.StackedContents; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.inventory.ContainerData; -import net.minecraft.world.inventory.RecipeHolder; -import net.minecraft.world.inventory.StackedContentsCompatible; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.crafting.BlastingRecipe; -import net.minecraft.world.item.crafting.Recipe; -import net.minecraft.world.item.crafting.RecipeType; -import net.minecraft.world.level.ItemLike; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity; -import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; -import net.minecraft.world.level.block.entity.TickableBlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.Vec3; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.EndStoneSmelter; -import ru.betterend.client.gui.EndStoneSmelterScreenHandler; -import ru.betterend.recipe.builders.AlloyingRecipe; -import ru.betterend.registry.EndBlockEntities; - -public class EndStoneSmelterBlockEntity extends BaseContainerBlockEntity implements WorldlyContainer, RecipeHolder, StackedContentsCompatible, TickableBlockEntity { - - private static final int[] TOP_SLOTS = new int[] { 0, 1 }; - private static final int[] BOTTOM_SLOTS = new int[] { 2, 3 }; - private static final int[] SIDE_SLOTS = new int[] { 1, 2 }; - private static final Map AVAILABLE_FUELS = Maps.newHashMap(); - - private final Object2IntOpenHashMap recipesUsed; - protected NonNullList inventory; - protected final ContainerData propertyDelegate; - private Recipe lastRecipe; - private int smeltTimeTotal; - private int smeltTime; - private int burnTime; - private int fuelTime; - - public EndStoneSmelterBlockEntity() { - super(EndBlockEntities.END_STONE_SMELTER); - this.inventory = NonNullList.withSize(4, ItemStack.EMPTY); - this.recipesUsed = new Object2IntOpenHashMap<>(); - this.propertyDelegate = new ContainerData() { - public int get(int index) { - switch(index) { - case 0: - return EndStoneSmelterBlockEntity.this.burnTime; - case 1: - return EndStoneSmelterBlockEntity.this.fuelTime; - case 2: - return EndStoneSmelterBlockEntity.this.smeltTime; - case 3: - return EndStoneSmelterBlockEntity.this.smeltTimeTotal; - default: - return 0; - } - } - - public void set(int index, int value) { - switch(index) { - case 0: - EndStoneSmelterBlockEntity.this.burnTime = value; - break; - case 1: - EndStoneSmelterBlockEntity.this.fuelTime = value; - break; - case 2: - EndStoneSmelterBlockEntity.this.smeltTime = value; - break; - case 3: - EndStoneSmelterBlockEntity.this.smeltTimeTotal = value; - } - } - - public int getCount() { - return 4; - } - }; - } - - private boolean isBurning() { - return burnTime > 0; - } - - @Override - public int getContainerSize() { - return inventory.size(); - } - - @Override - public boolean isEmpty() { - Iterator iterator = inventory.iterator(); - ItemStack itemStack; - do { - if (!iterator.hasNext()) { - return true; - } - itemStack = iterator.next(); - } while (itemStack.isEmpty()); - - return false; - } - - @Override - public ItemStack getItem(int slot) { - return inventory.get(slot); - } - - @Override - public ItemStack removeItem(int slot, int amount) { - return ContainerHelper.removeItem(inventory, slot, amount); - } - - @Override - public ItemStack removeItemNoUpdate(int slot) { - return ContainerHelper.takeItem(inventory, slot); - } - - @Override - public void setItem(int slot, ItemStack stack) { - ItemStack itemStack = inventory.get(slot); - boolean stackValid = !stack.isEmpty() && stack.sameItem(itemStack) && ItemStack.tagMatches(stack, itemStack); - inventory.set(slot, stack); - if (stack.getCount() > getMaxStackSize()) { - stack.setCount(getMaxStackSize()); - } - if ((slot == 0 || slot == 1) && !stackValid) { - smeltTimeTotal = getSmeltTime(); - smeltTime = 0; - setChanged(); - } - } - - protected int getSmeltTime() { - if (level == null) return 200; - int smeltTime = level.getRecipeManager().getRecipeFor(AlloyingRecipe.TYPE, this, level) - .map(AlloyingRecipe::getSmeltTime).orElse(0); - if (smeltTime == 0) { - smeltTime = level.getRecipeManager().getRecipeFor(RecipeType.BLASTING, this, level) - .map(BlastingRecipe::getCookingTime).orElse(200); - smeltTime /= 1.5; - } - return smeltTime; - } - - public void dropExperience(Player player) { - if (level == null) return; - List> list = Lists.newArrayList(); - for (Entry entry : recipesUsed.object2IntEntrySet()) { - level.getRecipeManager().byKey(entry.getKey()).ifPresent((recipe) -> { - list.add(recipe); - if (recipe instanceof AlloyingRecipe) { - AlloyingRecipe alloying = (AlloyingRecipe) recipe; - dropExperience(player.level, player.position(), entry.getIntValue(), alloying.getExperience()); - } else { - BlastingRecipe blasting = (BlastingRecipe) recipe; - dropExperience(player.level, player.position(), entry.getIntValue(), blasting.getExperience()); - } - }); - } - player.awardRecipes(list); - recipesUsed.clear(); - } - - private void dropExperience(Level world, Vec3 vec3d, int count, float amount) { - int expTotal = Mth.floor(count * amount); - float g = Mth.frac(count * amount); - if (g != 0.0F && Math.random() < g) { - expTotal++; - } - - while(expTotal > 0) { - int expVal = ExperienceOrb.getExperienceValue(expTotal); - expTotal -= expVal; - world.addFreshEntity(new ExperienceOrb(world, vec3d.x, vec3d.y, vec3d.z, expVal)); - } - } - - @Override - public boolean stillValid(Player player) { - if (level != null && level.getBlockEntity(worldPosition) != this) { - return false; - } - return player.distanceToSqr(worldPosition.getX() + 0.5D, worldPosition.getY() + 0.5D, worldPosition.getZ() + 0.5D) <= 64.0D; - } - - @Override - public void clearContent() { - inventory.clear(); - } - - @Override - protected Component getDefaultName() { - return new TranslatableComponent(String.format("block.%s.%s", BetterEnd.MOD_ID, EndStoneSmelter.ID)); - } - - @Override - protected AbstractContainerMenu createMenu(int syncId, Inventory playerInventory) { - return new EndStoneSmelterScreenHandler(syncId, playerInventory, this, propertyDelegate); - } - - @Override - public void tick() { - if (level == null) return; - - boolean initialBurning = isBurning(); - if (initialBurning) { - burnTime--; - } - - boolean burning = initialBurning; - if (!level.isClientSide) { - ItemStack fuel = inventory.get(2); - if (!burning && (fuel.isEmpty() || inventory.get(0).isEmpty() && inventory.get(1).isEmpty())) { - if (smeltTime > 0) { - smeltTime = Mth.clamp(smeltTime - 2, 0, smeltTimeTotal); - } - } else { - Recipe recipe = level.getRecipeManager().getRecipeFor(AlloyingRecipe.TYPE, this, level).orElse(null); - if (recipe == null) { - recipe = level.getRecipeManager().getRecipeFor(RecipeType.BLASTING, this, level).orElse(null); - } - boolean accepted = this.canAcceptRecipeOutput(recipe); - if (!burning && accepted) { - burnTime = getFuelTime(fuel); - fuelTime = burnTime; - burning = isBurning(); - if (burning) { - if (!fuel.isEmpty()) { - Item item = fuel.getItem(); - fuel.shrink(1); - if (fuel.isEmpty()) { - Item remainFuel = item.getCraftingRemainingItem(); - inventory.set(2, remainFuel == null ? ItemStack.EMPTY : new ItemStack(remainFuel)); - } - } - setChanged(); - } - } - - if (burning && accepted) { - this.smeltTime++; - if (smeltTime == smeltTimeTotal) { - smeltTime = 0; - smeltTimeTotal = getSmeltTime(); - craftRecipe(recipe); - setChanged(); - } - } else { - smeltTime = 0; - } - } - - if (initialBurning != burning) { - level.setBlock(worldPosition, level.getBlockState(worldPosition).setValue(EndStoneSmelter.LIT, burning), 3); - setChanged(); - } - } - } - - protected boolean canAcceptRecipeOutput(Recipe recipe) { - if (recipe == null) return false; - boolean validInput; - if (recipe instanceof AlloyingRecipe) { - validInput = !inventory.get(0).isEmpty() && - !inventory.get(1).isEmpty(); - } else { - validInput = !inventory.get(0).isEmpty() || - !inventory.get(1).isEmpty(); - } - if (validInput) { - ItemStack result = recipe.getResultItem(); - if (result.isEmpty()) { - return false; - } - ItemStack output = this.inventory.get(3); - int outCount = output.getCount(); - int total = outCount + result.getCount(); - if (output.isEmpty()) { - return true; - } - if (!output.sameItem(result)) { - return false; - } - if (outCount < getMaxStackSize() && outCount < output.getMaxStackSize()) { - return getMaxStackSize() >= total; - } - return output.getCount() < result.getMaxStackSize(); - } - return false; - } - - private void craftRecipe(Recipe recipe) { - if (recipe == null || !canAcceptRecipeOutput(recipe)) return; - - ItemStack result = recipe.getResultItem(); - ItemStack output = inventory.get(3); - if (output.isEmpty()) { - inventory.set(3, result.copy()); - } else if (output.getItem() == result.getItem()) { - output.grow(result.getCount()); - } - - assert this.level != null; - if (!this.level.isClientSide) { - setRecipeUsed(recipe); - } - - if (recipe instanceof AlloyingRecipe) { - inventory.get(0).shrink(1); - inventory.get(1).shrink(1); - } else { - if (!inventory.get(0).isEmpty()) { - inventory.get(0).shrink(1); - } else { - inventory.get(1).shrink(1); - } - } - } - - @Override - public void fillStackedContents(StackedContents finder) { - for (ItemStack itemStack : this.inventory) { - finder.accountStack(itemStack); - } - } - - @Override - public void setRecipeUsed(Recipe recipe) { - if (recipe != null) { - ResourceLocation recipeId = recipe.getId(); - recipesUsed.addTo(recipeId, 1); - lastRecipe = recipe; - } - } - - @Override - public Recipe getRecipeUsed() { - return this.lastRecipe; - } - - @Override - public int[] getSlotsForFace(Direction side) { - if (side == Direction.DOWN) { - return BOTTOM_SLOTS; - } - return side == Direction.UP ? TOP_SLOTS : SIDE_SLOTS; - } - - @Override - public boolean canPlaceItemThroughFace(int slot, ItemStack stack, Direction dir) { - return this.canPlaceItem(slot, stack); - } - - @Override - public boolean canTakeItemThroughFace(int slot, ItemStack stack, Direction dir) { - if (dir == Direction.DOWN && slot == 2) { - return stack.getItem() == Items.BUCKET; - } - return true; - } - - protected int getFuelTime(ItemStack fuel) { - if (fuel.isEmpty()) { - return 0; - } - Item item = fuel.getItem(); - return AVAILABLE_FUELS.getOrDefault(item, getFabricFuel(fuel)); - } - - @Override - public void load(BlockState state, CompoundTag tag) { - super.load(state, tag); - inventory = NonNullList.withSize(getContainerSize(), ItemStack.EMPTY); - ContainerHelper.loadAllItems(tag, inventory); - burnTime = tag.getShort("BurnTime"); - fuelTime = tag.getShort("FuelTime"); - smeltTime = tag.getShort("SmeltTime"); - smeltTimeTotal = tag.getShort("SmeltTimeTotal"); - CompoundTag compoundTag = tag.getCompound("RecipesUsed"); - for (String id : compoundTag.getAllKeys()) { - recipesUsed.put(new ResourceLocation(id), compoundTag.getInt(id)); - } - } - - @Override - public CompoundTag save(CompoundTag tag) { - super.save(tag); - tag.putShort("BurnTime", (short) burnTime); - tag.putShort("FuelTime", (short) fuelTime); - tag.putShort("SmeltTime", (short) smeltTime); - tag.putShort("SmeltTimeTotal", (short) smeltTimeTotal); - ContainerHelper.saveAllItems(tag, inventory); - CompoundTag usedRecipes = new CompoundTag(); - recipesUsed.forEach((identifier, integer) -> usedRecipes.putInt(identifier.toString(), integer)); - tag.put("RecipesUsed", usedRecipes); - - return tag; - } - - public boolean canPlaceItem(int slot, ItemStack stack) { - if (slot == 3) { - return false; - } else if (slot != 2) { - return true; - } - ItemStack itemStack = this.inventory.get(2); - return canUseAsFuel(stack) || stack.getItem() == Items.BUCKET && itemStack.getItem() != Items.BUCKET; - } - - public static boolean canUseAsFuel(ItemStack stack) { - return AVAILABLE_FUELS.containsKey(stack.getItem()) || getFabricFuel(stack) > 2000; - } - - public static void registerFuel(ItemLike fuel, int time) { - AVAILABLE_FUELS.put(fuel.asItem(), time); - } - - public static Map availableFuels() { - return AVAILABLE_FUELS; - } - - private static int getFabricFuel(ItemStack stack) { - Integer ticks = FuelRegistry.INSTANCE.get(stack.getItem()); - return ticks == null ? 0 : ticks; - } - - static { - AbstractFurnaceBlockEntity.getFuel().forEach((item, time) -> { - if (time >= 2000) { - registerFuel(item, time); - } - }); - } -} diff --git a/src/main/java/ru/betterend/blocks/entities/EternalPedestalEntity.java b/src/main/java/ru/betterend/blocks/entities/EternalPedestalEntity.java deleted file mode 100644 index d4da8a18..00000000 --- a/src/main/java/ru/betterend/blocks/entities/EternalPedestalEntity.java +++ /dev/null @@ -1,52 +0,0 @@ -package ru.betterend.blocks.entities; - -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.Level; -import ru.betterend.registry.EndBlockEntities; -import ru.betterend.rituals.EternalRitual; - -public class EternalPedestalEntity extends PedestalBlockEntity { - private EternalRitual linkedRitual; - - public EternalPedestalEntity() { - super(EndBlockEntities.ETERNAL_PEDESTAL); - } - - public boolean hasRitual() { - return linkedRitual != null; - } - - public void linkRitual(EternalRitual ritual) { - this.linkedRitual = ritual; - } - - public EternalRitual getRitual() { - return linkedRitual; - } - - @Override - public void setLevelAndPosition(Level world, BlockPos pos) { - super.setLevelAndPosition(world, pos); - if (hasRitual()) { - linkedRitual.setWorld(world); - } - } - - @Override - public CompoundTag save(CompoundTag tag) { - if (hasRitual()) { - tag.put("ritual", linkedRitual.toTag(new CompoundTag())); - } - return super.save(tag); - } - - @Override - protected void fromTag(CompoundTag tag) { - super.fromTag(tag); - if (tag.contains("ritual")) { - linkedRitual = new EternalRitual(level); - linkedRitual.fromTag(tag.getCompound("ritual")); - } - } -} diff --git a/src/main/java/ru/betterend/blocks/entities/InfusionPedestalEntity.java b/src/main/java/ru/betterend/blocks/entities/InfusionPedestalEntity.java deleted file mode 100644 index 2a6a4029..00000000 --- a/src/main/java/ru/betterend/blocks/entities/InfusionPedestalEntity.java +++ /dev/null @@ -1,63 +0,0 @@ -package ru.betterend.blocks.entities; - -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.Level; -import ru.betterend.registry.EndBlockEntities; -import ru.betterend.rituals.InfusionRitual; - -public class InfusionPedestalEntity extends PedestalBlockEntity { - - private InfusionRitual linkedRitual; - - public InfusionPedestalEntity() { - super(EndBlockEntities.INFUSION_PEDESTAL); - } - - @Override - public void setLevelAndPosition(Level world, BlockPos pos) { - super.setLevelAndPosition(world, pos); - if (hasRitual()) { - linkedRitual.setLocation(world, pos); - } else { - linkRitual(new InfusionRitual(this, world, pos)); - } - } - - public void linkRitual(InfusionRitual ritual) { - linkedRitual = ritual; - } - - public InfusionRitual getRitual() { - return linkedRitual; - } - - public boolean hasRitual() { - return linkedRitual != null; - } - - @Override - public void tick() { - if (hasRitual()) { - linkedRitual.tick(); - } - super.tick(); - } - - @Override - public CompoundTag save(CompoundTag tag) { - if (hasRitual()) { - tag.put("ritual", linkedRitual.toTag(new CompoundTag())); - } - return super.save(tag); - } - - @Override - protected void fromTag(CompoundTag tag) { - super.fromTag(tag); - if (tag.contains("ritual")) { - linkedRitual = new InfusionRitual(this, level, worldPosition); - linkedRitual.fromTag(tag.getCompound("ritual")); - } - } -} diff --git a/src/main/java/ru/betterend/blocks/entities/PedestalBlockEntity.java b/src/main/java/ru/betterend/blocks/entities/PedestalBlockEntity.java deleted file mode 100644 index 5dfe65e0..00000000 --- a/src/main/java/ru/betterend/blocks/entities/PedestalBlockEntity.java +++ /dev/null @@ -1,143 +0,0 @@ -package ru.betterend.blocks.entities; - -import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.Container; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraft.world.level.block.entity.TickableBlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import ru.betterend.blocks.basis.PedestalBlock; -import ru.betterend.registry.EndBlockEntities; -import ru.betterend.registry.EndItems; - -public class PedestalBlockEntity extends BlockEntity implements Container, TickableBlockEntity, BlockEntityClientSerializable { - private ItemStack activeItem = ItemStack.EMPTY; - - private final int maxAge = 314; - private int age; - - public PedestalBlockEntity() { - super(EndBlockEntities.PEDESTAL); - } - - public PedestalBlockEntity(BlockEntityType type) { - super(type); - } - - public int getAge() { - return age; - } - - public int getMaxAge() { - return maxAge; - } - - @Override - public int getContainerSize() { - return 1; - } - - @Override - public boolean isEmpty() { - return activeItem.isEmpty(); - } - - @Override - public ItemStack getItem(int slot) { - return activeItem; - } - - @Override - public ItemStack removeItem(int slot, int amount) { - return removeItemNoUpdate(slot); - } - - @Override - public boolean canPlaceItem(int slot, ItemStack stack) { - return isEmpty(); - } - - @Override - public void clearContent() { - activeItem = ItemStack.EMPTY; - setChanged(); - } - - @Override - public ItemStack removeItemNoUpdate(int slot) { - ItemStack stored = activeItem; - clearContent(); - return stored; - } - - @Override - public void setItem(int slot, ItemStack stack) { - activeItem = stack.split(1); - setChanged(); - } - - @Override - public void setChanged() { - if (level != null && !level.isClientSide) { - BlockState state = level.getBlockState(worldPosition); - if (state.getBlock() instanceof PedestalBlock) { - BlockState trueState = state.setValue(PedestalBlock.HAS_ITEM, !isEmpty()); - if (activeItem.getItem() == EndItems.ETERNAL_CRYSTAL) { - trueState = trueState.setValue(PedestalBlock.HAS_LIGHT, true); - } else { - trueState = trueState.setValue(PedestalBlock.HAS_LIGHT, false); - } - level.setBlockAndUpdate(worldPosition, trueState); - } - } - super.setChanged(); - } - - - @Override - public boolean stillValid(Player player) { - return true; - } - - @Override - public void load(BlockState state, CompoundTag tag) { - super.load(state, tag); - fromTag(tag); - } - - @Override - public CompoundTag save(CompoundTag tag) { - tag.put("active_item", activeItem.save(new CompoundTag())); - return super.save(tag); - } - - @Override - public void fromClientTag(CompoundTag tag) { - fromTag(tag); - } - - @Override - public CompoundTag toClientTag(CompoundTag tag) { - return save(tag); - } - - protected void fromTag(CompoundTag tag) { - if (tag.contains("active_item")) { - CompoundTag itemTag = tag.getCompound("active_item"); - activeItem = ItemStack.of(itemTag); - } - } - - @Override - public void tick() { - if (!isEmpty()) { - age++; - if (age > maxAge) { - age = 0; - } - } - } -} diff --git a/src/main/java/ru/betterend/client/BetterEndClient.java b/src/main/java/ru/betterend/client/BetterEndClient.java deleted file mode 100644 index 2a83e0c5..00000000 --- a/src/main/java/ru/betterend/client/BetterEndClient.java +++ /dev/null @@ -1,86 +0,0 @@ -package ru.betterend.client; - -import java.util.List; - -import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; -import net.minecraft.ChatFormatting; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.core.Registry; -import net.minecraft.network.chat.Style; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.world.level.block.Block; -import ru.bclib.BCLib; -import ru.bclib.blocks.BaseChestBlock; -import ru.bclib.blocks.BaseSignBlock; -import ru.bclib.client.render.BCLRenderLayer; -import ru.bclib.client.render.BaseChestBlockEntityRenderer; -import ru.bclib.client.render.BaseSignBlockEntityRenderer; -import ru.bclib.interfaces.IRenderTyped; -import ru.bclib.util.TranslationHelper; -import ru.betterend.BetterEnd; -import ru.betterend.events.ItemTooltipCallback; -import ru.betterend.interfaces.MultiModelItem; -import ru.betterend.item.CrystaliteArmor; -import ru.betterend.registry.EndBlockEntityRenders; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndEntitiesRenders; -import ru.betterend.registry.EndModelProviders; -import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndScreens; - -public class BetterEndClient implements ClientModInitializer { - @Override - public void onInitializeClient() { - registerRenderLayers(); - EndBlockEntityRenders.register(); - EndScreens.register(); - EndParticles.register(); - EndEntitiesRenders.register(); - EndModelProviders.register(); - MultiModelItem.register(); - ClientOptions.init(); - registerRenderers(); - registerTooltips(); - - if (BCLib.isDevEnvironment()) { - TranslationHelper.printMissingNames(BetterEnd.MOD_ID); - } - } - - public static void registerTooltips() { - ItemTooltipCallback.EVENT.register((player, stack, context, lines) -> { - if (stack.getItem() instanceof CrystaliteArmor) { - boolean hasSet = false; - if (player != null) { - hasSet = CrystaliteArmor.hasFullSet(player); - } - TranslatableComponent setDesc = new TranslatableComponent("tooltip.armor.crystalite_set"); - setDesc.setStyle(Style.EMPTY.applyFormats(hasSet ? ChatFormatting.BLUE : ChatFormatting.DARK_GRAY, ChatFormatting.ITALIC)); - lines.add(TextComponent.EMPTY); - lines.add(setDesc); - } - }); - } - - private void registerRenderLayers() { - RenderType cutout = RenderType.cutout(); - RenderType translucent = RenderType.translucent(); - Registry.BLOCK.forEach(block -> { - if (block instanceof IRenderTyped) { - BCLRenderLayer layer = ((IRenderTyped) block).getRenderLayer(); - if (layer == BCLRenderLayer.CUTOUT) - BlockRenderLayerMap.INSTANCE.putBlock(block, cutout); - else if (layer == BCLRenderLayer.TRANSLUCENT) - BlockRenderLayerMap.INSTANCE.putBlock(block, translucent); - } - }); - } - - private static void registerRenderers() { - List modBlocks = EndBlocks.getModBlocks(); - modBlocks.stream().filter(BaseChestBlock.class::isInstance).forEach(BaseChestBlockEntityRenderer::registerRenderLayer); - modBlocks.stream().filter(BaseSignBlock.class::isInstance).forEach(BaseSignBlockEntityRenderer::registerRenderLayer); - } -} diff --git a/src/main/java/ru/betterend/client/ClientOptions.java b/src/main/java/ru/betterend/client/ClientOptions.java deleted file mode 100644 index d80f950c..00000000 --- a/src/main/java/ru/betterend/client/ClientOptions.java +++ /dev/null @@ -1,50 +0,0 @@ -package ru.betterend.client; - -import ru.betterend.config.Configs; - -public class ClientOptions { - private static boolean customSky; - private static boolean useFogDensity; - private static boolean blendBiomeMusic; - private static boolean sulfurWaterColor; - - public static void init() { - customSky = Configs.CLENT_CONFIG.getBooleanRoot("customSky", true); - useFogDensity = Configs.CLENT_CONFIG.getBooleanRoot("useFogDensity", true); - blendBiomeMusic = Configs.CLENT_CONFIG.getBooleanRoot("blendBiomeMusic", true); - sulfurWaterColor = Configs.CLENT_CONFIG.getBooleanRoot("sulfurWaterColor", true); - Configs.CLENT_CONFIG.saveChanges(); - } - - public static boolean isCustomSky() { - return customSky; - } - - public static void setCustomSky(boolean customSky) { - ClientOptions.customSky = customSky; - } - - public static boolean useFogDensity() { - return useFogDensity; - } - - public static void setUseFogDensity(boolean useFogDensity) { - ClientOptions.useFogDensity = useFogDensity; - } - - public static boolean blendBiomeMusic() { - return blendBiomeMusic; - } - - public static void setBlendBiomeMusic(boolean blendBiomeMusic) { - ClientOptions.blendBiomeMusic = blendBiomeMusic; - } - - public static boolean useSulfurWaterColor() { - return sulfurWaterColor; - } - - public static void setSulfurWaterColor(boolean sulfurWaterColor) { - ClientOptions.sulfurWaterColor = sulfurWaterColor; - } -} diff --git a/src/main/java/ru/betterend/client/gui/EndStoneSmelterRecipeBookScreen.java b/src/main/java/ru/betterend/client/gui/EndStoneSmelterRecipeBookScreen.java deleted file mode 100644 index 1ed760f5..00000000 --- a/src/main/java/ru/betterend/client/gui/EndStoneSmelterRecipeBookScreen.java +++ /dev/null @@ -1,102 +0,0 @@ -package ru.betterend.client.gui; - -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.PoseStack; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.gui.GuiComponent; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.gui.screens.recipebook.BlastingRecipeBookComponent; -import net.minecraft.core.NonNullList; -import net.minecraft.world.inventory.Slot; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Recipe; -import ru.betterend.blocks.entities.EndStoneSmelterBlockEntity; - -@Environment(EnvType.CLIENT) -public class EndStoneSmelterRecipeBookScreen extends BlastingRecipeBookComponent { - private Iterator fuelIterator; - private Set fuels; - private Slot fuelSlot; - private Item currentItem; - private float frameTime; - - @Override - protected Set getFuelItems() { - return EndStoneSmelterBlockEntity.availableFuels().keySet(); - } - - @Override - public void slotClicked(Slot slot) { - super.slotClicked(slot); - if (slot != null && slot.index < this.menu.getSize()) { - this.fuelSlot = null; - } - } - - @Override - public void setupGhostRecipe(Recipe recipe, List slots) { - this.ghostRecipe.clear(); - ItemStack result = recipe.getResultItem(); - this.ghostRecipe.setRecipe(recipe); - this.ghostRecipe.addIngredient(Ingredient.of(result), (slots.get(3)).x, (slots.get(3)).y); - NonNullList inputs = recipe.getIngredients(); - Iterator iterator = inputs.iterator(); - for(int i = 0; i < 2; i++) { - if (!iterator.hasNext()) { - return; - } - Ingredient ingredient = iterator.next(); - if (!ingredient.isEmpty()) { - Slot slot = slots.get(i); - this.ghostRecipe.addIngredient(ingredient, slot.x, slot.y); - } - } - this.fuelSlot = slots.get(2); - if (this.fuels == null) { - this.fuels = this.getFuelItems(); - } - - this.fuelIterator = this.fuels.iterator(); - this.currentItem = null; - } - - @Override - public void renderGhostRecipe(PoseStack matrices, int x, int y, boolean bl, float f) { - this.ghostRecipe.render(matrices, minecraft, x, y, bl, f); - if (fuelSlot != null) { - if (!Screen.hasControlDown()) { - this.frameTime += f; - } - - int slotX = this.fuelSlot.x + x; - int slotY = this.fuelSlot.y + y; - GuiComponent.fill(matrices, slotX, slotY, slotX + 16, slotY + 16, 822018048); - this.minecraft.getItemRenderer().renderAndDecorateItem(minecraft.player, this.getFuel().getDefaultInstance(), slotX, slotY); - RenderSystem.depthFunc(516); - GuiComponent.fill(matrices, slotX, slotY, slotX + 16, slotY + 16, 822083583); - RenderSystem.depthFunc(515); - } - } - - private Item getFuel() { - if (this.currentItem == null || this.frameTime > 30.0F) { - this.frameTime = 0.0F; - if (this.fuelIterator == null || !this.fuelIterator.hasNext()) { - if (this.fuels == null) { - this.fuels = this.getFuelItems(); - } - this.fuelIterator = this.fuels.iterator(); - } - this.currentItem = this.fuelIterator.next(); - } - return this.currentItem; - } -} diff --git a/src/main/java/ru/betterend/client/gui/EndStoneSmelterScreen.java b/src/main/java/ru/betterend/client/gui/EndStoneSmelterScreen.java deleted file mode 100644 index c030ed9f..00000000 --- a/src/main/java/ru/betterend/client/gui/EndStoneSmelterScreen.java +++ /dev/null @@ -1,129 +0,0 @@ -package ru.betterend.client.gui; - -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.PoseStack; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.gui.components.ImageButton; -import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; -import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; -import net.minecraft.client.gui.screens.recipebook.RecipeUpdateListener; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.inventory.ClickType; -import net.minecraft.world.inventory.Slot; -import ru.betterend.BetterEnd; - -@Environment(EnvType.CLIENT) -public class EndStoneSmelterScreen extends AbstractContainerScreen implements RecipeUpdateListener { - - private final static ResourceLocation RECIPE_BUTTON_TEXTURE = new ResourceLocation("textures/gui/recipe_button.png"); - private final static ResourceLocation BACKGROUND_TEXTURE = BetterEnd.makeID("textures/gui/smelter_gui.png"); - - public final EndStoneSmelterRecipeBookScreen recipeBook; - private boolean narrow; - - public EndStoneSmelterScreen(EndStoneSmelterScreenHandler handler, Inventory inventory, Component title) { - super(handler, inventory, title); - recipeBook = new EndStoneSmelterRecipeBookScreen(); - } - - public void init() { - super.init(); - narrow = width < 379; - recipeBook.init(width, height, minecraft, narrow, menu); - leftPos = recipeBook.updateScreenPosition(narrow, width, imageWidth); - addButton(new ImageButton(leftPos + 20, height / 2 - 49, 20, 18, 0, 0, 19, RECIPE_BUTTON_TEXTURE, (buttonWidget) -> { - recipeBook.initVisuals(narrow); - recipeBook.toggleVisibility(); - leftPos = recipeBook.updateScreenPosition(narrow, width, imageWidth); - ((ImageButton) buttonWidget).setPosition(leftPos + 20, height / 2 - 49); - })); - titleLabelX = (imageWidth - font.width(title)) / 2; - } - - @Override - public void tick() { - super.tick(); - recipeBook.tick(); - } - - @Override - public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { - renderBackground(matrices); - if (recipeBook.isVisible() && narrow) { - renderBg(matrices, delta, mouseX, mouseY); - recipeBook.render(matrices, mouseX, mouseY, delta); - } else { - recipeBook.render(matrices, mouseX, mouseY, delta); - super.render(matrices, mouseX, mouseY, delta); - recipeBook.renderGhostRecipe(matrices, leftPos, topPos, true, delta); - } - renderTooltip(matrices, mouseX, mouseY); - recipeBook.renderTooltip(matrices, leftPos, topPos, mouseX, mouseY); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (this.recipeBook.mouseClicked(mouseX, mouseY, button)) { - return true; - } else { - return narrow && recipeBook.isVisible() || super.mouseClicked(mouseX, mouseY, button); - } - } - - @Override - protected void slotClicked(Slot slot, int invSlot, int clickData, ClickType actionType) { - super.slotClicked(slot, invSlot, clickData, actionType); - this.recipeBook.slotClicked(slot); - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - return !recipeBook.keyPressed(keyCode, scanCode, modifiers) && super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - protected boolean hasClickedOutside(double mouseX, double mouseY, int left, int top, int button) { - boolean isMouseOut = mouseX < left || mouseY < top || mouseX >= (left + imageWidth) || mouseY >= (top + imageHeight); - return this.recipeBook.hasClickedOutside(mouseX, mouseY, leftPos, topPos, imageWidth, imageHeight, button) && isMouseOut; - } - - @Override - public boolean charTyped(char chr, int keyCode) { - return recipeBook.charTyped(chr, keyCode) || super.charTyped(chr, keyCode); - } - - @Override - public void recipesUpdated() { - recipeBook.recipesUpdated(); - } - - @Override - public RecipeBookComponent getRecipeBookComponent() { - return recipeBook; - } - - @Override - protected void renderBg(PoseStack matrices, float delta, int mouseX, int mouseY) { - if (minecraft == null) return; - RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); - minecraft.getTextureManager().bind(BACKGROUND_TEXTURE); - blit(matrices, leftPos, topPos, 0, 0, imageWidth, imageHeight); - int progress; - if (menu.isBurning()) { - progress = menu.getFuelProgress(); - blit(matrices, leftPos + 56, topPos + 36 + 12 - progress, 176, 12 - progress, 14, progress + 1); - } - progress = menu.getSmeltProgress(); - blit(matrices, leftPos + 92, topPos + 34, 176, 14, progress + 1, 16); - } - - @Override - public void removed() { - recipeBook.removed(); - super.removed(); - } -} diff --git a/src/main/java/ru/betterend/client/gui/EndStoneSmelterScreenHandler.java b/src/main/java/ru/betterend/client/gui/EndStoneSmelterScreenHandler.java deleted file mode 100644 index e2c98053..00000000 --- a/src/main/java/ru/betterend/client/gui/EndStoneSmelterScreenHandler.java +++ /dev/null @@ -1,190 +0,0 @@ -package ru.betterend.client.gui; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry; -import net.minecraft.world.Container; -import net.minecraft.world.SimpleContainer; -import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.entity.player.StackedContents; -import net.minecraft.world.inventory.ContainerData; -import net.minecraft.world.inventory.MenuType; -import net.minecraft.world.inventory.RecipeBookMenu; -import net.minecraft.world.inventory.RecipeBookType; -import net.minecraft.world.inventory.SimpleContainerData; -import net.minecraft.world.inventory.Slot; -import net.minecraft.world.inventory.StackedContentsCompatible; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Recipe; -import net.minecraft.world.level.Level; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.EndStoneSmelter; -import ru.betterend.blocks.entities.EndStoneSmelterBlockEntity; -import ru.betterend.client.gui.slot.SmelterFuelSlot; -import ru.betterend.client.gui.slot.SmelterOutputSlot; -import ru.betterend.recipe.builders.AlloyingRecipe; - -public class EndStoneSmelterScreenHandler extends RecipeBookMenu { - - public final static MenuType HANDLER_TYPE = ScreenHandlerRegistry.registerSimple( - BetterEnd.makeID(EndStoneSmelter.ID), EndStoneSmelterScreenHandler::new); - - private final Container inventory; - private final ContainerData propertyDelegate; - protected final Level world; - - public EndStoneSmelterScreenHandler(int syncId, Inventory playerInventory) { - this(syncId, playerInventory, new SimpleContainer(4), new SimpleContainerData(4)); - } - - public EndStoneSmelterScreenHandler(int syncId, Inventory playerInventory, Container inventory, ContainerData propertyDelegate) { - super(HANDLER_TYPE, syncId); - this.inventory = inventory; - this.propertyDelegate = propertyDelegate; - this.world = playerInventory.player.level; - - addDataSlots(propertyDelegate); - addSlot(new Slot(inventory, 0, 45, 17)); - addSlot(new Slot(inventory, 1, 67, 17)); - addSlot(new SmelterFuelSlot(this, inventory, 2, 56, 53)); - addSlot(new SmelterOutputSlot(playerInventory.player, inventory, 3, 129, 35)); - - for(int i = 0; i < 3; ++i) { - for(int j = 0; j < 9; ++j) { - addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); - } - } - for(int i = 0; i < 9; ++i) { - addSlot(new Slot(playerInventory, i, 8 + i * 18, 142)); - } - } - - @Override - public MenuType getType() { - return HANDLER_TYPE; - } - - @Override - public void fillCraftSlotsStackedContents(StackedContents finder) { - if (inventory instanceof StackedContentsCompatible) { - ((StackedContentsCompatible) inventory).fillStackedContents(finder); - } - } - - @Override - public void clearCraftingContent() { - inventory.clearContent(); - } - - @Override - public boolean recipeMatches(Recipe recipe) { - return recipe.matches(inventory, world); - } - - @Override - public int getResultSlotIndex() { - return 3; - } - - @Override - public int getGridWidth() { - return 2; - } - - @Override - public int getGridHeight() { - return 1; - } - - @Override - public int getSize() { - return 4; - } - - @Override - public RecipeBookType getRecipeBookType() { - return RecipeBookType.BLAST_FURNACE; - } - - @Override - public boolean stillValid(Player player) { - return inventory.stillValid(player); - } - - protected boolean isSmeltable(ItemStack itemStack) { - return world.getRecipeManager().getRecipeFor(AlloyingRecipe.TYPE, new SimpleContainer(itemStack), world).isPresent(); - } - - public boolean isFuel(ItemStack itemStack) { - return EndStoneSmelterBlockEntity.canUseAsFuel(itemStack); - } - - @Override - public ItemStack quickMoveStack(Player player, int index) { - Slot slot = slots.get(index); - if (slot == null || !slot.hasItem()) return ItemStack.EMPTY; - - ItemStack slotStack = slot.getItem(); - ItemStack itemStack = slotStack.copy(); - if (index == 3) { - if (!moveItemStackTo(slotStack, 4, 40, true)) { - return ItemStack.EMPTY; - } - slot.onQuickCraft(slotStack, itemStack); - } else if (index != 2 && index != 1 && index != 0) { - if (isSmeltable(slotStack)) { - if (!moveItemStackTo(slotStack, 0, 2, false)) { - return ItemStack.EMPTY; - } - } else if (isFuel(slotStack)) { - if (!moveItemStackTo(slotStack, 2, 3, false)) { - return ItemStack.EMPTY; - } - } else if (index < 31) { - if (!moveItemStackTo(slotStack, 31, 40, false)) { - return ItemStack.EMPTY; - } - } else if (index < 40 && !moveItemStackTo(slotStack, 4, 31, false)) { - return ItemStack.EMPTY; - } - } else if (!moveItemStackTo(slotStack, 4, 40, false)) { - return ItemStack.EMPTY; - } - - if (slotStack.isEmpty()) { - slot.set(ItemStack.EMPTY); - } else { - slot.setChanged(); - } - - if (slotStack.getCount() == itemStack.getCount()) { - return ItemStack.EMPTY; - } - - slot.onTake(player, slotStack); - - return itemStack; - } - - @Environment(EnvType.CLIENT) - public int getSmeltProgress() { - int time = propertyDelegate.get(2); - int timeTotal = propertyDelegate.get(3); - return timeTotal != 0 && time != 0 ? time * 24 / timeTotal : 0; - } - - @Environment(EnvType.CLIENT) - public int getFuelProgress() { - int fuelTime = propertyDelegate.get(1); - if (fuelTime == 0) { - fuelTime = 200; - } - return propertyDelegate.get(0) * 13 / fuelTime; - } - - @Environment(EnvType.CLIENT) - public boolean isBurning() { - return propertyDelegate.get(0) > 0; - } -} diff --git a/src/main/java/ru/betterend/client/gui/slot/SmelterFuelSlot.java b/src/main/java/ru/betterend/client/gui/slot/SmelterFuelSlot.java deleted file mode 100644 index 06ec70a5..00000000 --- a/src/main/java/ru/betterend/client/gui/slot/SmelterFuelSlot.java +++ /dev/null @@ -1,25 +0,0 @@ -package ru.betterend.client.gui.slot; - -import net.minecraft.world.Container; -import net.minecraft.world.inventory.FurnaceFuelSlot; -import net.minecraft.world.inventory.Slot; -import net.minecraft.world.item.ItemStack; -import ru.betterend.client.gui.EndStoneSmelterScreenHandler; - -public class SmelterFuelSlot extends Slot { - - private final EndStoneSmelterScreenHandler handler; - - public SmelterFuelSlot(EndStoneSmelterScreenHandler handler, Container inventory, int index, int x, int y) { - super(inventory, index, x, y); - this.handler = handler; - } - - public boolean mayPlace(ItemStack stack) { - return this.handler.isFuel(stack) || FurnaceFuelSlot.isBucket(stack); - } - - public int getMaxStackSize(ItemStack stack) { - return FurnaceFuelSlot.isBucket(stack) ? 1 : super.getMaxStackSize(stack); - } -} diff --git a/src/main/java/ru/betterend/client/gui/slot/SmelterOutputSlot.java b/src/main/java/ru/betterend/client/gui/slot/SmelterOutputSlot.java deleted file mode 100644 index 212eb179..00000000 --- a/src/main/java/ru/betterend/client/gui/slot/SmelterOutputSlot.java +++ /dev/null @@ -1,49 +0,0 @@ -package ru.betterend.client.gui.slot; - -import net.minecraft.world.Container; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.Slot; -import net.minecraft.world.item.ItemStack; -import ru.betterend.blocks.entities.EndStoneSmelterBlockEntity; - -public class SmelterOutputSlot extends Slot { - - private Player player; - private int amount; - - public SmelterOutputSlot(Player player, Container inventory, int index, int x, int y) { - super(inventory, index, x, y); - this.player = player; - } - - public boolean mayPlace(ItemStack stack) { - return false; - } - - public ItemStack remove(int amount) { - if (this.hasItem()) { - this.amount += Math.min(amount, this.getItem().getCount()); - } - - return super.remove(amount); - } - - public ItemStack onTake(Player player, ItemStack stack) { - this.checkTakeAchievements(stack); - super.onTake(player, stack); - return stack; - } - - protected void onQuickCraft(ItemStack stack, int amount) { - this.amount += amount; - this.checkTakeAchievements(stack); - } - - protected void checkTakeAchievements(ItemStack stack) { - stack.onCraftedBy(this.player.level, this.player, this.amount); - if (!this.player.level.isClientSide && this.container instanceof EndStoneSmelterBlockEntity) { - ((EndStoneSmelterBlockEntity) this.container).dropExperience(player); - } - this.amount = 0; - } -} diff --git a/src/main/java/ru/betterend/client/models/Patterns.java b/src/main/java/ru/betterend/client/models/Patterns.java deleted file mode 100644 index d78a1327..00000000 --- a/src/main/java/ru/betterend/client/models/Patterns.java +++ /dev/null @@ -1,139 +0,0 @@ -package ru.betterend.client.models; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.charset.StandardCharsets; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.stream.Collectors; - -import com.google.common.collect.Maps; - -import net.minecraft.client.Minecraft; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceManager; -import ru.betterend.BetterEnd; - -public class Patterns { - //Block Models - public final static ResourceLocation BLOCK_EMPTY = BetterEnd.makeID("patterns/block/empty.json"); - public final static ResourceLocation BLOCK_BASE = BetterEnd.makeID("patterns/block/block.json"); - public final static ResourceLocation BLOCK_SIDED = BetterEnd.makeID("patterns/block/block_sided.json"); - public final static ResourceLocation BLOCK_BOTTOM_TOP = BetterEnd.makeID("patterns/block/block_bottom_top.json"); - public final static ResourceLocation BLOCK_SLAB = BetterEnd.makeID("patterns/block/slab.json"); - public final static ResourceLocation BLOCK_STAIR = BetterEnd.makeID("patterns/block/stairs.json"); - public final static ResourceLocation BLOCK_STAIR_INNER = BetterEnd.makeID("patterns/block/inner_stairs.json"); - public final static ResourceLocation BLOCK_STAIR_OUTER = BetterEnd.makeID("patterns/block/outer_stairs.json"); - public final static ResourceLocation BLOCK_WALL_POST = BetterEnd.makeID("patterns/block/wall_post.json"); - public final static ResourceLocation BLOCK_WALL_SIDE = BetterEnd.makeID("patterns/block/wall_side.json"); - public final static ResourceLocation BLOCK_WALL_SIDE_TALL = BetterEnd.makeID("patterns/block/wall_side_tall.json"); - public final static ResourceLocation BLOCK_FENCE_POST = BetterEnd.makeID("patterns/block/fence_post.json"); - public final static ResourceLocation BLOCK_FENCE_SIDE = BetterEnd.makeID("patterns/block/fence_side.json"); - public final static ResourceLocation BLOCK_BUTTON = BetterEnd.makeID("patterns/block/button.json"); - public final static ResourceLocation BLOCK_BUTTON_PRESSED = BetterEnd.makeID("patterns/block/button_pressed.json"); - public final static ResourceLocation BLOCK_PILLAR = BetterEnd.makeID("patterns/block/pillar.json"); - public final static ResourceLocation BLOCK_PLATE_UP = BetterEnd.makeID("patterns/block/pressure_plate_up.json"); - public final static ResourceLocation BLOCK_PLATE_DOWN = BetterEnd.makeID("patterns/block/pressure_plate_down.json"); - public final static ResourceLocation BLOCK_DOOR_TOP = BetterEnd.makeID("patterns/block/door_top.json"); - public final static ResourceLocation BLOCK_DOOR_TOP_HINGE = BetterEnd.makeID("patterns/block/door_top_hinge.json"); - public final static ResourceLocation BLOCK_DOOR_BOTTOM = BetterEnd.makeID("patterns/block/door_bottom.json"); - public final static ResourceLocation BLOCK_DOOR_BOTTOM_HINGE = BetterEnd.makeID("patterns/block/door_bottom_hinge.json"); - public final static ResourceLocation BLOCK_CROSS = BetterEnd.makeID("patterns/block/cross.json"); - public final static ResourceLocation BLOCK_CROSS_SHADED = BetterEnd.makeID("patterns/block/cross_shaded.json"); - public final static ResourceLocation BLOCK_GATE_CLOSED = BetterEnd.makeID("patterns/block/fence_gate_closed.json"); - public final static ResourceLocation BLOCK_GATE_CLOSED_WALL = BetterEnd.makeID("patterns/block/wall_gate_closed.json"); - public final static ResourceLocation BLOCK_GATE_OPEN = BetterEnd.makeID("patterns/block/fence_gate_open.json"); - public final static ResourceLocation BLOCK_GATE_OPEN_WALL = BetterEnd.makeID("patterns/block/wall_gate_open.json"); - public final static ResourceLocation BLOCK_TRAPDOOR = BetterEnd.makeID("patterns/block/trapdoor.json"); - public final static ResourceLocation BLOCK_LADDER = BetterEnd.makeID("patterns/block/ladder.json"); - public final static ResourceLocation BLOCK_BARREL_OPEN = BetterEnd.makeID("patterns/block/barrel_open.json"); - public final static ResourceLocation BLOCK_PEDESTAL_DEFAULT = BetterEnd.makeID("patterns/block/pedestal_default.json"); - public final static ResourceLocation BLOKC_PEDESTAL_COLUMN = BetterEnd.makeID("patterns/block/pedestal_column.json"); - public final static ResourceLocation BLOCK_PEDESTAL_COLUMN_TOP = BetterEnd.makeID("patterns/block/pedestal_column_top.json"); - public final static ResourceLocation BLOCK_PEDESTAL_TOP = BetterEnd.makeID("patterns/block/pedestal_top.json"); - public final static ResourceLocation BLOCK_PEDESTAL_BOTTOM = BetterEnd.makeID("patterns/block/pedestal_bottom.json"); - public final static ResourceLocation BLOCK_PEDESTAL_PILLAR = BetterEnd.makeID("patterns/block/pedestal_pillar.json"); - public final static ResourceLocation BLOCK_BOOKSHELF = BetterEnd.makeID("patterns/block/bookshelf.json"); - public final static ResourceLocation BLOCK_STONE_LANTERN_CEIL = BetterEnd.makeID("patterns/block/stone_lantern_ceil.json"); - public final static ResourceLocation BLOCK_STONE_LANTERN_FLOOR = BetterEnd.makeID("patterns/block/stone_lantern_floor.json"); - public final static ResourceLocation BLOCK_BULB_LANTERN_FLOOR = BetterEnd.makeID("patterns/block/bulb_lantern_floor.json"); - public final static ResourceLocation BLOCK_BULB_LANTERN_CEIL = BetterEnd.makeID("patterns/block/bulb_lantern_ceil.json"); - public final static ResourceLocation BLOCK_PETAL_COLORED = BetterEnd.makeID("models/block/block_petal_colored.json"); - public final static ResourceLocation BLOCK_COMPOSTER = BetterEnd.makeID("patterns/block/composter.json"); - public final static ResourceLocation BLOCK_COLORED = BetterEnd.makeID("patterns/block/block_colored.json"); - public final static ResourceLocation BLOCK_BARS_POST = BetterEnd.makeID("patterns/block/bars_post.json"); - public final static ResourceLocation BLOCK_BARS_SIDE = BetterEnd.makeID("patterns/block/bars_side.json"); - public final static ResourceLocation BLOCK_ANVIL = BetterEnd.makeID("patterns/block/anvil.json"); - public final static ResourceLocation BLOCK_CHAIN = BetterEnd.makeID("patterns/block/chain.json"); - public final static ResourceLocation BLOCK_CHANDELIER_FLOOR = BetterEnd.makeID("patterns/block/chandelier_floor.json"); - public final static ResourceLocation BLOCK_CHANDELIER_WALL = BetterEnd.makeID("patterns/block/chandelier_wall.json"); - public final static ResourceLocation BLOCK_CHANDELIER_CEIL = BetterEnd.makeID("patterns/block/chandelier_ceil.json"); - public final static ResourceLocation BLOCK_FURNACE = BetterEnd.makeID("patterns/block/furnace.json"); - public final static ResourceLocation BLOCK_FURNACE_LIT = BetterEnd.makeID("patterns/block/furnace_glow.json"); - public final static ResourceLocation BLOCK_TOP_SIDE_BOTTOM = BetterEnd.makeID("patterns/block/top_side_bottom.json"); - public final static ResourceLocation BLOCK_PATH = BetterEnd.makeID("patterns/block/path.json"); - - //Item Models - public final static ResourceLocation ITEM_WALL = BetterEnd.makeID("patterns/item/pattern_wall.json"); - public final static ResourceLocation ITEM_FENCE = BetterEnd.makeID("patterns/item/pattern_fence.json"); - public final static ResourceLocation ITEM_BUTTON = BetterEnd.makeID("patterns/item/pattern_button.json"); - public final static ResourceLocation ITEM_CHEST = BetterEnd.makeID("patterns/item/pattern_chest.json"); - public final static ResourceLocation ITEM_BLOCK = BetterEnd.makeID("patterns/item/pattern_block_item.json"); - public final static ResourceLocation ITEM_GENERATED = BetterEnd.makeID("patterns/item/pattern_item_generated.json"); - public final static ResourceLocation ITEM_HANDHELD = BetterEnd.makeID("patterns/item/pattern_item_handheld.json"); - public final static ResourceLocation ITEM_SPAWN_EGG = BetterEnd.makeID("patterns/item/pattern_item_spawn_egg.json"); - - public static Optional createItemGenerated(String name) { - return createJson(ITEM_GENERATED, name); - } - - public static Optional createBlockSimple(String name) { - return Patterns.createJson(Patterns.BLOCK_BASE, name, name); - } - public static Optional createBlockPillar(String name) { - return Patterns.createJson(Patterns.BLOCK_PILLAR, name, name); - } - - public static String createJson(Reader data, String parent, String block) { - try (BufferedReader buffer = new BufferedReader(data)) { - return buffer.lines().collect(Collectors.joining()) - .replace("%parent%", parent) - .replace("%block%", block); - } catch (Exception ex) { - return null; - } - } - - public static Optional createJson(ResourceLocation patternId, String parent, String block) { - ResourceManager resourceManager = Minecraft.getInstance().getResourceManager(); - try (InputStream input = resourceManager.getResource(patternId).getInputStream()) { - return Optional.ofNullable(createJson(new InputStreamReader(input, StandardCharsets.UTF_8), parent, block)); - } catch (Exception ex) { - return Optional.empty(); - } - } - - public static Optional createJson(ResourceLocation patternId, String texture) { - Map textures = Maps.newHashMap(); - textures.put("%texture%", texture); - return createJson(patternId, textures); - } - - public static Optional createJson(ResourceLocation patternId, Map textures) { - ResourceManager resourceManager = Minecraft.getInstance().getResourceManager(); - try (InputStream input = resourceManager.getResource(patternId).getInputStream()) { - String json = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)) - .lines().collect(Collectors.joining()); - for (Entry texture : textures.entrySet()) { - json = json.replace(texture.getKey(), texture.getValue()); - } - return Optional.of(json); - } catch (Exception ex) { - return Optional.empty(); - } - } - -} diff --git a/src/main/java/ru/betterend/client/render/ArmoredElytraLayer.java b/src/main/java/ru/betterend/client/render/ArmoredElytraLayer.java deleted file mode 100644 index 6f729286..00000000 --- a/src/main/java/ru/betterend/client/render/ArmoredElytraLayer.java +++ /dev/null @@ -1,51 +0,0 @@ -package ru.betterend.client.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import net.minecraft.client.model.EntityModel; -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.entity.ItemRenderer; -import net.minecraft.client.renderer.entity.RenderLayerParent; -import net.minecraft.client.renderer.entity.layers.ElytraLayer; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.player.PlayerModelPart; -import net.minecraft.world.item.ItemStack; -import ru.betterend.interfaces.FallFlyingItem; -import ru.betterend.item.model.ArmoredElytraModel; - -public class ArmoredElytraLayer> extends ElytraLayer { - private final ArmoredElytraModel elytraModel = new ArmoredElytraModel<>(); - - public ArmoredElytraLayer(RenderLayerParent renderLayerParent) { - super(renderLayerParent); - } - - public void render(PoseStack poseStack, MultiBufferSource multiBufferSource, int i, T livingEntity, float f, float g, float h, float j, float k, float l) { - ItemStack itemStack = livingEntity.getItemBySlot(EquipmentSlot.CHEST); - if (itemStack.getItem() instanceof FallFlyingItem) { - ResourceLocation wingsTexture = ((FallFlyingItem) itemStack.getItem()).getModelTexture(); - if (livingEntity instanceof AbstractClientPlayer) { - AbstractClientPlayer abstractClientPlayer = (AbstractClientPlayer) livingEntity; - if (abstractClientPlayer.isElytraLoaded() && abstractClientPlayer.getElytraTextureLocation() != null) { - wingsTexture = abstractClientPlayer.getElytraTextureLocation(); - } else if (abstractClientPlayer.isCapeLoaded() && abstractClientPlayer.getCloakTextureLocation() != null && abstractClientPlayer.isModelPartShown(PlayerModelPart.CAPE)) { - wingsTexture = abstractClientPlayer.getCloakTextureLocation(); - } - } - - poseStack.pushPose(); - poseStack.translate(0.0D, 0.0D, 0.125D); - getParentModel().copyPropertiesTo(elytraModel); - elytraModel.setupAnim(livingEntity, f, g, j, k, l); - VertexConsumer vertexConsumer = ItemRenderer.getArmorFoilBuffer(multiBufferSource, RenderType.armorCutoutNoCull(wingsTexture), false, itemStack.hasFoil()); - elytraModel.renderToBuffer(poseStack, vertexConsumer, i, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); - poseStack.popPose(); - } - } -} diff --git a/src/main/java/ru/betterend/client/render/BeamRenderer.java b/src/main/java/ru/betterend/client/render/BeamRenderer.java deleted file mode 100644 index 88de8add..00000000 --- a/src/main/java/ru/betterend/client/render/BeamRenderer.java +++ /dev/null @@ -1,63 +0,0 @@ -package ru.betterend.client.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import com.mojang.math.Matrix3f; -import com.mojang.math.Matrix4f; -import com.mojang.math.Vector3f; - -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Mth; - -public class BeamRenderer { - private static final ResourceLocation BEAM_TEXTURE = new ResourceLocation("textures/entity/end_gateway_beam.png"); - - public static void renderLightBeam(PoseStack matrices, MultiBufferSource vertexConsumers, int age, float tick, int minY, int maxY, float[] colors, float alpha, float beamIn, float beamOut) { - float red = colors[0]; - float green = colors[1]; - float blue = colors[2]; - - int maxBY = minY + maxY; - float delta = maxY < 0 ? tick : -tick; - float fractDelta = Mth.frac(delta * 0.2F - (float) Mth.floor(delta * 0.1F)); - float xIn = -beamIn; - float minV = Mth.clamp(fractDelta - 1.0F, 0.0F, 1.0F); - float maxV = (float) maxY * (0.5F / beamIn) + minV; - float rotation = (age + tick) / 25.0F + 6.0F; - - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderType.beaconBeam(BEAM_TEXTURE, true)); - - matrices.pushPose(); - matrices.mulPose(Vector3f.YP.rotation(-rotation)); - renderBeam(matrices, vertexConsumer, red, green, blue, alpha, minY, maxBY, beamIn, 0.0F, 0.0F, beamIn, 0.0F, xIn, xIn, 0.0F, 0.0F, 1.0F, minV, maxV); - - float xOut = -beamOut; - maxV = (float) maxY + minV; - renderBeam(matrices, vertexConsumer, red, green, blue, alpha, minY, maxBY, xOut, xOut, beamOut, xOut, xOut, beamOut, beamOut, beamOut, 0.0F, 1.0F, minV, maxV); - matrices.popPose(); - } - - private static void renderBeam(PoseStack matrices, VertexConsumer vertexConsumer, float red, float green, float blue, float alpha, int minY, int maxY, float x1, float d1, float x2, float d2, float x3, float d3, float x4, float d4, float minU, float maxU, float minV, float maxV) { - PoseStack.Pose entry = matrices.last(); - Matrix4f matrix4f = entry.pose(); - Matrix3f matrix3f = entry.normal(); - renderBeam(matrix4f, matrix3f, vertexConsumer, red, green, blue, alpha, maxY, minY, x1, d1, x2, d2, minU, maxU, minV, maxV); - renderBeam(matrix4f, matrix3f, vertexConsumer, red, green, blue, alpha, maxY, minY, x4, d4, x3, d3, minU, maxU, minV, maxV); - renderBeam(matrix4f, matrix3f, vertexConsumer, red, green, blue, alpha, maxY, minY, x2, d2, x4, d4, minU, maxU, minV, maxV); - renderBeam(matrix4f, matrix3f, vertexConsumer, red, green, blue, alpha, maxY, minY, x3, d3, x1, d1, minU, maxU, minV, maxV); - } - - private static void renderBeam(Matrix4f matrix4f, Matrix3f matrix3f, VertexConsumer vertexConsumer, float red, float green, float blue, float alpha, int minY, int maxY, float minX, float minD, float maxX, float maxD, float minU, float maxU, float minV, float maxV) { - addVertex(matrix4f, matrix3f, vertexConsumer, red, green, blue, alpha, maxX, minY, maxD, maxU, minV); - addVertex(matrix4f, matrix3f, vertexConsumer, red, green, blue, alpha, maxX, maxY, maxD, maxU, maxV); - addVertex(matrix4f, matrix3f, vertexConsumer, red, green, blue, alpha, minX, maxY, minD, minU, maxV); - addVertex(matrix4f, matrix3f, vertexConsumer, red, green, blue, alpha, minX, minY, minD, minU, minV); - } - - private static void addVertex(Matrix4f matrix4f, Matrix3f matrix3f, VertexConsumer vertexConsumer, float red, float green, float blue, float alpha, float x, float y, float d, float u, float v) { - vertexConsumer.vertex(matrix4f, x, y, d).color(red, green, blue, alpha).uv(u, v).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(15728880).normal(matrix3f, 0.0F, 1.0F, 0.0F).endVertex(); - } -} diff --git a/src/main/java/ru/betterend/client/render/EndCrystalRenderer.java b/src/main/java/ru/betterend/client/render/EndCrystalRenderer.java deleted file mode 100644 index c75dfc93..00000000 --- a/src/main/java/ru/betterend/client/render/EndCrystalRenderer.java +++ /dev/null @@ -1,54 +0,0 @@ -package ru.betterend.client.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import com.mojang.math.Quaternion; -import com.mojang.math.Vector3f; - -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.resources.ResourceLocation; - -public class EndCrystalRenderer { - private static final ResourceLocation CRYSTAL_TEXTURE = new ResourceLocation("textures/entity/end_crystal/end_crystal.png"); - private static final ResourceLocation CRYSTAL_BEAM_TEXTURE = new ResourceLocation("textures/entity/end_crystal/end_crystal_beam.png"); - private static final RenderType END_CRYSTAL; - private static final ModelPart CORE; - private static final ModelPart FRAME; - private static final int AGE_CYCLE = 240; - private static final float SINE_45_DEGREES; - - public static void render(int age, int maxAge, float tickDelta, PoseStack matrices, MultiBufferSource vertexConsumerProvider, int light) { - float k = (float) AGE_CYCLE / maxAge; - float rotation = (age * k + tickDelta) * 3.0F; - VertexConsumer vertexConsumer = vertexConsumerProvider.getBuffer(END_CRYSTAL); - matrices.pushPose(); - matrices.scale(0.8F, 0.8F, 0.8F); - matrices.translate(0.0D, -0.5D, 0.0D); - matrices.mulPose(Vector3f.YP.rotationDegrees(rotation)); - matrices.translate(0.0D, 0.8F, 0.0D); - matrices.mulPose(new Quaternion(new Vector3f(SINE_45_DEGREES, 0.0F, SINE_45_DEGREES), 60.0F, true)); - FRAME.render(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY); - matrices.scale(0.875F, 0.875F, 0.875F); - matrices.mulPose(new Quaternion(new Vector3f(SINE_45_DEGREES, 0.0F, SINE_45_DEGREES), 60.0F, true)); - matrices.mulPose(Vector3f.YP.rotationDegrees(rotation)); - FRAME.render(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY); - matrices.scale(0.875F, 0.875F, 0.875F); - matrices.mulPose(new Quaternion(new Vector3f(SINE_45_DEGREES, 0.0F, SINE_45_DEGREES), 60.0F, true)); - matrices.mulPose(Vector3f.YP.rotationDegrees(rotation)); - CORE.render(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY); - matrices.popPose(); - } - - static { - END_CRYSTAL = RenderType.entityCutoutNoCull(CRYSTAL_TEXTURE); - RenderType.entitySmoothCutout(CRYSTAL_BEAM_TEXTURE); - SINE_45_DEGREES = (float) Math.sin(0.7853981633974483D); - FRAME = new ModelPart(64, 32, 0, 0); - FRAME.addBox(-4.0F, -4.0F, -4.0F, 8.0F, 8.0F, 8.0F); - CORE = new ModelPart(64, 32, 32, 0); - CORE.addBox(-4.0F, -4.0F, -4.0F, 8.0F, 8.0F, 8.0F); - } -} diff --git a/src/main/java/ru/betterend/client/render/EternalCrystalRenderer.java b/src/main/java/ru/betterend/client/render/EternalCrystalRenderer.java deleted file mode 100644 index f9100d9d..00000000 --- a/src/main/java/ru/betterend/client/render/EternalCrystalRenderer.java +++ /dev/null @@ -1,70 +0,0 @@ -package ru.betterend.client.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import com.mojang.math.Vector3f; - -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.core.Vec3i; -import net.minecraft.util.Mth; -import ru.bclib.util.ColorUtil; -import ru.bclib.util.MHelper; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.AuroraCrystalBlock; - -public class EternalCrystalRenderer { - private static final RenderType RENDER_LAYER; - private static final ModelPart[] SHARDS; - private static final ModelPart CORE; - - public static void render(int age, float tickDelta, PoseStack matrices, MultiBufferSource vertexConsumerProvider, int light) { - VertexConsumer vertexConsumer = vertexConsumerProvider.getBuffer(RENDER_LAYER); - float[] colors = colors(age); - float rotation = (age + tickDelta) / 25.0F + 6.0F; - matrices.pushPose(); - matrices.scale(0.6F, 0.6F, 0.6F); - matrices.mulPose(Vector3f.YP.rotation(rotation)); - CORE.render(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, colors[0], colors[1], colors[2], colors[3]); - - for (int i = 0; i < 4; i++) { - matrices.pushPose(); - float offset = Mth.sin(rotation * 2 + i) * 0.15F; - matrices.translate(0, offset, 0); - SHARDS[i].render(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, colors[0], colors[1], colors[2], colors[3]); - matrices.popPose(); - } - - matrices.popPose(); - } - - public static float[] colors(int age) { - double delta = age * 0.01; - int index = MHelper.floor(delta); - int index2 = (index + 1) & 3; - delta -= index; - index &= 3; - - Vec3i color1 = AuroraCrystalBlock.COLORS[index]; - Vec3i color2 = AuroraCrystalBlock.COLORS[index2]; - - int r = MHelper.floor(Mth.lerp(delta, color1.getX(), color2.getX())); - int g = MHelper.floor(Mth.lerp(delta, color1.getY(), color2.getY())); - int b = MHelper.floor(Mth.lerp(delta, color1.getZ(), color2.getZ())); - - return ColorUtil.toFloatArray(ColorUtil.color(r, g, b)); - } - - static { - RENDER_LAYER = RenderType.beaconBeam(BetterEnd.makeID("textures/entity/eternal_crystal.png"), true); - SHARDS = new ModelPart[4]; - SHARDS[0] = new ModelPart(16, 16, 2, 4).addBox(-5.0F, 1.0F, -3.0F, 2.0F, 8.0F, 2.0F); - SHARDS[1] = new ModelPart(16, 16, 2, 4).addBox(3.0F, -1.0F, -1.0F, 2.0F, 8.0F, 2.0F); - SHARDS[2] = new ModelPart(16, 16, 2, 4).addBox(-1.0F, 0.0F, -5.0F, 2.0F, 4.0F, 2.0F); - SHARDS[3] = new ModelPart(16, 16, 2, 4).addBox(0.0F, 3.0F, 4.0F, 2.0F, 6.0F, 2.0F); - CORE = new ModelPart(16, 16, 0, 0); - CORE.addBox(-2.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F); - } -} diff --git a/src/main/java/ru/betterend/client/render/PedestalItemRenderer.java b/src/main/java/ru/betterend/client/render/PedestalItemRenderer.java deleted file mode 100644 index e66cdee8..00000000 --- a/src/main/java/ru/betterend/client/render/PedestalItemRenderer.java +++ /dev/null @@ -1,77 +0,0 @@ -package ru.betterend.client.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Vector3f; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.block.model.ItemTransforms; -import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher; -import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.util.Mth; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; -import ru.betterend.blocks.EternalPedestal; -import ru.betterend.blocks.basis.PedestalBlock; -import ru.betterend.blocks.entities.PedestalBlockEntity; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -@Environment(EnvType.CLIENT) -public class PedestalItemRenderer extends BlockEntityRenderer { - - public PedestalItemRenderer(BlockEntityRenderDispatcher dispatcher) { - super(dispatcher); - } - - @Override - public void render(T blockEntity, float tickDelta, PoseStack matrices, - MultiBufferSource vertexConsumers, int light, int overlay) { - - Level world = blockEntity.getLevel(); - if (world == null || blockEntity.isEmpty()) return; - - BlockState state = world.getBlockState(blockEntity.getBlockPos()); - if (!(state.getBlock() instanceof PedestalBlock)) return; - - ItemStack activeItem = blockEntity.getItem(0); - - matrices.pushPose(); - Minecraft minecraft = Minecraft.getInstance(); - BakedModel model = minecraft.getItemRenderer().getModel(activeItem, world, null); - Vector3f translate = model.getTransforms().ground.translation; - PedestalBlock pedestal = (PedestalBlock) state.getBlock(); - matrices.translate(translate.x(), translate.y(), translate.z()); - matrices.translate(0.5, pedestal.getHeight(state), 0.5); - if (activeItem.getItem() instanceof BlockItem) { - matrices.scale(1.5F, 1.5F, 1.5F); - } else { - matrices.scale(1.25F, 1.25F, 1.25F); - } - int age = blockEntity.getAge(); - if (state.is(EndBlocks.ETERNAL_PEDESTAL) && state.getValue(EternalPedestal.ACTIVATED)) { - float[] colors = EternalCrystalRenderer.colors(age); - int y = blockEntity.getBlockPos().getY(); - - BeamRenderer.renderLightBeam(matrices, vertexConsumers, age, tickDelta, -y, 1024 - y, colors, 0.25F, 0.13F, 0.16F); - float altitude = Mth.sin((blockEntity.getAge() + tickDelta) / 10.0F) * 0.1F + 0.1F; - matrices.translate(0.0D, altitude, 0.0D); - } - if (activeItem.getItem() == Items.END_CRYSTAL) { - EndCrystalRenderer.render(age, blockEntity.getMaxAge(), tickDelta, matrices, vertexConsumers, light); - } else if (activeItem.getItem() == EndItems.ETERNAL_CRYSTAL) { - EternalCrystalRenderer.render(age, tickDelta, matrices, vertexConsumers, light); - } else { - float rotation = (age + tickDelta) / 25.0F + 6.0F; - matrices.mulPose(Vector3f.YP.rotation(rotation)); - minecraft.getItemRenderer().render(activeItem, ItemTransforms.TransformType.GROUND, false, matrices, vertexConsumers, light, overlay, model); - } - matrices.popPose(); - } -} diff --git a/src/main/java/ru/betterend/config/Configs.java b/src/main/java/ru/betterend/config/Configs.java deleted file mode 100644 index 98c5d859..00000000 --- a/src/main/java/ru/betterend/config/Configs.java +++ /dev/null @@ -1,34 +0,0 @@ -package ru.betterend.config; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import ru.bclib.BCLib; -import ru.bclib.config.EntryConfig; -import ru.bclib.config.IdConfig; -import ru.bclib.config.PathConfig; -import ru.betterend.BetterEnd; - -public class Configs { - public static final PathConfig ENTITY_CONFIG = new PathConfig(BetterEnd.MOD_ID, "entities"); - public static final PathConfig BLOCK_CONFIG = new PathConfig(BetterEnd.MOD_ID, "blocks"); - public static final PathConfig ITEM_CONFIG = new PathConfig(BetterEnd.MOD_ID, "items"); - public static final IdConfig BIOME_CONFIG = new EntryConfig(BetterEnd.MOD_ID, "biomes"); - public static final PathConfig GENERATOR_CONFIG = new PathConfig(BetterEnd.MOD_ID, "generator"); - public static final PathConfig RECIPE_CONFIG = new PathConfig(BetterEnd.MOD_ID, "recipes"); - - @Environment(value = EnvType.CLIENT) - public static final PathConfig CLENT_CONFIG = new PathConfig(BetterEnd.MOD_ID, "client"); - - public static void saveConfigs() { - ENTITY_CONFIG.saveChanges(); - BLOCK_CONFIG.saveChanges(); - BIOME_CONFIG.saveChanges(); - ITEM_CONFIG.saveChanges(); - GENERATOR_CONFIG.saveChanges(); - RECIPE_CONFIG.saveChanges(); - - if (BCLib.isClient()) { - CLENT_CONFIG.saveChanges(); - } - } -} diff --git a/src/main/java/ru/betterend/effects/EndEnchantments.java b/src/main/java/ru/betterend/effects/EndEnchantments.java deleted file mode 100644 index 6755a3de..00000000 --- a/src/main/java/ru/betterend/effects/EndEnchantments.java +++ /dev/null @@ -1,16 +0,0 @@ -package ru.betterend.effects; - -import net.minecraft.core.Registry; -import net.minecraft.world.item.enchantment.Enchantment; -import ru.betterend.BetterEnd; -import ru.betterend.effects.enchantment.EndVeilEnchantment; - -public class EndEnchantments { - public final static Enchantment END_VEIL = registerEnchantment("end_veil", new EndVeilEnchantment()); - - public static Enchantment registerEnchantment(String name, Enchantment enchantment) { - return Registry.register(Registry.ENCHANTMENT, BetterEnd.makeID(name), enchantment); - } - - public static void register() {} -} diff --git a/src/main/java/ru/betterend/effects/EndPotions.java b/src/main/java/ru/betterend/effects/EndPotions.java deleted file mode 100644 index 0b2e2394..00000000 --- a/src/main/java/ru/betterend/effects/EndPotions.java +++ /dev/null @@ -1,31 +0,0 @@ -package ru.betterend.effects; - -import net.minecraft.core.Registry; -import net.minecraft.world.effect.MobEffect; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.alchemy.Potion; -import net.minecraft.world.item.alchemy.Potions; -import ru.betterend.BetterEnd; -import ru.betterend.mixin.common.PotionBrewingAccessor; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class EndPotions { - public final static Potion END_VEIL = registerPotion("end_veil", EndStatusEffects.END_VEIL, 3600); - public final static Potion LONG_END_VEIL = registerPotion("long_end_veil", EndStatusEffects.END_VEIL, 9600); - - public static Potion registerPotion(String name, MobEffect effect, int duration) { - return registerPotion(name, new Potion(name, new MobEffectInstance(effect, duration))); - } - - public static Potion registerPotion(String name, Potion potion) { - return Registry.register(Registry.POTION, BetterEnd.makeID(name), potion); - } - - public static void register() { - PotionBrewingAccessor.callAddMix(Potions.AWKWARD, EndItems.ENDER_DUST, END_VEIL); - PotionBrewingAccessor.callAddMix(END_VEIL, Items.REDSTONE, LONG_END_VEIL); - PotionBrewingAccessor.callAddMix(Potions.AWKWARD, EndBlocks.MURKWEED.asItem(), Potions.NIGHT_VISION); - } -} diff --git a/src/main/java/ru/betterend/effects/EndStatusEffects.java b/src/main/java/ru/betterend/effects/EndStatusEffects.java deleted file mode 100644 index 1a7edb84..00000000 --- a/src/main/java/ru/betterend/effects/EndStatusEffects.java +++ /dev/null @@ -1,20 +0,0 @@ -package ru.betterend.effects; - -import net.minecraft.core.Registry; -import net.minecraft.world.effect.MobEffect; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.effect.MobEffects; -import ru.betterend.BetterEnd; -import ru.betterend.effects.status.EndVeilEffect; - -public class EndStatusEffects { - public final static MobEffectInstance CRYSTALITE_HEALTH_REGEN = new MobEffectInstance(MobEffects.REGENERATION, 40, 0, true, false, true); - public final static MobEffectInstance CRYSTALITE_DIG_SPEED = new MobEffectInstance(MobEffects.DIG_SPEED, 40, 0, true, false, true); - public final static MobEffectInstance CRYSTALITE_MOVE_SPEED = new MobEffectInstance(MobEffects.MOVEMENT_SPEED, 40, 0, true, false, true); - - public final static MobEffect END_VEIL = registerEffect("end_veil", new EndVeilEffect()); - - public static MobEffect registerEffect(String name, E effect) { - return Registry.register(Registry.MOB_EFFECT, BetterEnd.makeID(name), effect); - } -} diff --git a/src/main/java/ru/betterend/effects/enchantment/EndVeilEnchantment.java b/src/main/java/ru/betterend/effects/enchantment/EndVeilEnchantment.java deleted file mode 100644 index 57d040e9..00000000 --- a/src/main/java/ru/betterend/effects/enchantment/EndVeilEnchantment.java +++ /dev/null @@ -1,17 +0,0 @@ -package ru.betterend.effects.enchantment; - -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.item.enchantment.Enchantment; -import net.minecraft.world.item.enchantment.EnchantmentCategory; - -public class EndVeilEnchantment extends Enchantment { - - public EndVeilEnchantment() { - super(Enchantment.Rarity.VERY_RARE, EnchantmentCategory.ARMOR_HEAD, new EquipmentSlot[] { EquipmentSlot.HEAD }); - } - - @Override - public boolean isDiscoverable() { - return false; - } -} diff --git a/src/main/java/ru/betterend/effects/status/EndVeilEffect.java b/src/main/java/ru/betterend/effects/status/EndVeilEffect.java deleted file mode 100644 index eff6cbb3..00000000 --- a/src/main/java/ru/betterend/effects/status/EndVeilEffect.java +++ /dev/null @@ -1,16 +0,0 @@ -package ru.betterend.effects.status; - -import net.minecraft.world.effect.MobEffect; -import net.minecraft.world.effect.MobEffectCategory; - -public class EndVeilEffect extends MobEffect { - - public EndVeilEffect() { - super(MobEffectCategory.BENEFICIAL, 0x0D554A); - } - - @Override - public boolean isDurationEffectTick(int duration, int amplifier) { - return false; - } -} diff --git a/src/main/java/ru/betterend/entity/CubozoaEntity.java b/src/main/java/ru/betterend/entity/CubozoaEntity.java deleted file mode 100644 index e58053f4..00000000 --- a/src/main/java/ru/betterend/entity/CubozoaEntity.java +++ /dev/null @@ -1,158 +0,0 @@ -package ru.betterend.entity; - -import java.util.List; -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.protocol.game.ClientboundGameEventPacket; -import net.minecraft.network.syncher.EntityDataAccessor; -import net.minecraft.network.syncher.EntityDataSerializers; -import net.minecraft.network.syncher.SynchedEntityData; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.world.DifficultyInstance; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.effect.MobEffects; -import net.minecraft.world.entity.EntityDimensions; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.MobSpawnType; -import net.minecraft.world.entity.Pose; -import net.minecraft.world.entity.SpawnGroupData; -import net.minecraft.world.entity.ai.attributes.AttributeSupplier; -import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.animal.AbstractSchoolingFish; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.ServerLevelAccessor; -import net.minecraft.world.phys.AABB; -import ru.bclib.api.BiomeAPI; -import ru.betterend.registry.EndBiomes; -import ru.betterend.registry.EndItems; - -public class CubozoaEntity extends AbstractSchoolingFish { - public static final int VARIANTS = 2; - private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(CubozoaEntity.class, EntityDataSerializers.BYTE); - private static final EntityDataAccessor SCALE = SynchedEntityData.defineId(CubozoaEntity.class, EntityDataSerializers.BYTE); - - public CubozoaEntity(EntityType entityType, Level world) { - super(entityType, world); - } - - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, SpawnGroupData entityData, CompoundTag entityTag) { - SpawnGroupData data = super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityTag); - - if (BiomeAPI.getFromBiome(world.getBiome(blockPosition())) == EndBiomes.SULPHUR_SPRINGS) { - this.entityData.set(VARIANT, (byte) 1); - } - - if (entityTag != null) { - if (entityTag.contains("Variant")) { - this.entityData.set(VARIANT, entityTag.getByte("Variant")); - } - if (entityTag.contains("Scale")) { - this.entityData.set(SCALE, entityTag.getByte("Scale")); - } - } - - this.refreshDimensions(); - return data; - } - - @Override - protected void defineSynchedData() { - super.defineSynchedData(); - this.entityData.define(VARIANT, (byte) 0); - this.entityData.define(SCALE, (byte) this.getRandom().nextInt(16)); - } - - @Override - public void addAdditionalSaveData(CompoundTag tag) { - super.addAdditionalSaveData(tag); - tag.putByte("Variant", (byte) getVariant()); - tag.putByte("Scale", getByteScale()); - } - - @Override - public void readAdditionalSaveData(CompoundTag tag) { - super.readAdditionalSaveData(tag); - if (tag.contains("Variant")) { - this.entityData.set(VARIANT, tag.getByte("Variant")); - } - if (tag.contains("Scale")) { - this.entityData.set(SCALE, tag.getByte("Scale")); - } - } - - @Override - protected ItemStack getBucketItemStack() { - ItemStack bucket = EndItems.BUCKET_CUBOZOA.getDefaultInstance(); - CompoundTag tag = bucket.getOrCreateTag(); - tag.putByte("Variant", entityData.get(VARIANT)); - tag.putByte("Scale", entityData.get(SCALE)); - return bucket; - } - - public static AttributeSupplier.Builder createMobAttributes() { - return LivingEntity.createLivingAttributes() - .add(Attributes.MAX_HEALTH, 2.0) - .add(Attributes.FOLLOW_RANGE, 16.0) - .add(Attributes.MOVEMENT_SPEED, 0.5); - } - - public int getVariant() { - return (int) this.entityData.get(VARIANT); - } - - public byte getByteScale() { - return this.entityData.get(SCALE); - } - - public float getScale() { - return getByteScale() / 32F + 0.75F; - } - - public static boolean canSpawn(EntityType type, ServerLevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) { - AABB box = new AABB(pos).inflate(16); - List list = world.getEntitiesOfClass(CubozoaEntity.class, box, (entity) -> { - return true; - }); - return list.size() < 9; - } - - protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) { - return dimensions.height * 0.5F; - } - - @Override - protected void dropFromLootTable(DamageSource source, boolean causedByPlayer) { - int count = random.nextInt(3); - if (count > 0) { - ItemEntity drop = new ItemEntity(level, getX(), getY(), getZ(), new ItemStack(EndItems.GELATINE, count)); - this.level.addFreshEntity(drop); - } - } - - @Override - protected SoundEvent getFlopSound() { - return SoundEvents.SALMON_FLOP; - } - - @Override - public void playerTouch(Player player) { - if (player instanceof ServerPlayer && player.hurt(DamageSource.mobAttack(this), 0.5F)) { - if (!this.isSilent()) { - ((ServerPlayer) player).connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.PUFFER_FISH_STING, 0.0F)); - } - if (random.nextBoolean()) { - player.addEffect(new MobEffectInstance(MobEffects.POISON, 20, 0)); - } - } - } -} diff --git a/src/main/java/ru/betterend/entity/DragonflyEntity.java b/src/main/java/ru/betterend/entity/DragonflyEntity.java deleted file mode 100644 index 63ff1ed3..00000000 --- a/src/main/java/ru/betterend/entity/DragonflyEntity.java +++ /dev/null @@ -1,205 +0,0 @@ -package ru.betterend.entity; - -import java.util.EnumSet; -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.entity.AgableMob; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.Mob; -import net.minecraft.world.entity.MobSpawnType; -import net.minecraft.world.entity.ai.attributes.AttributeSupplier; -import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.ai.control.FlyingMoveControl; -import net.minecraft.world.entity.ai.control.LookControl; -import net.minecraft.world.entity.ai.goal.BreedGoal; -import net.minecraft.world.entity.ai.goal.FloatGoal; -import net.minecraft.world.entity.ai.goal.FollowParentGoal; -import net.minecraft.world.entity.ai.goal.Goal; -import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation; -import net.minecraft.world.entity.ai.navigation.PathNavigation; -import net.minecraft.world.entity.ai.util.RandomPos; -import net.minecraft.world.entity.animal.Animal; -import net.minecraft.world.entity.animal.FlyingAnimal; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.ServerLevelAccessor; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.pathfinder.BlockPathTypes; -import net.minecraft.world.level.pathfinder.Path; -import net.minecraft.world.phys.Vec3; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.registry.EndEntities; -import ru.betterend.registry.EndSounds; - -public class DragonflyEntity extends Animal implements FlyingAnimal { - public DragonflyEntity(EntityType entityType, Level world) { - super(entityType, world); - this.moveControl = new FlyingMoveControl(this, 20, true); - this.lookControl = new DragonflyLookControl(this); - this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); - this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, -1.0F); - this.xpReward = 1; - } - - public static AttributeSupplier.Builder createMobAttributes() { - return LivingEntity.createLivingAttributes() - .add(Attributes.MAX_HEALTH, 8.0D) - .add(Attributes.FOLLOW_RANGE, 16.0D) - .add(Attributes.FLYING_SPEED, 1.0D) - .add(Attributes.MOVEMENT_SPEED, 0.1D); - } - - @Override - public boolean canBeLeashed(Player player) { - return false; - } - - @Override - protected PathNavigation createNavigation(Level world) { - FlyingPathNavigation birdNavigation = new FlyingPathNavigation(this, world) { - public boolean isStableDestination(BlockPos pos) { - BlockState state = this.level.getBlockState(pos); - return state.isAir() || !state.getMaterial().blocksMotion(); - } - - public void tick() { - super.tick(); - } - }; - birdNavigation.setCanOpenDoors(false); - birdNavigation.setCanFloat(false); - birdNavigation.setCanPassDoors(true); - return birdNavigation; - } - - @Override - public float getWalkTargetValue(BlockPos pos, LevelReader world) { - return world.getBlockState(pos).isAir() ? 10.0F : 0.0F; - } - - @Override - protected void registerGoals() { - this.goalSelector.addGoal(1, new FloatGoal(this)); - this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D)); - this.goalSelector.addGoal(3, new FollowParentGoal(this, 1.0D)); - this.goalSelector.addGoal(4, new WanderAroundGoal()); - } - - @Override - public boolean isPushable() { - return false; - } - - @Override - protected boolean makeFlySound() { - return true; - } - - @Override - public boolean causeFallDamage(float fallDistance, float damageMultiplier) { - return false; - } - - @Override - public boolean isMovementNoisy() { - return false; - } - - @Override - public boolean isNoGravity() { - return true; - } - - @Override - public SoundEvent getAmbientSound() { - return EndSounds.ENTITY_DRAGONFLY; - } - - @Override - protected float getSoundVolume() { - return MHelper.randRange(0.25F, 0.5F, random); - } - - class DragonflyLookControl extends LookControl { - DragonflyLookControl(Mob entity) { - super(entity); - } - - protected boolean resetXRotOnTick() { - return true; - } - } - - class WanderAroundGoal extends Goal { - WanderAroundGoal() { - this.setFlags(EnumSet.of(Goal.Flag.MOVE)); - } - - public boolean canUse() { - return DragonflyEntity.this.navigation.isDone() && DragonflyEntity.this.random.nextInt(10) == 0; - } - - public boolean canContinueToUse() { - return DragonflyEntity.this.navigation.isInProgress(); - } - - public void start() { - Vec3 vec3d = this.getRandomLocation(); - if (vec3d != null) { - BlockPos pos = new BlockPos(vec3d); - try { - Path path = DragonflyEntity.this.navigation.createPath(pos, 1); - if (path != null) { - DragonflyEntity.this.navigation.moveTo(path, 1.0D); - } - } - catch (Exception e) {} - } - super.start(); - } - - private Vec3 getRandomLocation() { - int h = BlocksHelper.downRay(DragonflyEntity.this.level, DragonflyEntity.this.blockPosition(), 16); - Vec3 rotation = DragonflyEntity.this.getViewVector(0.0F); - Vec3 airPos = RandomPos.getAboveLandPos(DragonflyEntity.this, 8, 7, rotation, 1.5707964F, 2, 1); - if (airPos != null) { - if (isInVoid(airPos)) { - for (int i = 0; i < 8; i++) { - airPos = RandomPos.getAboveLandPos(DragonflyEntity.this, 16, 7, rotation, MHelper.PI2, 2, 1); - if (airPos != null && !isInVoid(airPos)) { - return airPos; - } - } - return null; - } - if (h > 5 && airPos.y() >= DragonflyEntity.this.blockPosition().getY()) { - airPos = new Vec3(airPos.x, airPos.y - h * 0.5, airPos.z); - } - return airPos; - } - return RandomPos.getAirPos(DragonflyEntity.this, 8, 4, -2, rotation, 1.5707963705062866D); - } - - private boolean isInVoid(Vec3 pos) { - int h = BlocksHelper.downRay(DragonflyEntity.this.level, new BlockPos(pos), 128); - return h > 100; - } - } - - @Override - public AgableMob getBreedOffspring(ServerLevel world, AgableMob entity) { - return EndEntities.DRAGONFLY.create(world); - } - - public static boolean canSpawn(EntityType type, ServerLevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) { - int y = world.getChunk(pos).getHeight(Types.WORLD_SURFACE, pos.getX() & 15, pos.getY() & 15); - return y > 0 && pos.getY() >= y; - } -} diff --git a/src/main/java/ru/betterend/entity/EndFishEntity.java b/src/main/java/ru/betterend/entity/EndFishEntity.java deleted file mode 100644 index dec0cad8..00000000 --- a/src/main/java/ru/betterend/entity/EndFishEntity.java +++ /dev/null @@ -1,160 +0,0 @@ -package ru.betterend.entity; - -import java.util.List; -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.syncher.EntityDataAccessor; -import net.minecraft.network.syncher.EntityDataSerializers; -import net.minecraft.network.syncher.SynchedEntityData; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.world.DifficultyInstance; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.MobSpawnType; -import net.minecraft.world.entity.SpawnGroupData; -import net.minecraft.world.entity.ai.attributes.AttributeSupplier; -import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.animal.AbstractSchoolingFish; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.ServerLevelAccessor; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.phys.AABB; -import ru.bclib.api.BiomeAPI; -import ru.betterend.registry.EndBiomes; -import ru.betterend.registry.EndItems; - -public class EndFishEntity extends AbstractSchoolingFish { - public static final int VARIANTS_NORMAL = 5; - public static final int VARIANTS_SULPHUR = 3; - public static final int VARIANTS = VARIANTS_NORMAL + VARIANTS_SULPHUR; - private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(EndFishEntity.class, EntityDataSerializers.BYTE); - private static final EntityDataAccessor SCALE = SynchedEntityData.defineId(EndFishEntity.class, EntityDataSerializers.BYTE); - - public EndFishEntity(EntityType entityType, Level world) { - super(entityType, world); - } - - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, SpawnGroupData entityData, CompoundTag entityTag) { - SpawnGroupData data = super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityTag); - - if (BiomeAPI.getFromBiome(world.getBiome(blockPosition())) == EndBiomes.SULPHUR_SPRINGS) { - this.entityData.set(VARIANT, (byte) (random.nextInt(VARIANTS_SULPHUR) + VARIANTS_NORMAL)); - } - - if (entityTag != null) { - if (entityTag.contains("Variant")) { - this.entityData.set(VARIANT, entityTag.getByte("variant")); - } - if (entityTag.contains("Scale")) { - this.entityData.set(SCALE, entityTag.getByte("scale")); - } - } - - this.refreshDimensions(); - return data; - } - - @Override - protected void defineSynchedData() { - super.defineSynchedData(); - this.entityData.define(VARIANT, (byte) this.getRandom().nextInt(VARIANTS_NORMAL)); - this.entityData.define(SCALE, (byte) this.getRandom().nextInt(16)); - } - - @Override - public void addAdditionalSaveData(CompoundTag tag) { - super.addAdditionalSaveData(tag); - tag.putByte("Variant", (byte) getVariant()); - tag.putByte("Scale", getByteScale()); - } - - @Override - public void readAdditionalSaveData(CompoundTag tag) { - super.readAdditionalSaveData(tag); - if (tag.contains("Variant")) { - this.entityData.set(VARIANT, tag.getByte("Variant")); - } - if (tag.contains("Scale")) { - this.entityData.set(SCALE, tag.getByte("Scale")); - } - } - - @Override - protected ItemStack getBucketItemStack() { - ItemStack bucket = EndItems.BUCKET_END_FISH.getDefaultInstance(); - CompoundTag tag = bucket.getOrCreateTag(); - tag.putByte("variant", entityData.get(VARIANT)); - tag.putByte("scale", entityData.get(SCALE)); - return bucket; - } - - @Override - protected SoundEvent getFlopSound() { - return SoundEvents.TROPICAL_FISH_FLOP; - } - - @Override - protected SoundEvent getAmbientSound() { - return SoundEvents.SALMON_AMBIENT; - } - - @Override - protected SoundEvent getDeathSound() { - return SoundEvents.SALMON_DEATH; - } - - @Override - protected SoundEvent getHurtSound(DamageSource source) { - return SoundEvents.SALMON_HURT; - } - - @Override - public void tick() { - super.tick(); - if (random.nextInt(8) == 0 && getFeetBlockState().is(Blocks.WATER)) { - double x = getX() + random.nextGaussian() * 0.2; - double y = getY() + random.nextGaussian() * 0.2; - double z = getZ() + random.nextGaussian() * 0.2; - level.addParticle(ParticleTypes.BUBBLE, x, y, z, 0, 0, 0); - } - } - - public static AttributeSupplier.Builder createMobAttributes() { - return LivingEntity.createLivingAttributes() - .add(Attributes.MAX_HEALTH, 2.0) - .add(Attributes.FOLLOW_RANGE, 16.0) - .add(Attributes.MOVEMENT_SPEED, 0.75); - } - - public int getVariant() { - return (int) this.entityData.get(VARIANT); - } - - public byte getByteScale() { - return this.entityData.get(SCALE); - } - - public float getScale() { - return getByteScale() / 32F + 0.75F; - } - - public static boolean canSpawn(EntityType type, ServerLevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) { - AABB box = new AABB(pos).inflate(16); - List list = world.getEntitiesOfClass(EndFishEntity.class, box, (entity) -> { return true; }); - return list.size() < 9; - } - - @Override - protected void dropFromLootTable(DamageSource source, boolean causedByPlayer) { - ItemEntity drop = new ItemEntity(level, getX(), getY(), getZ(), new ItemStack(EndItems.END_FISH_RAW)); - this.level.addFreshEntity(drop); - } -} diff --git a/src/main/java/ru/betterend/entity/EndSlimeEntity.java b/src/main/java/ru/betterend/entity/EndSlimeEntity.java deleted file mode 100644 index 24662f26..00000000 --- a/src/main/java/ru/betterend/entity/EndSlimeEntity.java +++ /dev/null @@ -1,416 +0,0 @@ -package ru.betterend.entity; - -import java.util.EnumSet; -import java.util.List; -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.particles.ParticleOptions; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; -import net.minecraft.network.syncher.EntityDataAccessor; -import net.minecraft.network.syncher.EntityDataSerializers; -import net.minecraft.network.syncher.SynchedEntityData; -import net.minecraft.util.Mth; -import net.minecraft.world.DifficultyInstance; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.effect.MobEffects; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.MobSpawnType; -import net.minecraft.world.entity.SpawnGroupData; -import net.minecraft.world.entity.ai.attributes.AttributeSupplier; -import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.ai.control.MoveControl; -import net.minecraft.world.entity.ai.goal.Goal; -import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; -import net.minecraft.world.entity.animal.IronGolem; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.entity.monster.Slime; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.ServerLevelAccessor; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.phys.AABB; -import ru.bclib.api.BiomeAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.biomes.BCLBiome; -import ru.betterend.interfaces.ISlime; -import ru.betterend.registry.EndBiomes; - -public class EndSlimeEntity extends Slime { - private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(EndSlimeEntity.class, EntityDataSerializers.BYTE); - private static final MutableBlockPos POS = new MutableBlockPos(); - - public EndSlimeEntity(EntityType entityType, Level world) { - super(entityType, world); - this.moveControl = new EndSlimeMoveControl(this); - } - - protected void registerGoals() { - this.goalSelector.addGoal(1, new SwimmingGoal()); - this.goalSelector.addGoal(2, new FaceTowardTargetGoal()); - this.goalSelector.addGoal(3, new RandomLookGoal()); - this.goalSelector.addGoal(5, new MoveGoal()); - this.targetSelector.addGoal(1, new NearestAttackableTargetGoal(this, Player.class, 10, true, false, (livingEntity) -> { - return Math.abs(livingEntity.getY() - this.getY()) <= 4.0D; - })); - this.targetSelector.addGoal(3, new NearestAttackableTargetGoal(this, IronGolem.class, true)); - } - - public static AttributeSupplier.Builder createMobAttributes() { - return LivingEntity.createLivingAttributes() - .add(Attributes.MAX_HEALTH, 1.0D) - .add(Attributes.ATTACK_DAMAGE, 1.0D) - .add(Attributes.FOLLOW_RANGE, 16.0D) - .add(Attributes.MOVEMENT_SPEED, 0.15D); - } - - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, SpawnGroupData entityData, CompoundTag entityTag) { - SpawnGroupData data = super.finalizeSpawn(world, difficulty, spawnReason, entityData, entityTag); - BCLBiome biome = BiomeAPI.getFromBiome(world.getBiome(blockPosition())); - if (biome == EndBiomes.FOGGY_MUSHROOMLAND) { - this.setMossy(); - } - else if (biome == EndBiomes.MEGALAKE || biome == EndBiomes.MEGALAKE_GROVE) { - this.setLake(); - } - else if (biome == EndBiomes.AMBER_LAND) { - this.setAmber(true); - } - this.refreshDimensions(); - return data; - } - - @Override - protected void defineSynchedData() { - super.defineSynchedData(); - this.entityData.define(VARIANT, (byte) 0); - } - - @Override - public void addAdditionalSaveData(CompoundTag tag) { - super.addAdditionalSaveData(tag); - tag.putByte("Variant", (byte) getSlimeType()); - } - - @Override - public void readAdditionalSaveData(CompoundTag tag) { - super.readAdditionalSaveData(tag); - if (tag.contains("Variant")) { - this.entityData.set(VARIANT, tag.getByte("Variant")); - } - } - - @Override - protected ParticleOptions getParticleType() { - return ParticleTypes.PORTAL; - } - - @Override - public void remove() { - int i = this.getSize(); - if (!this.level.isClientSide && i > 1 && this.isDeadOrDying()) { - Component text = this.getCustomName(); - boolean bl = this.isNoAi(); - float f = (float) i / 4.0F; - int j = i / 2; - int k = 2 + this.random.nextInt(3); - int type = this.getSlimeType(); - - for (int l = 0; l < k; ++l) { - float g = ((float) (l % 2) - 0.5F) * f; - float h = ((float) (l / 2) - 0.5F) * f; - EndSlimeEntity slimeEntity = (EndSlimeEntity) this.getType().create(this.level); - if (this.isPersistenceRequired()) { - slimeEntity.setPersistenceRequired(); - } - - slimeEntity.setSlimeType(type); - slimeEntity.setCustomName(text); - slimeEntity.setNoAi(bl); - slimeEntity.setInvulnerable(this.isInvulnerable()); - ((ISlime) slimeEntity).be_setSlimeSize(j, true); - slimeEntity.refreshDimensions(); - slimeEntity.moveTo(this.getX() + (double) g, this.getY() + 0.5D, this.getZ() + (double) h, this.random.nextFloat() * 360.0F, 0.0F); - this.level.addFreshEntity(slimeEntity); - } - } - this.removed = true; - } - - @Override - protected void dropFromLootTable(DamageSource source, boolean causedByPlayer) { - int maxCount = this.getSize(); - int minCount = maxCount >> 1; - if (minCount < 1) { - minCount = 1; - } - if (causedByPlayer && this.lastHurtByPlayer != null) { - int looting = EnchantmentHelper.getMobLooting(this.lastHurtByPlayer); - minCount += looting; - } - int count = minCount < maxCount ? MHelper.randRange(minCount, maxCount, random) : maxCount; - ItemEntity drop = new ItemEntity(level, getX(), getY(), getZ(), new ItemStack(Items.SLIME_BALL, count)); - this.level.addFreshEntity(drop); - } - - public int getSlimeType() { - return this.entityData.get(VARIANT).intValue(); - } - - public void setSlimeType(int value) { - this.entityData.set(VARIANT, (byte) value); - } - - protected void setMossy() { - setSlimeType(1); - } - - public boolean isMossy() { - return getSlimeType() == 1; - } - - protected void setLake() { - setSlimeType(2); - } - - public boolean isLake() { - return getSlimeType() == 2; - } - - protected void setAmber(boolean mossy) { - this.entityData.set(VARIANT, (byte) 3); - } - - public boolean isAmber() { - return this.entityData.get(VARIANT) == 3; - } - - public boolean isChorus() { - return this.entityData.get(VARIANT) == 0; - } - - public static boolean canSpawn(EntityType type, ServerLevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) { - return random.nextInt(16) == 0 || isPermanentBiome(world, pos) || (notManyEntities(world, pos, 32, 3) && isWaterNear(world, pos, 32, 8)); - } - - private static boolean isPermanentBiome(ServerLevelAccessor world, BlockPos pos) { - Biome biome = world.getBiome(pos); - return BiomeAPI.getFromBiome(biome) == EndBiomes.CHORUS_FOREST; - } - - private static boolean notManyEntities(ServerLevelAccessor world, BlockPos pos, int radius, int maxCount) { - AABB box = new AABB(pos).inflate(radius); - List list = world.getEntitiesOfClass(EndSlimeEntity.class, box, (entity) -> { return true; }); - return list.size() <= maxCount; - } - - private static boolean isWaterNear(ServerLevelAccessor world, BlockPos pos, int radius, int radius2) { - for (int x = pos.getX() - radius; x <= pos.getX() + radius; x++) { - POS.setX(x); - for (int z = pos.getZ() - radius; z <= pos.getZ() + radius; z++) { - POS.setZ(z); - for (int y = pos.getY() - radius2; y <= pos.getY() + radius2; y++) { - POS.setY(y); - if (world.getBlockState(POS).getBlock() == Blocks.WATER) { - return true; - } - } - } - } - return false; - } - - class MoveGoal extends Goal { - public MoveGoal() { - this.setFlags(EnumSet.of(Goal.Flag.JUMP, Goal.Flag.MOVE)); - } - - public boolean canUse() { - if (EndSlimeEntity.this.isPassenger()) { - return false; - } - - float yaw = EndSlimeEntity.this.getYHeadRot(); - float speed = EndSlimeEntity.this.getSpeed(); - if (speed > 0.1) { - float dx = Mth.sin(-yaw * 0.017453292F); - float dz = Mth.cos(-yaw * 0.017453292F); - BlockPos pos = EndSlimeEntity.this.blockPosition().offset(dx * speed * 4, 0, dz * speed * 4); - int down = BlocksHelper.downRay(EndSlimeEntity.this.level, pos, 16); - return down < 5; - } - - return true; - } - - public void tick() { - ((EndSlimeMoveControl) EndSlimeEntity.this.getMoveControl()).move(1.0D); - } - } - - class SwimmingGoal extends Goal { - public SwimmingGoal() { - this.setFlags(EnumSet.of(Goal.Flag.JUMP, Goal.Flag.MOVE)); - EndSlimeEntity.this.getNavigation().setCanFloat(true); - } - - public boolean canUse() { - return (EndSlimeEntity.this.isInWater() - || EndSlimeEntity.this.isInLava()) - && EndSlimeEntity.this.getMoveControl() instanceof EndSlimeMoveControl; - } - - public void tick() { - if (EndSlimeEntity.this.getRandom().nextFloat() < 0.8F) { - EndSlimeEntity.this.getJumpControl().jump(); - } - - ((EndSlimeMoveControl) EndSlimeEntity.this.getMoveControl()).move(1.2D); - } - } - - class RandomLookGoal extends Goal { - private float targetYaw; - private int timer; - - public RandomLookGoal() { - this.setFlags(EnumSet.of(Goal.Flag.LOOK)); - } - - public boolean canUse() { - return EndSlimeEntity.this.getTarget() == null - && (EndSlimeEntity.this.onGround - || EndSlimeEntity.this.isInWater() - || EndSlimeEntity.this.isInLava() - || EndSlimeEntity.this.hasEffect(MobEffects.LEVITATION)) - && EndSlimeEntity.this.getMoveControl() instanceof EndSlimeMoveControl; - } - - public void tick() { - if (--this.timer <= 0) { - this.timer = 40 + EndSlimeEntity.this.getRandom().nextInt(60); - this.targetYaw = (float) EndSlimeEntity.this.getRandom().nextInt(360); - } - - ((EndSlimeMoveControl) EndSlimeEntity.this.getMoveControl()).look(this.targetYaw, false); - } - } - - class FaceTowardTargetGoal extends Goal { - private int ticksLeft; - - public FaceTowardTargetGoal() { - this.setFlags(EnumSet.of(Goal.Flag.LOOK)); - } - - public boolean canUse() { - LivingEntity livingEntity = EndSlimeEntity.this.getTarget(); - if (livingEntity == null) { - return false; - } - else if (!livingEntity.isAlive()) { - return false; - } - else { - return livingEntity instanceof Player && ((Player) livingEntity).abilities.invulnerable ? false : EndSlimeEntity.this.getMoveControl() instanceof EndSlimeMoveControl; - } - } - - public void start() { - this.ticksLeft = 300; - super.start(); - } - - public boolean canContinueToUse() { - LivingEntity livingEntity = EndSlimeEntity.this.getTarget(); - if (livingEntity == null) { - return false; - } - else if (!livingEntity.isAlive()) { - return false; - } - else if (livingEntity instanceof Player && ((Player) livingEntity).abilities.invulnerable) { - return false; - } - else { - return --this.ticksLeft > 0; - } - } - - public void tick() { - EndSlimeEntity.this.lookAt(EndSlimeEntity.this.getTarget(), 10.0F, 10.0F); - ((EndSlimeMoveControl) EndSlimeEntity.this.getMoveControl()).look(EndSlimeEntity.this.yRot, EndSlimeEntity.this.isDealsDamage()); - } - } - - class EndSlimeMoveControl extends MoveControl { - private float targetYaw; - private int ticksUntilJump; - private boolean jumpOften; - - public EndSlimeMoveControl(EndSlimeEntity slime) { - super(slime); - this.targetYaw = 180.0F * slime.yRot / 3.1415927F; - } - - public void look(float targetYaw, boolean jumpOften) { - this.targetYaw = targetYaw; - this.jumpOften = jumpOften; - } - - public void move(double speed) { - this.speedModifier = speed; - this.operation = MoveControl.Operation.MOVE_TO; - } - - public void tick() { - this.mob.yRot = this.rotlerp(this.mob.yRot, this.targetYaw, 90.0F); - this.mob.yHeadRot = this.mob.yRot; - this.mob.yBodyRot = this.mob.yRot; - if (this.operation != MoveControl.Operation.MOVE_TO) { - this.mob.setZza(0.0F); - } - else { - this.operation = MoveControl.Operation.WAIT; - if (this.mob.isOnGround()) { - this.mob.setSpeed((float) (this.speedModifier * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED))); - if (this.ticksUntilJump-- <= 0) { - this.ticksUntilJump = EndSlimeEntity.this.getJumpDelay(); - if (this.jumpOften) { - this.ticksUntilJump /= 3; - } - - EndSlimeEntity.this.getJumpControl().jump(); - if (EndSlimeEntity.this.doPlayJumpSound()) { - EndSlimeEntity.this.playSound(EndSlimeEntity.this.getJumpSound(), EndSlimeEntity.this.getSoundVolume(), getJumpSoundPitch()); - } - } - else { - EndSlimeEntity.this.xxa = 0.0F; - EndSlimeEntity.this.zza = 0.0F; - this.mob.setSpeed(0.0F); - } - } - else { - this.mob.setSpeed((float) (this.speedModifier * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED))); - } - - } - } - - private float getJumpSoundPitch() { - float f = EndSlimeEntity.this.isTiny() ? 1.4F : 0.8F; - return ((EndSlimeEntity.this.random.nextFloat() - EndSlimeEntity.this.random.nextFloat()) * 0.2F + 1.0F) * f; - } - } -} diff --git a/src/main/java/ru/betterend/entity/ShadowWalkerEntity.java b/src/main/java/ru/betterend/entity/ShadowWalkerEntity.java deleted file mode 100644 index 100bccac..00000000 --- a/src/main/java/ru/betterend/entity/ShadowWalkerEntity.java +++ /dev/null @@ -1,154 +0,0 @@ -package ru.betterend.entity; - -import java.util.List; -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.effect.MobEffects; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.MobSpawnType; -import net.minecraft.world.entity.ai.attributes.AttributeSupplier; -import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; -import net.minecraft.world.entity.ai.goal.MeleeAttackGoal; -import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal; -import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal; -import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; -import net.minecraft.world.entity.monster.Monster; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.ServerLevelAccessor; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.AABB; -import ru.bclib.util.MHelper; -import ru.betterend.registry.EndSounds; - -public class ShadowWalkerEntity extends Monster { - public ShadowWalkerEntity(EntityType entityType, Level world) { - super(entityType, world); - } - - @Override - protected void registerGoals() { - this.goalSelector.addGoal(2, new AttackGoal(this, 1.0D, false)); - this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0D)); - this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 8.0F)); - this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); - this.targetSelector.addGoal(2, new NearestAttackableTargetGoal(this, Player.class, true)); - } - - public static AttributeSupplier.Builder createMobAttributes() { - return Monster.createMonsterAttributes() - .add(Attributes.FOLLOW_RANGE, 35.0) - .add(Attributes.MOVEMENT_SPEED, 0.15) - .add(Attributes.ATTACK_DAMAGE, 4.5) - .add(Attributes.ARMOR, 2.0) - .add(Attributes.SPAWN_REINFORCEMENTS_CHANCE); - } - - @Override - public void tick() { - super.tick(); - level.addParticle(ParticleTypes.ASH, - getX() + random.nextGaussian() * 0.2, - getY() + random.nextGaussian() * 0.5 + 1, - getZ() + random.nextGaussian() * 0.2, - 0, 0, 0); - level.addParticle(ParticleTypes.SMOKE, - getX() + random.nextGaussian() * 0.2, - getY() + random.nextGaussian() * 0.5 + 1, - getZ() + random.nextGaussian() * 0.2, - 0, 0, 0); - level.addParticle(ParticleTypes.ENTITY_EFFECT, - getX() + random.nextGaussian() * 0.2, - getY() + random.nextGaussian() * 0.5 + 1, - getZ() + random.nextGaussian() * 0.2, - 0, 0, 0); - } - - @Override - protected SoundEvent getAmbientSound() { - return EndSounds.ENTITY_SHADOW_WALKER; - } - - @Override - protected SoundEvent getHurtSound(DamageSource source) { - return EndSounds.ENTITY_SHADOW_WALKER_DAMAGE; - } - - @Override - protected SoundEvent getDeathSound() { - return EndSounds.ENTITY_SHADOW_WALKER_DEATH; - } - - @Override - protected void playStepSound(BlockPos pos, BlockState state) {} - - @Override - protected float getSoundVolume() { - return MHelper.randRange(0.25F, 0.5F, random); - } - - @Override - protected float getVoicePitch() { - return MHelper.randRange(0.75F, 1.25F, random); - } - - @Override - public boolean doHurtTarget(Entity target) { - boolean attack = super.doHurtTarget(target); - if (attack && target instanceof LivingEntity) { - LivingEntity living = (LivingEntity) target; - if (!(living.hasEffect(MobEffects.BLINDNESS))) { - living.addEffect(new MobEffectInstance(MobEffects.BLINDNESS, 60)); - } - } - return attack; - } - - public static boolean canSpawn(EntityType type, ServerLevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) { - if (Monster.checkMonsterSpawnRules(type, world, spawnReason, pos, random)) { - AABB box = new AABB(pos).inflate(16); - List entities = world.getEntitiesOfClass(ShadowWalkerEntity.class, box, (entity) -> { return true; }); - return entities.size() < 6; - } - return false; - } - - private final class AttackGoal extends MeleeAttackGoal { - private final ShadowWalkerEntity walker; - private int ticks; - - public AttackGoal(ShadowWalkerEntity walker, double speed, boolean pauseWhenMobIdle) { - super(walker, speed, pauseWhenMobIdle); - this.walker = walker; - } - - public void start() { - super.start(); - this.ticks = 0; - } - - public void stop() { - super.stop(); - this.walker.setAggressive(false); - } - - public void tick() { - super.tick(); - ++this.ticks; - if (this.ticks >= 5 && this.getTicksUntilNextAttack() < this.getAttackInterval() / 2) { - this.walker.setAggressive(true); - } - else { - this.walker.setAggressive(false); - } - } - } -} diff --git a/src/main/java/ru/betterend/entity/SilkMothEntity.java b/src/main/java/ru/betterend/entity/SilkMothEntity.java deleted file mode 100644 index 4c54e387..00000000 --- a/src/main/java/ru/betterend/entity/SilkMothEntity.java +++ /dev/null @@ -1,310 +0,0 @@ -package ru.betterend.entity; - -import java.util.EnumSet; -import java.util.List; -import java.util.Random; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Registry; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.AgableMob; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.Mob; -import net.minecraft.world.entity.MobSpawnType; -import net.minecraft.world.entity.ai.attributes.AttributeSupplier; -import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.ai.control.FlyingMoveControl; -import net.minecraft.world.entity.ai.control.LookControl; -import net.minecraft.world.entity.ai.goal.BreedGoal; -import net.minecraft.world.entity.ai.goal.FloatGoal; -import net.minecraft.world.entity.ai.goal.FollowParentGoal; -import net.minecraft.world.entity.ai.goal.Goal; -import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation; -import net.minecraft.world.entity.ai.navigation.PathNavigation; -import net.minecraft.world.entity.ai.util.RandomPos; -import net.minecraft.world.entity.animal.Animal; -import net.minecraft.world.entity.animal.FlyingAnimal; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.ServerLevelAccessor; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.pathfinder.BlockPathTypes; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.EndBlockProperties; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndEntities; -import ru.betterend.registry.EndItems; - -public class SilkMothEntity extends Animal implements FlyingAnimal { - private BlockPos hivePos; - private BlockPos entrance; - private Level hiveWorld; - - public SilkMothEntity(EntityType entityType, Level world) { - super(entityType, world); - this.moveControl = new FlyingMoveControl(this, 20, true); - this.lookControl = new MothLookControl(this); - this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F); - this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, -1.0F); - this.xpReward = 1; - } - - public static AttributeSupplier.Builder createMobAttributes() { - return LivingEntity.createLivingAttributes() - .add(Attributes.MAX_HEALTH, 2.0D) - .add(Attributes.FOLLOW_RANGE, 16.0D) - .add(Attributes.FLYING_SPEED, 0.4D) - .add(Attributes.MOVEMENT_SPEED, 0.1D); - } - - public void setHive(Level world, BlockPos hive) { - this.hivePos = hive; - this.hiveWorld = world; - } - - @Override - public boolean canBeLeashed(Player player) { - return false; - } - - @Override - public void addAdditionalSaveData(CompoundTag tag) { - if (hivePos != null) { - tag.put("HivePos", NbtUtils.writeBlockPos(hivePos)); - tag.putString("HiveWorld", hiveWorld.dimension().location().toString()); - } - } - - @Override - public void readAdditionalSaveData(CompoundTag tag) { - if (tag.contains("HivePos")) { - hivePos = NbtUtils.readBlockPos(tag.getCompound("HivePos")); - ResourceLocation worldID = new ResourceLocation(tag.getString("HiveWorld")); - try { - hiveWorld = level.getServer().getLevel(ResourceKey.create(Registry.DIMENSION_REGISTRY, worldID)); - } - catch (Exception e) { - BetterEnd.LOGGER.warning("Silk Moth Hive World {} is missing!", worldID); - hivePos = null; - } - } - } - - @Override - protected void registerGoals() { - this.goalSelector.addGoal(1, new ReturnToHiveGoal()); - this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D)); - this.goalSelector.addGoal(5, new FollowParentGoal(this, 1.25D)); - this.goalSelector.addGoal(8, new WanderAroundGoal()); - this.goalSelector.addGoal(9, new FloatGoal(this)); - } - - @Override - protected PathNavigation createNavigation(Level world) { - FlyingPathNavigation birdNavigation = new FlyingPathNavigation(this, world) { - public boolean isStableDestination(BlockPos pos) { - BlockState state = this.level.getBlockState(pos); - return state.isAir() || !state.getMaterial().blocksMotion(); - } - - public void tick() { - super.tick(); - } - }; - birdNavigation.setCanOpenDoors(false); - birdNavigation.setCanFloat(false); - birdNavigation.setCanPassDoors(true); - return birdNavigation; - } - - @Override - public boolean isPushable() { - return false; - } - - @Override - protected boolean makeFlySound() { - return true; - } - - @Override - public boolean causeFallDamage(float fallDistance, float damageMultiplier) { - return false; - } - - @Override - public boolean isMovementNoisy() { - return false; - } - - @Override - public boolean isNoGravity() { - return true; - } - - @Override - public AgableMob getBreedOffspring(ServerLevel world, AgableMob entity) { - return EndEntities.SILK_MOTH.create(world); - } - - @Override - protected void dropFromLootTable(DamageSource source, boolean causedByPlayer) { - int minCount = 0; - int maxCount = 1; - if (causedByPlayer && this.lastHurtByPlayer != null) { - int looting = EnchantmentHelper.getMobLooting(this.lastHurtByPlayer); - minCount += looting; - maxCount += looting; - if (maxCount > 2) { - maxCount = 2; - } - } - int count = minCount < maxCount ? MHelper.randRange(minCount, maxCount, random) : maxCount; - ItemEntity drop = new ItemEntity(level, getX(), getY(), getZ(), new ItemStack(EndItems.SILK_FIBER, count)); - this.level.addFreshEntity(drop); - } - - public static boolean canSpawn(EntityType type, ServerLevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) { - int y = world.getChunk(pos).getHeight(Types.WORLD_SURFACE, pos.getX() & 15, pos.getY() & 15); - return y > 0 && pos.getY() >= y && notManyEntities(world, pos, 32, 1); - } - - private static boolean notManyEntities(ServerLevelAccessor world, BlockPos pos, int radius, int maxCount) { - AABB box = new AABB(pos).inflate(radius); - List list = world.getEntitiesOfClass(SilkMothEntity.class, box, (entity) -> true); - return list.size() <= maxCount; - } - - class MothLookControl extends LookControl { - MothLookControl(Mob entity) { - super(entity); - } - - protected boolean resetXRotOnTick() { - return true; - } - } - - class WanderAroundGoal extends Goal { - WanderAroundGoal() { - this.setFlags(EnumSet.of(Goal.Flag.MOVE)); - } - - @Override - public boolean canUse() { - return SilkMothEntity.this.navigation.isDone() && SilkMothEntity.this.random.nextInt(10) == 0; - } - - @Override - public boolean canContinueToUse() { - return SilkMothEntity.this.navigation.isInProgress(); - } - - @Override - public void start() { - Vec3 vec3d = null; - if (SilkMothEntity.this.hivePos != null && SilkMothEntity.this.hiveWorld == SilkMothEntity.this.level) { - if (SilkMothEntity.this.position().distanceToSqr(SilkMothEntity.this.hivePos.getX(), SilkMothEntity.this.hivePos.getY(), SilkMothEntity.this.hivePos.getZ()) > 16) { - vec3d = SilkMothEntity.this.position().add(random.nextGaussian() * 2, 0, random.nextGaussian() * 2); - } - } - vec3d = vec3d == null ? this.getRandomLocation() : vec3d; - if (vec3d != null) { - try { - SilkMothEntity.this.navigation.moveTo(SilkMothEntity.this.navigation.createPath(new BlockPos(vec3d), 1), 1.0D); - } - catch (Exception e) {} - } - } - - @Nullable - private Vec3 getRandomLocation() { - Vec3 vec3d3 = SilkMothEntity.this.getViewVector(0.0F); - Vec3 vec3d4 = RandomPos.getAboveLandPos(SilkMothEntity.this, 8, 7, vec3d3, 1.5707964F, 2, 1); - return vec3d4 != null ? vec3d4 : RandomPos.getAirPos(SilkMothEntity.this, 8, 4, -2, vec3d3, 1.5707963705062866D); - } - } - - class ReturnToHiveGoal extends Goal { - ReturnToHiveGoal() { - this.setFlags(EnumSet.of(Goal.Flag.MOVE)); - } - - @Override - public boolean canUse() { - return SilkMothEntity.this.hivePos != null - && SilkMothEntity.this.hiveWorld == SilkMothEntity.this.level - && SilkMothEntity.this.navigation.isDone() - && SilkMothEntity.this.random.nextInt(16) == 0 - && SilkMothEntity.this.position().distanceToSqr(SilkMothEntity.this.hivePos.getX(), SilkMothEntity.this.hivePos.getY(), SilkMothEntity.this.hivePos.getZ()) < 64; - } - - @Override - public boolean canContinueToUse() { - return SilkMothEntity.this.navigation.isInProgress() && level.getBlockState(entrance).isAir() && (level.getBlockState(hivePos).is(EndBlocks.SILK_MOTH_NEST) || level.getBlockState(hivePos).is(EndBlocks.SILK_MOTH_HIVE)); - } - - @Override - public void start() { - BlockState state = SilkMothEntity.this.level.getBlockState(SilkMothEntity.this.hivePos); - if (!state.is(EndBlocks.SILK_MOTH_NEST) && !state.is(EndBlocks.SILK_MOTH_HIVE)) { - SilkMothEntity.this.hivePos = null; - return; - } - try { - SilkMothEntity.this.entrance = SilkMothEntity.this.hivePos.relative(state.getValue(BlockStateProperties.HORIZONTAL_FACING)); - SilkMothEntity.this.navigation.moveTo(SilkMothEntity.this.navigation.createPath(entrance, 1), 1.0D); - } - catch (Exception e) {} - } - - @Override - public void tick() { - super.tick(); - if (SilkMothEntity.this.entrance == null) { - return; - } - double dx = Math.abs(SilkMothEntity.this.entrance.getX() - SilkMothEntity.this.getX()); - double dy = Math.abs(SilkMothEntity.this.entrance.getY() - SilkMothEntity.this.getY()); - double dz = Math.abs(SilkMothEntity.this.entrance.getZ() - SilkMothEntity.this.getZ()); - if (dx + dy + dz < 1) { - BlockState state = SilkMothEntity.this.level.getBlockState(hivePos); - if (state.is(EndBlocks.SILK_MOTH_NEST) || state.is(EndBlocks.SILK_MOTH_HIVE)) { - int fullness = state.getValue(EndBlockProperties.FULLNESS); - boolean isHive = state.is(EndBlocks.SILK_MOTH_HIVE); - if (fullness < 3 && (isHive || SilkMothEntity.this.random.nextBoolean())) { - fullness += isHive ? MHelper.randRange(1, 2, random) : 1; - if (fullness > 3) { - fullness = 3; - } - BlocksHelper.setWithUpdate(SilkMothEntity.this.hiveWorld, SilkMothEntity.this.hivePos, state.setValue(EndBlockProperties.FULLNESS, fullness)); - } - SilkMothEntity.this.level.playSound(null, SilkMothEntity.this.entrance, SoundEvents.BEEHIVE_ENTER, SoundSource.BLOCKS, 1, 1); - SilkMothEntity.this.remove(); - } - else { - SilkMothEntity.this.hivePos = null; - } - } - } - } -} diff --git a/src/main/java/ru/betterend/entity/model/BlockBenchModel.java b/src/main/java/ru/betterend/entity/model/BlockBenchModel.java deleted file mode 100644 index cb0758ad..00000000 --- a/src/main/java/ru/betterend/entity/model/BlockBenchModel.java +++ /dev/null @@ -1,25 +0,0 @@ -package ru.betterend.entity.model; - -import java.util.function.Function; - -import net.minecraft.client.model.EntityModel; -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; - -public abstract class BlockBenchModel extends EntityModel { - public BlockBenchModel() { - super(); - } - - public BlockBenchModel(Function function) { - super(function); - } - - protected void setRotationAngle(ModelPart modelRenderer, float x, float y, float z) { - modelRenderer.xRot = x; - modelRenderer.yRot = y; - modelRenderer.zRot = z; - } -} diff --git a/src/main/java/ru/betterend/entity/model/CubozoaEntityModel.java b/src/main/java/ru/betterend/entity/model/CubozoaEntityModel.java deleted file mode 100644 index 91f0abda..00000000 --- a/src/main/java/ru/betterend/entity/model/CubozoaEntityModel.java +++ /dev/null @@ -1,104 +0,0 @@ -package ru.betterend.entity.model; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.util.Mth; -import ru.betterend.entity.CubozoaEntity; - -public class CubozoaEntityModel extends BlockBenchModel { - private final ModelPart model; - private final ModelPart main_cube_r1; - private final ModelPart tentacle_center_1; - private final ModelPart tentacle_1; - private final ModelPart tentacle_center_2; - private final ModelPart tentacle_2; - private final ModelPart tentacle_center_3; - private final ModelPart tentacle_3; - private final ModelPart tentacle_center_4; - private final ModelPart tentacle_4; - private float scaleY; - private float scaleXZ; - - public CubozoaEntityModel() { - super(RenderType::entityTranslucent); - - texWidth = 48; - texHeight = 48; - - model = new ModelPart(this); - model.setPos(0.0F, 24.0F, 0.0F); - model.texOffs(0, 17).addBox(-2.0F, -12.5F, -2.0F, 4.0F, 4.0F, 4.0F, 0.0F); - - main_cube_r1 = new ModelPart(this); - main_cube_r1.setPos(0.0F, -14.0F, 0.0F); - model.addChild(main_cube_r1); - setRotationAngle(main_cube_r1, 0.0F, 0.0F, -3.1416F); - main_cube_r1.texOffs(0, 0).addBox(-5.0F, -7.0F, -5.0F, 10.0F, 7.0F, 10.0F, 0.0F); - - tentacle_center_1 = new ModelPart(this); - tentacle_center_1.setPos(0.0F, 0.0F, 0.0F); - model.addChild(tentacle_center_1); - - - tentacle_1 = new ModelPart(this); - tentacle_1.setPos(0.0F, -7.0F, 4.5F); - tentacle_center_1.addChild(tentacle_1); - tentacle_1.texOffs(16, 17).addBox(-4.0F, 0.0F, 0.0F, 8.0F, 7.0F, 0.0F, 0.0F); - - tentacle_center_2 = new ModelPart(this); - tentacle_center_2.setPos(0.0F, 0.0F, 0.0F); - model.addChild(tentacle_center_2); - setRotationAngle(tentacle_center_2, 0.0F, -1.5708F, 0.0F); - - - tentacle_2 = new ModelPart(this); - tentacle_2.setPos(0.0F, -7.0F, 4.5F); - tentacle_center_2.addChild(tentacle_2); - tentacle_2.texOffs(16, 17).addBox(-4.0F, 0.0F, 0.0F, 8.0F, 7.0F, 0.0F, 0.0F); - - tentacle_center_3 = new ModelPart(this); - tentacle_center_3.setPos(0.0F, 0.0F, 0.0F); - model.addChild(tentacle_center_3); - setRotationAngle(tentacle_center_3, 0.0F, 3.1416F, 0.0F); - - - tentacle_3 = new ModelPart(this); - tentacle_3.setPos(0.0F, -7.0F, 4.5F); - tentacle_center_3.addChild(tentacle_3); - tentacle_3.texOffs(16, 17).addBox(-4.0F, 0.0F, 0.0F, 8.0F, 7.0F, 0.0F, 0.0F); - - tentacle_center_4 = new ModelPart(this); - tentacle_center_4.setPos(0.0F, 0.0F, 0.0F); - model.addChild(tentacle_center_4); - setRotationAngle(tentacle_center_4, 0.0F, 1.5708F, 0.0F); - - - tentacle_4 = new ModelPart(this); - tentacle_4.setPos(0.0F, -7.0F, 4.5F); - tentacle_center_4.addChild(tentacle_4); - tentacle_4.texOffs(16, 17).addBox(-4.0F, 0.0F, 0.0F, 8.0F, 7.0F, 0.0F, 0.0F); - } - - @Override - public void setupAnim(CubozoaEntity entity, float limbAngle, float limbDistance, float animationProgress, float headYaw, float headPitch) { - float sin = Mth.sin(animationProgress * 0.13F); - scaleY = sin * 0.1F + 0.9F; - scaleXZ = Mth.sin(animationProgress * 0.13F + 3.14F) * 0.1F + 0.9F; - - tentacle_1.xRot = sin * 0.15F; - tentacle_2.xRot = sin * 0.15F; - tentacle_3.xRot = sin * 0.15F; - tentacle_4.xRot = sin * 0.15F; - } - - @Override - public void renderToBuffer(PoseStack matrices, VertexConsumer vertices, int light, int overlay, float red, float green, float blue, float alpha) { - matrices.pushPose(); - matrices.scale(scaleXZ, scaleY, scaleXZ); - model.render(matrices, vertices, light, overlay); - matrices.popPose(); - } -} diff --git a/src/main/java/ru/betterend/entity/model/DragonflyEntityModel.java b/src/main/java/ru/betterend/entity/model/DragonflyEntityModel.java deleted file mode 100644 index 88162bc2..00000000 --- a/src/main/java/ru/betterend/entity/model/DragonflyEntityModel.java +++ /dev/null @@ -1,106 +0,0 @@ -package ru.betterend.entity.model; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.RenderType; -import ru.betterend.entity.DragonflyEntity; - -public class DragonflyEntityModel extends BlockBenchModel { - private final ModelPart model; - private final ModelPart head; - private final ModelPart tail; - private final ModelPart tail_2; - private final ModelPart wing_1; - private final ModelPart wing_2; - private final ModelPart wing_3; - private final ModelPart wing_4; - private final ModelPart legs_1; - private final ModelPart legs_2; - - public DragonflyEntityModel() { - super(RenderType::entityCutout); - - texWidth = 64; - texHeight = 64; - - model = new ModelPart(this); - model.setPos(2.0F, 21.5F, -4.0F); - model.texOffs(0, 0).addBox(-4.0F, -4.0F, 0.0F, 4.0F, 4.0F, 9.0F, 0.0F); - - head = new ModelPart(this); - head.setPos(-2.0F, -2.0F, 0.0F); - model.addChild(head); - setRotationAngle(head, 0.3491F, 0.0F, 0.0F); - head.texOffs(17, 0).addBox(-1.5F, -1.5F, -2.5F, 3.0F, 3.0F, 3.0F, 0.0F); - - tail = new ModelPart(this); - tail.setPos(-2.0F, -2.0F, 9.0F); - model.addChild(tail); - tail.texOffs(26, 0).addBox(-1.5F, -1.5F, 0.0F, 3.0F, 3.0F, 7.0F, 0.0F); - - tail_2 = new ModelPart(this); - tail_2.setPos(0.0F, 0.0F, 7.0F); - tail.addChild(tail_2); - tail_2.texOffs(36, 0).addBox(-1.0F, -1.0F, 0.0F, 2.0F, 2.0F, 10.0F, 0.0F); - - wing_1 = new ModelPart(this); - wing_1.setPos(-2.0F, -4.0F, 4.0F); - model.addChild(wing_1); - wing_1.texOffs(0, 13).addBox(-15.0F, 0.0F, -3.0F, 15.0F, 0.0F, 4.0F, 0.0F); - - wing_2 = new ModelPart(this); - wing_2.setPos(-2.0F, -4.0F, 4.0F); - model.addChild(wing_2); - wing_2.mirror = true; - wing_2.texOffs(0, 13).addBox(0.0F, 0.0F, -3.0F, 15.0F, 0.0F, 4.0F, 0.0F); - - wing_3 = new ModelPart(this); - wing_3.setPos(-2.0F, -4.0F, 8.0F); - model.addChild(wing_3); - wing_3.texOffs(4, 17).addBox(-12.0F, 0.0F, -2.5F, 12.0F, 0.0F, 3.0F, 0.0F); - - wing_4 = new ModelPart(this); - wing_4.setPos(-2.0F, -4.0F, 8.0F); - model.addChild(wing_4); - wing_4.mirror = true; - wing_4.texOffs(4, 17).addBox(0.0F, 0.0F, -2.5F, 12.0F, 0.0F, 3.0F, 0.0F); - - legs_1 = new ModelPart(this); - legs_1.setPos(-1.0F, 0.0F, 1.0F); - model.addChild(legs_1); - setRotationAngle(legs_1, 0.0F, 0.0F, -0.5236F); - legs_1.texOffs(50, 1).addBox(0.0F, 0.0F, 0.0F, 0.0F, 3.0F, 6.0F, 0.0F); - - legs_2 = new ModelPart(this); - legs_2.setPos(-3.0F, 0.0F, 1.0F); - model.addChild(legs_2); - setRotationAngle(legs_2, 0.0F, 0.0F, 0.5236F); - legs_2.texOffs(50, 1).addBox(0.0F, 0.0F, 0.0F, 0.0F, 3.0F, 6.0F, 0.0F); - } - - @Override - public void setupAnim(DragonflyEntity entity, float limbAngle, float limbDistance, float animationProgress, - float headYaw, float headPitch) { - float progress = animationProgress * 2F; - - wing_1.zRot = 0.3491F + (float) Math.sin(progress) * 0.3491F; - wing_2.zRot = -wing_1.zRot; - - wing_3.zRot = 0.3491F + (float) Math.cos(progress) * 0.3491F; - wing_4.zRot = -wing_3.zRot; - - progress = animationProgress * 0.05F; - - head.xRot = 0.3491F + (float) Math.sin(progress * 0.7F) * 0.1F; - tail.xRot = (float) Math.cos(progress) * 0.05F - 0.05F; - tail_2.xRot = -tail.xRot * 1.5F; - } - - @Override - public void renderToBuffer(PoseStack matrices, VertexConsumer vertices, int light, int overlay, float red, - float green, float blue, float alpha) { - model.render(matrices, vertices, light, overlay); - } -} diff --git a/src/main/java/ru/betterend/entity/model/EndFishEntityModel.java b/src/main/java/ru/betterend/entity/model/EndFishEntityModel.java deleted file mode 100644 index ebfe8f7b..00000000 --- a/src/main/java/ru/betterend/entity/model/EndFishEntityModel.java +++ /dev/null @@ -1,76 +0,0 @@ -package ru.betterend.entity.model; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.RenderType; -import ru.betterend.entity.EndFishEntity; - -public class EndFishEntityModel extends BlockBenchModel { - private final ModelPart model; - private final ModelPart fin_top; - private final ModelPart fin_bottom; - private final ModelPart flipper; - private final ModelPart fin_right; - private final ModelPart fin_left; - - public EndFishEntityModel() { - super(RenderType::entityCutout); - - texWidth = 32; - texHeight = 32; - - model = new ModelPart(this); - model.setPos(0.0F, 20.0F, 0.0F); - model.texOffs(0, 0).addBox(-1.0F, -2.0F, -4.0F, 2.0F, 4.0F, 8.0F, 0.0F); - - fin_top = new ModelPart(this); - fin_top.setPos(0.0F, -2.0F, -4.0F); - model.addChild(fin_top); - setRotationAngle(fin_top, -0.6981F, 0.0F, 0.0F); - fin_top.texOffs(0, 6).addBox(0.0F, -8.0F, 0.0F, 0.0F, 8.0F, 6.0F, 0.0F); - - fin_bottom = new ModelPart(this); - fin_bottom.setPos(0.0F, 2.0F, -4.0F); - model.addChild(fin_bottom); - setRotationAngle(fin_bottom, 0.6981F, 0.0F, 0.0F); - fin_bottom.texOffs(0, 6).addBox(0.0F, 0.0F, 0.0F, 0.0F, 8.0F, 6.0F, 0.0F); - - flipper = new ModelPart(this); - flipper.setPos(0.0F, 0.0F, 2.0F); - model.addChild(flipper); - setRotationAngle(flipper, -0.7854F, 0.0F, 0.0F); - flipper.texOffs(0, 15).addBox(0.0F, -5.0F, 0.0F, 0.0F, 5.0F, 5.0F, 0.0F); - - fin_right = new ModelPart(this); - fin_right.setPos(-1.0F, 0.0F, -1.0F); - model.addChild(fin_right); - setRotationAngle(fin_right, 1.5708F, 0.7854F, 0.0F); - fin_right.texOffs(0, 25).addBox(-3.7071F, 0.7071F, -1.5F, 3.0F, 0.0F, 3.0F, 0.0F); - - fin_left = new ModelPart(this); - fin_left.setPos(1.0F, 0.0F, -1.0F); - model.addChild(fin_left); - setRotationAngle(fin_left, 1.5708F, -0.7854F, 0.0F); - fin_left.texOffs(0, 25).addBox(0.7071F, 0.7071F, -1.5F, 3.0F, 0.0F, 3.0F, 0.0F, true); - } - - @Override - public void setupAnim(EndFishEntity entity, float limbAngle, float limbDistance, float animationProgress, - float headYaw, float headPitch) { - float s1 = (float) Math.sin(animationProgress * 0.1); - float s2 = (float) Math.sin(animationProgress * 0.05); - flipper.yRot = s1 * 0.3F; - fin_top.xRot = s2 * 0.02F - 0.6981F; - fin_bottom.xRot = 0.6981F - s2 * 0.02F; - fin_left.yRot = s1 * 0.3F - 0.7854F; - fin_right.yRot = 0.7854F - s1 * 0.3F; - } - - @Override - public void renderToBuffer(PoseStack matrices, VertexConsumer vertices, int light, int overlay, float red, - float green, float blue, float alpha) { - model.render(matrices, vertices, light, overlay); - } -} diff --git a/src/main/java/ru/betterend/entity/model/EndSlimeEntityModel.java b/src/main/java/ru/betterend/entity/model/EndSlimeEntityModel.java deleted file mode 100644 index 5d3bb97d..00000000 --- a/src/main/java/ru/betterend/entity/model/EndSlimeEntityModel.java +++ /dev/null @@ -1,83 +0,0 @@ -package ru.betterend.entity.model; - -import com.google.common.collect.ImmutableList; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import net.minecraft.client.model.ListModel; -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.RenderType; -import ru.bclib.util.MHelper; -import ru.betterend.entity.EndSlimeEntity; - -public class EndSlimeEntityModel extends ListModel { - private final ModelPart flower; - private final ModelPart crop; - private final ModelPart innerCube; - private final ModelPart rightEye; - private final ModelPart leftEye; - private final ModelPart mouth; - - public EndSlimeEntityModel(boolean onlyShell) { - super(RenderType::entityCutout); - - this.innerCube = new ModelPart(this, 0, 16); - this.rightEye = new ModelPart(this, 32, 0); - this.leftEye = new ModelPart(this, 32, 4); - this.mouth = new ModelPart(this, 32, 8); - this.flower = new ModelPart(this); - this.crop = new ModelPart(this); - - if (onlyShell) { - this.innerCube.texOffs(0, 0); - this.innerCube.addBox(-4.0F, 16.0F, -4.0F, 8.0F, 8.0F, 8.0F); - } else { - this.innerCube.addBox(-3.0F, 17.0F, -3.0F, 6.0F, 6.0F, 6.0F); - this.rightEye.addBox(-3.25F, 18.0F, -3.5F, 2.0F, 2.0F, 2.0F); - this.leftEye.addBox(1.25F, 18.0F, -3.5F, 2.0F, 2.0F, 2.0F); - this.mouth.addBox(0.0F, 21.0F, -3.5F, 1.0F, 1.0F, 1.0F); - - for (int i = 0; i < 4; i++) { - ModelPart petalRot = new ModelPart(this); - petalRot.yRot = MHelper.degreesToRadians(i * 45F); - - ModelPart petal = new ModelPart(this, 40, 0); - petal.setPos(-4, 8, 0); - petal.addBox(0.0F, 0.0F, 0.0F, 8.0F, 8.0F, 0.0F, 0.0F); - - this.flower.addChild(petalRot); - petalRot.addChild(petal); - } - - for (int i = 0; i < 2; i++) { - ModelPart petalRot = new ModelPart(this); - petalRot.yRot = MHelper.degreesToRadians(i * 90F + 45F); - - ModelPart petal = new ModelPart(this, 40, 0); - petal.setPos(-4, 8, 0); - petal.addBox(0.0F, 0.0F, 0.0F, 8.0F, 8.0F, 0.0F, 0.0F); - - this.crop.addChild(petalRot); - petalRot.addChild(petal); - } - } - } - - @Override - public void setupAnim(T entity, float limbAngle, float limbDistance, float animationProgress, float headYaw, - float headPitch) { - } - - public void renderFlower(PoseStack matrices, VertexConsumer vertices, int light, int overlay) { - flower.render(matrices, vertices, light, overlay); - } - - public void renderCrop(PoseStack matrices, VertexConsumer vertices, int light, int overlay) { - crop.render(matrices, vertices, light, overlay); - } - - @Override - public Iterable parts() { - return ImmutableList.of(this.innerCube, this.rightEye, this.leftEye, this.mouth); - } -} diff --git a/src/main/java/ru/betterend/entity/model/SilkMothEntityModel.java b/src/main/java/ru/betterend/entity/model/SilkMothEntityModel.java deleted file mode 100644 index 5d21fafe..00000000 --- a/src/main/java/ru/betterend/entity/model/SilkMothEntityModel.java +++ /dev/null @@ -1,138 +0,0 @@ -package ru.betterend.entity.model; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.util.Mth; -import ru.betterend.entity.SilkMothEntity; - -public class SilkMothEntityModel extends BlockBenchModel { - private final ModelPart legsL; - private final ModelPart cube_r1; - private final ModelPart cube_r2; - private final ModelPart cube_r3; - private final ModelPart legsR; - private final ModelPart cube_r4; - private final ModelPart cube_r5; - private final ModelPart cube_r6; - private final ModelPart head_pivot; - private final ModelPart tendril_r_r1; - private final ModelPart tendril_r_r2; - private final ModelPart bb_main; - private final ModelPart wingR_r1; - private final ModelPart wingL_r1; - private final ModelPart abdomen_r1; - - public SilkMothEntityModel() { - super(RenderType::entityCutout); - - texWidth = 64; - texHeight = 64; - - legsL = new ModelPart(this); - legsL.setPos(1.5F, 19.9F, -0.45F); - setRotationAngle(legsL, 0.0F, 0.0F, 0.6981F); - - cube_r1 = new ModelPart(this); - cube_r1.setPos(0.0F, 0.0F, -1.0F); - legsL.addChild(cube_r1); - setRotationAngle(cube_r1, 0.0F, 0.2182F, 0.3927F); - cube_r1.texOffs(0, 13).addBox(0.0216F, 0.0F, -0.5976F, 3.0F, 0.0F, 1.0F, 0.0F); - - cube_r2 = new ModelPart(this); - cube_r2.setPos(0.5F, 0.1F, -0.05F); - legsL.addChild(cube_r2); - setRotationAngle(cube_r2, 0.0F, 0.0F, 0.3927F); - cube_r2.texOffs(0, 15).addBox(0.0F, 0.0F, -0.6F, 3.0F, 0.0F, 1.0F, 0.0F); - - cube_r3 = new ModelPart(this); - cube_r3.setPos(0.0F, 0.0F, 0.9F); - legsL.addChild(cube_r3); - setRotationAngle(cube_r3, 0.0F, -0.2182F, 0.3927F); - cube_r3.texOffs(0, 14).addBox(0.0F, 0.0F, -0.5F, 3.0F, 0.0F, 1.0F, 0.0F); - - legsR = new ModelPart(this); - legsR.setPos(-1.5F, 19.9F, -0.55F); - setRotationAngle(legsR, 0.0F, 3.1416F, -0.6545F); - - cube_r4 = new ModelPart(this); - cube_r4.setPos(0.0F, 0.0F, -1.0F); - legsR.addChild(cube_r4); - setRotationAngle(cube_r4, 0.0F, 0.2182F, 0.3927F); - cube_r4.texOffs(0, 10).addBox(0.0F, 0.0F, -0.5F, 3.0F, 0.0F, 1.0F, 0.0F); - - cube_r5 = new ModelPart(this); - cube_r5.setPos(0.5F, 0.1F, -0.05F); - legsR.addChild(cube_r5); - setRotationAngle(cube_r5, 0.0F, 0.0F, 0.3927F); - cube_r5.texOffs(0, 11).addBox(0.0F, 0.0F, -0.4F, 3.0F, 0.0F, 1.0F, 0.0F); - - cube_r6 = new ModelPart(this); - cube_r6.setPos(0.0F, 0.0F, 0.9F); - legsR.addChild(cube_r6); - setRotationAngle(cube_r6, 0.0F, -0.2182F, 0.3927F); - cube_r6.texOffs(0, 12).addBox(0.0216F, 0.0F, -0.4024F, 3.0F, 0.0F, 1.0F, 0.0F); - - head_pivot = new ModelPart(this); - head_pivot.setPos(0.0F, 18.0F, -3.0F); - head_pivot.texOffs(15, 10).addBox(-1.5F, -1.5F, -2.0F, 3.0F, 3.0F, 3.0F, 0.0F); - - tendril_r_r1 = new ModelPart(this); - tendril_r_r1.setPos(1.0F, -1.15F, -1.0F); - head_pivot.addChild(tendril_r_r1); - setRotationAngle(tendril_r_r1, 0.0F, 0.0F, 0.3927F); - tendril_r_r1.texOffs(23, 0).addBox(-1.5F, -5.0F, 0.0F, 3.0F, 5.0F, 0.0F, 0.0F, true); - - tendril_r_r2 = new ModelPart(this); - tendril_r_r2.setPos(-1.0F, -1.15F, -1.0F); - head_pivot.addChild(tendril_r_r2); - setRotationAngle(tendril_r_r2, 0.0F, 0.0F, -0.3927F); - tendril_r_r2.texOffs(23, 0).addBox(-1.5F, -5.0F, 0.0F, 3.0F, 5.0F, 0.0F, 0.0F); - - bb_main = new ModelPart(this); - bb_main.setPos(0.0F, 24.0F, 0.0F); - bb_main.texOffs(19, 19).addBox(-2.5F, -8.5F, -3.0F, 5.0F, 5.0F, 3.0F, 0.0F); - - wingR_r1 = new ModelPart(this); - wingR_r1.setPos(-1.5F, -6.5F, 0.5F); - bb_main.addChild(wingR_r1); - setRotationAngle(wingR_r1, 0.0F, 0.0F, 0.3927F); - wingR_r1.texOffs(0, 5).addBox(-7.0F, 0.0F, -3.0F, 9.0F, 0.0F, 5.0F, 0.0F, true); - - wingL_r1 = new ModelPart(this); - wingL_r1.setPos(1.5F, -6.5F, 0.5F); - bb_main.addChild(wingL_r1); - setRotationAngle(wingL_r1, 0.0F, 0.0F, -0.3927F); - wingL_r1.texOffs(0, 5).addBox(-2.0F, 0.0F, -3.0F, 9.0F, 0.0F, 5.0F, 0.0F); - - abdomen_r1 = new ModelPart(this); - abdomen_r1.setPos(1.0F, -3.9F, 0.0F); - bb_main.addChild(abdomen_r1); - setRotationAngle(abdomen_r1, -0.3927F, 0.0F, 0.0F); - abdomen_r1.texOffs(0, 10).addBox(-3.0F, -4.0F, -1.0F, 4.0F, 4.0F, 7.0F, 0.0F); - } - - @Override - public void setupAnim(SilkMothEntity entity, float limbAngle, float limbDistance, float animationProgress, - float headYaw, float headPitch) { - wingR_r1.zRot = Mth.sin(animationProgress * 2F) * 0.4F + 0.3927F; - wingL_r1.zRot = -wingR_r1.zRot; - head_pivot.xRot = Mth.sin(animationProgress * 0.03F) * 0.1F; - tendril_r_r1.zRot = Mth.sin(animationProgress * 0.07F) * 0.2F + 0.3927F; - tendril_r_r2.zRot = -tendril_r_r1.zRot; - abdomen_r1.xRot = Mth.sin(animationProgress * 0.05F) * 0.1F - 0.3927F; - legsR.zRot = Mth.sin(animationProgress * 0.07F) * 0.1F - 0.6545F; - legsL.zRot = -legsR.zRot; - } - - @Override - public void renderToBuffer(PoseStack matrices, VertexConsumer vertices, int light, int overlay, float red, - float green, float blue, float alpha) { - bb_main.render(matrices, vertices, light, overlay); - head_pivot.render(matrices, vertices, light, overlay); - legsL.render(matrices, vertices, light, overlay); - legsR.render(matrices, vertices, light, overlay); - } -} diff --git a/src/main/java/ru/betterend/entity/render/RendererEntityCubozoa.java b/src/main/java/ru/betterend/entity/render/RendererEntityCubozoa.java deleted file mode 100644 index 5b6b78fe..00000000 --- a/src/main/java/ru/betterend/entity/render/RendererEntityCubozoa.java +++ /dev/null @@ -1,55 +0,0 @@ -package ru.betterend.entity.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.entity.EntityRenderDispatcher; -import net.minecraft.client.renderer.entity.MobRenderer; -import net.minecraft.client.renderer.entity.layers.EyesLayer; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.resources.ResourceLocation; -import ru.betterend.BetterEnd; -import ru.betterend.entity.CubozoaEntity; -import ru.betterend.entity.model.CubozoaEntityModel; - -public class RendererEntityCubozoa extends MobRenderer { - private static final ResourceLocation[] TEXTURE = new ResourceLocation[2]; - private static final RenderType[] GLOW = new RenderType[2]; - - public RendererEntityCubozoa(EntityRenderDispatcher entityRenderDispatcher) { - super(entityRenderDispatcher, new CubozoaEntityModel(), 0.5f); - this.addLayer(new EyesLayer(this) { - @Override - public RenderType renderType() { - return GLOW[0]; - } - - @Override - public void render(PoseStack matrices, MultiBufferSource vertexConsumers, int light, CubozoaEntity entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(GLOW[entity.getVariant()]); - this.getParentModel().renderToBuffer(matrices, vertexConsumer, 15728640, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); - } - }); - } - - @Override - protected void scale(CubozoaEntity entity, PoseStack matrixStack, float f) { - float scale = entity.getScale(); - matrixStack.scale(scale, scale, scale); - } - - @Override - public ResourceLocation getTextureLocation(CubozoaEntity entity) { - return TEXTURE[entity.getVariant()]; - } - - static { - TEXTURE[0] = BetterEnd.makeID("textures/entity/cubozoa/cubozoa.png"); - TEXTURE[1] = BetterEnd.makeID("textures/entity/cubozoa/cubozoa_sulphur.png"); - - GLOW[0] = RenderType.eyes(BetterEnd.makeID("textures/entity/cubozoa/cubozoa_glow.png")); - GLOW[1] = RenderType.eyes(BetterEnd.makeID("textures/entity/cubozoa/cubozoa_sulphur_glow.png")); - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/entity/render/RendererEntityEndFish.java b/src/main/java/ru/betterend/entity/render/RendererEntityEndFish.java deleted file mode 100644 index fce70f61..00000000 --- a/src/main/java/ru/betterend/entity/render/RendererEntityEndFish.java +++ /dev/null @@ -1,57 +0,0 @@ -package ru.betterend.entity.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.entity.EntityRenderDispatcher; -import net.minecraft.client.renderer.entity.MobRenderer; -import net.minecraft.client.renderer.entity.layers.EyesLayer; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.resources.ResourceLocation; -import ru.betterend.BetterEnd; -import ru.betterend.entity.EndFishEntity; -import ru.betterend.entity.model.EndFishEntityModel; - -public class RendererEntityEndFish extends MobRenderer { - private static final ResourceLocation[] TEXTURE = new ResourceLocation[EndFishEntity.VARIANTS]; - private static final RenderType[] GLOW = new RenderType[EndFishEntity.VARIANTS]; - - public RendererEntityEndFish(EntityRenderDispatcher entityRenderDispatcher) { - super(entityRenderDispatcher, new EndFishEntityModel(), 0.5f); - this.addLayer(new EyesLayer(this) { - @Override - public RenderType renderType() { - return GLOW[0]; - } - - @Override - public void render(PoseStack matrices, MultiBufferSource vertexConsumers, int light, EndFishEntity entity, - float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, - float headPitch) { - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(GLOW[entity.getVariant()]); - this.getParentModel().renderToBuffer(matrices, vertexConsumer, 15728640, OverlayTexture.NO_OVERLAY, - 1.0F, 1.0F, 1.0F, 1.0F); - } - }); - } - - @Override - protected void scale(EndFishEntity entity, PoseStack matrixStack, float f) { - float scale = entity.getScale(); - matrixStack.scale(scale, scale, scale); - } - - @Override - public ResourceLocation getTextureLocation(EndFishEntity entity) { - return TEXTURE[entity.getVariant()]; - } - - static { - for (int i = 0; i < EndFishEntity.VARIANTS; i++) { - TEXTURE[i] = BetterEnd.makeID("textures/entity/end_fish/end_fish_" + i + ".png"); - GLOW[i] = RenderType.eyes(BetterEnd.makeID("textures/entity/end_fish/end_fish_" + i + "_glow.png")); - } - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/entity/render/RendererEntityEndSlime.java b/src/main/java/ru/betterend/entity/render/RendererEntityEndSlime.java deleted file mode 100644 index 3fad8fc1..00000000 --- a/src/main/java/ru/betterend/entity/render/RendererEntityEndSlime.java +++ /dev/null @@ -1,116 +0,0 @@ -package ru.betterend.entity.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.entity.EntityRenderDispatcher; -import net.minecraft.client.renderer.entity.LivingEntityRenderer; -import net.minecraft.client.renderer.entity.MobRenderer; -import net.minecraft.client.renderer.entity.RenderLayerParent; -import net.minecraft.client.renderer.entity.layers.EyesLayer; -import net.minecraft.client.renderer.entity.layers.RenderLayer; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Mth; -import ru.betterend.BetterEnd; -import ru.betterend.entity.EndSlimeEntity; -import ru.betterend.entity.model.EndSlimeEntityModel; - -public class RendererEntityEndSlime extends MobRenderer> { - private static final ResourceLocation TEXTURE[] = new ResourceLocation[4]; - private static final RenderType GLOW[] = new RenderType[4]; - - public RendererEntityEndSlime(EntityRenderDispatcher entityRenderDispatcher) { - super(entityRenderDispatcher, new EndSlimeEntityModel(false), 0.25F); - this.addLayer(new OverlayFeatureRenderer(this)); - this.addLayer(new EyesLayer>(this) { - @Override - public RenderType renderType() { - return GLOW[0]; - } - - @Override - public void render(PoseStack matrices, MultiBufferSource vertexConsumers, int light, EndSlimeEntity entity, - float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, - float headPitch) { - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(GLOW[entity.getSlimeType()]); - this.getParentModel().renderToBuffer(matrices, vertexConsumer, 15728640, OverlayTexture.NO_OVERLAY, - 1.0F, 1.0F, 1.0F, 1.0F); - if (entity.isLake()) { - this.getParentModel().renderFlower(matrices, vertexConsumer, 15728640, OverlayTexture.NO_OVERLAY); - } - } - }); - } - - @Override - public ResourceLocation getTextureLocation(EndSlimeEntity entity) { - return TEXTURE[entity.getSlimeType()]; - } - - @Override - public void render(EndSlimeEntity slimeEntity, float f, float g, PoseStack matrixStack, - MultiBufferSource vertexConsumerProvider, int i) { - this.shadowRadius = 0.25F * (float) slimeEntity.getSize(); - super.render(slimeEntity, f, g, matrixStack, vertexConsumerProvider, i); - } - - @Override - protected void scale(EndSlimeEntity slimeEntity, PoseStack matrixStack, float f) { - matrixStack.scale(0.999F, 0.999F, 0.999F); - matrixStack.translate(0.0D, 0.0010000000474974513D, 0.0D); - float h = (float) slimeEntity.getSize(); - float i = Mth.lerp(f, slimeEntity.oSquish, slimeEntity.squish) / (h * 0.5F + 1.0F); - float j = 1.0F / (i + 1.0F); - matrixStack.scale(j * h, 1.0F / j * h, j * h); - } - - private final class OverlayFeatureRenderer - extends RenderLayer> { - private final EndSlimeEntityModel modelOrdinal = new EndSlimeEntityModel(true); - private final EndSlimeEntityModel modelLake = new EndSlimeEntityModel(true); - - public OverlayFeatureRenderer(RenderLayerParent> featureRendererContext) { - super(featureRendererContext); - } - - public void render(PoseStack matrixStack, MultiBufferSource vertexConsumerProvider, int i, T livingEntity, - float f, float g, float h, float j, float k, float l) { - if (!livingEntity.isInvisible()) { - if (livingEntity.isLake()) { - VertexConsumer vertexConsumer = vertexConsumerProvider - .getBuffer(RenderType.entityCutout(this.getTextureLocation(livingEntity))); - this.getParentModel().renderFlower(matrixStack, vertexConsumer, i, - LivingEntityRenderer.getOverlayCoords(livingEntity, 0.0F)); - } else if (livingEntity.isAmber() || livingEntity.isChorus()) { - VertexConsumer vertexConsumer = vertexConsumerProvider - .getBuffer(RenderType.entityCutout(this.getTextureLocation(livingEntity))); - this.getParentModel().renderCrop(matrixStack, vertexConsumer, i, - LivingEntityRenderer.getOverlayCoords(livingEntity, 0.0F)); - } - - EndSlimeEntityModel model = livingEntity.getSlimeType() == 1 ? modelLake : modelOrdinal; - this.getParentModel().copyPropertiesTo(model); - model.prepareMobModel(livingEntity, f, g, h); - model.setupAnim(livingEntity, f, g, j, k, l); - VertexConsumer vertexConsumer = vertexConsumerProvider - .getBuffer(RenderType.entityTranslucent(this.getTextureLocation(livingEntity))); - model.renderToBuffer(matrixStack, vertexConsumer, i, - LivingEntityRenderer.getOverlayCoords(livingEntity, 0.0F), 1.0F, 1.0F, 1.0F, 1.0F); - } - } - } - - static { - TEXTURE[0] = BetterEnd.makeID("textures/entity/end_slime/end_slime.png"); - TEXTURE[1] = BetterEnd.makeID("textures/entity/end_slime/end_slime_mossy.png"); - TEXTURE[2] = BetterEnd.makeID("textures/entity/end_slime/end_slime_lake.png"); - TEXTURE[3] = BetterEnd.makeID("textures/entity/end_slime/end_slime_amber.png"); - GLOW[0] = RenderType.eyes(BetterEnd.makeID("textures/entity/end_slime/end_slime_glow.png")); - GLOW[1] = GLOW[0]; - GLOW[2] = RenderType.eyes(BetterEnd.makeID("textures/entity/end_slime/end_slime_lake_glow.png")); - GLOW[3] = RenderType.eyes(BetterEnd.makeID("textures/entity/end_slime/end_slime_amber_glow.png")); - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/entity/render/RendererEntityShadowWalker.java b/src/main/java/ru/betterend/entity/render/RendererEntityShadowWalker.java deleted file mode 100644 index d75db944..00000000 --- a/src/main/java/ru/betterend/entity/render/RendererEntityShadowWalker.java +++ /dev/null @@ -1,22 +0,0 @@ -package ru.betterend.entity.render; - -import net.minecraft.client.model.PlayerModel; -import net.minecraft.client.renderer.entity.EntityRenderDispatcher; -import net.minecraft.client.renderer.entity.HumanoidMobRenderer; -import net.minecraft.resources.ResourceLocation; -import ru.betterend.BetterEnd; -import ru.betterend.entity.ShadowWalkerEntity; - -public class RendererEntityShadowWalker - extends HumanoidMobRenderer> { - private static final ResourceLocation TEXTURE = BetterEnd.makeID("textures/entity/shadow_walker.png"); - - public RendererEntityShadowWalker(EntityRenderDispatcher entityRenderDispatcher) { - super(entityRenderDispatcher, new PlayerModel(0.0F, false), 0.5F); - } - - @Override - public ResourceLocation getTextureLocation(ShadowWalkerEntity zombieEntity) { - return TEXTURE; - } -} diff --git a/src/main/java/ru/betterend/entity/render/SilkMothEntityRenderer.java b/src/main/java/ru/betterend/entity/render/SilkMothEntityRenderer.java deleted file mode 100644 index 7d3a2745..00000000 --- a/src/main/java/ru/betterend/entity/render/SilkMothEntityRenderer.java +++ /dev/null @@ -1,21 +0,0 @@ -package ru.betterend.entity.render; - -import net.minecraft.client.renderer.entity.EntityRenderDispatcher; -import net.minecraft.client.renderer.entity.MobRenderer; -import net.minecraft.resources.ResourceLocation; -import ru.betterend.BetterEnd; -import ru.betterend.entity.SilkMothEntity; -import ru.betterend.entity.model.SilkMothEntityModel; - -public class SilkMothEntityRenderer extends MobRenderer { - private static final ResourceLocation TEXTURE = BetterEnd.makeID("textures/entity/silk_moth.png"); - - public SilkMothEntityRenderer(EntityRenderDispatcher entityRenderDispatcher) { - super(entityRenderDispatcher, new SilkMothEntityModel(), 0.5f); - } - - @Override - public ResourceLocation getTextureLocation(SilkMothEntity entity) { - return TEXTURE; - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/events/ItemTooltipCallback.java b/src/main/java/ru/betterend/events/ItemTooltipCallback.java deleted file mode 100644 index 3173e5f6..00000000 --- a/src/main/java/ru/betterend/events/ItemTooltipCallback.java +++ /dev/null @@ -1,32 +0,0 @@ -package ru.betterend.events; - -import java.util.List; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.network.chat.Component; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; - -@Environment(EnvType.CLIENT) -public interface ItemTooltipCallback { - /** - * Fired after the game has appended all base tooltip lines to the list. - */ - Event EVENT = EventFactory.createArrayBacked(ItemTooltipCallback.class, callbacks -> (player, stack, context, lines) -> { - for (ItemTooltipCallback callback : callbacks) { - callback.getTooltip(player, stack, context, lines); - } - }); - - /** - * Called when an item stack's tooltip is rendered. Text added to {@code lines} will be - * rendered with the tooltip. - * - * @param lines the list containing the lines of text displayed on the stack's tooltip - */ - void getTooltip(Player player, ItemStack stack, TooltipFlag context, List lines); -} diff --git a/src/main/java/ru/betterend/events/PlayerAdvancementsCallback.java b/src/main/java/ru/betterend/events/PlayerAdvancementsCallback.java deleted file mode 100644 index 8c6aca1a..00000000 --- a/src/main/java/ru/betterend/events/PlayerAdvancementsCallback.java +++ /dev/null @@ -1,17 +0,0 @@ -package ru.betterend.events; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.advancements.Advancement; -import net.minecraft.server.level.ServerPlayer; - -public interface PlayerAdvancementsCallback { - - Event PLAYER_ADVANCEMENT_COMPLETE = EventFactory.createArrayBacked(PlayerAdvancementsCallback.class, callbacks -> (player, advancement, criterionName) -> { - for (PlayerAdvancementsCallback event : callbacks) { - event.onAdvancementComplete(player, advancement, criterionName); - } - }); - - void onAdvancementComplete(ServerPlayer player, Advancement advancement, String criterionName); -} diff --git a/src/main/java/ru/betterend/integration/EndBiomeIntegration.java b/src/main/java/ru/betterend/integration/EndBiomeIntegration.java deleted file mode 100644 index 023f0e6a..00000000 --- a/src/main/java/ru/betterend/integration/EndBiomeIntegration.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.betterend.integration; - -public interface EndBiomeIntegration { - void addBiomes(); -} diff --git a/src/main/java/ru/betterend/integration/FlamboyantRefabricatedIntegration.java b/src/main/java/ru/betterend/integration/FlamboyantRefabricatedIntegration.java deleted file mode 100644 index c123c9a9..00000000 --- a/src/main/java/ru/betterend/integration/FlamboyantRefabricatedIntegration.java +++ /dev/null @@ -1,52 +0,0 @@ -package ru.betterend.integration; - -import java.awt.Color; -import java.util.Map; - -import com.google.common.collect.Maps; - -import net.minecraft.world.level.ItemLike; -import ru.bclib.integration.ModIntegration; -import ru.bclib.util.ColorUtil; -import ru.betterend.blocks.HydraluxPetalColoredBlock; -import ru.betterend.blocks.complex.ColoredMaterial; -import ru.betterend.registry.EndBlocks; - -public class FlamboyantRefabricatedIntegration extends ModIntegration { - public FlamboyantRefabricatedIntegration() { - super("flamboyant"); - } - - @Override - public void init() { - Map colors = Maps.newHashMap(); - Map dyes = Maps.newHashMap(); - - addColor("fead1d", "amber", colors, dyes); - addColor("bd9a5f", "beige", colors, dyes); - addColor("edeada", "cream", colors, dyes); - addColor("33430e", "dark_green", colors, dyes); - addColor("639920", "forest_green", colors, dyes); - addColor("f0618c", "hot_pink", colors, dyes); - addColor("491c7b", "indigo", colors, dyes); - addColor("65291b", "maroon", colors, dyes); - addColor("2c3969", "navy", colors, dyes); - addColor("827c17", "olive", colors, dyes); - addColor("7bc618", "pale_green", colors, dyes); - addColor("f4a4bd", "pale_pink", colors, dyes); - addColor("f8d45a", "pale_yellow", colors, dyes); - addColor("6bb1cf", "sky_blue", colors, dyes); - addColor("6e8c9c", "slate_gray", colors, dyes); - addColor("b02454", "violet", colors, dyes); - - new ColoredMaterial(HydraluxPetalColoredBlock::new, EndBlocks.HYDRALUX_PETAL_BLOCK, colors, dyes, true); - } - - private void addColor(String hex, String name, Map colors, Map dyes) { - int color = ColorUtil.color(hex); - colors.put(color, name); - dyes.put(color, getItem(name + "_dye")); - - System.out.println(name + " " + color + " " + new Color(color)); - } -} diff --git a/src/main/java/ru/betterend/integration/Integrations.java b/src/main/java/ru/betterend/integration/Integrations.java deleted file mode 100644 index f611af4d..00000000 --- a/src/main/java/ru/betterend/integration/Integrations.java +++ /dev/null @@ -1,53 +0,0 @@ -package ru.betterend.integration; - -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import ru.bclib.api.ModIntegrationAPI; -import ru.bclib.integration.ModIntegration; -import ru.bclib.recipes.GridRecipe; -import ru.betterend.BetterEnd; -import ru.betterend.config.Configs; -import ru.betterend.events.PlayerAdvancementsCallback; -import ru.betterend.integration.byg.BYGIntegration; -import ru.betterend.item.GuideBookItem; -import ru.betterend.registry.EndItems; - -public class Integrations { - public static final ModIntegration BYG = ModIntegrationAPI.register(new BYGIntegration()); - public static final ModIntegration NOURISH = ModIntegrationAPI.register(new NourishIntegration()); - public static final ModIntegration FLAMBOYANT_REFABRICATED = ModIntegrationAPI.register(new FlamboyantRefabricatedIntegration()); - - private static boolean hasHydrogen; - - public static void init() { - if (hasGuideBook()) { - GuideBookItem.register(); - - PlayerAdvancementsCallback.PLAYER_ADVANCEMENT_COMPLETE.register((player, advancement, criterionName) -> { - ResourceLocation advId = new ResourceLocation("minecraft:end/enter_end_gateway"); - if (advId.equals(advancement.getId())) { - player.addItem(new ItemStack(GuideBookItem.GUIDE_BOOK)); - } - }); - - GridRecipe.make(BetterEnd.MOD_ID, "guide_book", GuideBookItem.GUIDE_BOOK) - .checkConfig(Configs.RECIPE_CONFIG) - .setShape("D", "B", "C") - .addMaterial('D', EndItems.ENDER_DUST) - .addMaterial('B', Items.BOOK) - .addMaterial('C', EndItems.CRYSTAL_SHARDS) - .build(); - } - hasHydrogen = FabricLoader.getInstance().isModLoaded("hydrogen"); - } - - public static boolean hasGuideBook() { - return FabricLoader.getInstance().isModLoaded("patchouli"); - } - - public static boolean hasHydrogen() { - return hasHydrogen; - } -} diff --git a/src/main/java/ru/betterend/integration/NourishIntegration.java b/src/main/java/ru/betterend/integration/NourishIntegration.java deleted file mode 100644 index 71f6cd47..00000000 --- a/src/main/java/ru/betterend/integration/NourishIntegration.java +++ /dev/null @@ -1,55 +0,0 @@ -package ru.betterend.integration; - -import net.minecraft.tags.Tag; -import net.minecraft.world.item.Item; -import ru.bclib.integration.ModIntegration; -import ru.bclib.util.TagHelper; -import ru.betterend.registry.EndItems; - -public class NourishIntegration extends ModIntegration { - public NourishIntegration() { - super("nourish"); - } - - @Override - public void init() { - Tag.Named fats = getItemTag("fats"); - Tag.Named fruit = getItemTag("fruit"); - Tag.Named protein = getItemTag("protein"); - Tag.Named sweets = getItemTag("sweets"); - - TagHelper.addTag( - fats, - EndItems.END_FISH_RAW, - EndItems.END_FISH_COOKED - ); - TagHelper.addTag( - fruit, - EndItems.SHADOW_BERRY_RAW, - EndItems.SHADOW_BERRY_COOKED, - EndItems.BLOSSOM_BERRY, - EndItems.SHADOW_BERRY_JELLY, - EndItems.SWEET_BERRY_JELLY, - EndItems.BLOSSOM_BERRY_JELLY, - EndItems.AMBER_ROOT_RAW, - EndItems.CHORUS_MUSHROOM_RAW, - EndItems.CHORUS_MUSHROOM_COOKED, - EndItems.BOLUX_MUSHROOM_COOKED - ); - TagHelper.addTag( - protein, - EndItems.END_FISH_RAW, - EndItems.END_FISH_COOKED, - EndItems.CHORUS_MUSHROOM_COOKED, - EndItems.BOLUX_MUSHROOM_COOKED, - EndItems.CAVE_PUMPKIN_PIE - ); - TagHelper.addTag( - sweets, - EndItems.SHADOW_BERRY_JELLY, - EndItems.SWEET_BERRY_JELLY, - EndItems.BLOSSOM_BERRY_JELLY, - EndItems.CAVE_PUMPKIN_PIE - ); - } -} diff --git a/src/main/java/ru/betterend/integration/byg/BYGBlocks.java b/src/main/java/ru/betterend/integration/byg/BYGBlocks.java deleted file mode 100644 index 18ceff7a..00000000 --- a/src/main/java/ru/betterend/integration/byg/BYGBlocks.java +++ /dev/null @@ -1,15 +0,0 @@ -package ru.betterend.integration.byg; - -import net.minecraft.world.level.block.Block; -import ru.bclib.blocks.BaseVineBlock; -import ru.betterend.blocks.basis.EndWallPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class BYGBlocks { - public static final Block IVIS_MOSS = EndBlocks.registerBlock("ivis_moss", new EndWallPlantBlock()); - public static final Block NIGHTSHADE_MOSS = EndBlocks.registerBlock("nightshade_moss", new EndWallPlantBlock()); - - public static final Block IVIS_VINE = EndBlocks.registerBlock("ivis_vine", new BaseVineBlock()); - - public static void register() {} -} diff --git a/src/main/java/ru/betterend/integration/byg/BYGIntegration.java b/src/main/java/ru/betterend/integration/byg/BYGIntegration.java deleted file mode 100644 index 7306d1dd..00000000 --- a/src/main/java/ru/betterend/integration/byg/BYGIntegration.java +++ /dev/null @@ -1,82 +0,0 @@ -package ru.betterend.integration.byg; - -import java.util.List; -import java.util.stream.Collectors; - -import net.minecraft.data.BuiltinRegistries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.ai.behavior.WeightedList; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import ru.bclib.api.BiomeAPI; -import ru.bclib.api.TagAPI; -import ru.bclib.integration.ModIntegration; -import ru.bclib.util.TagHelper; -import ru.bclib.world.biomes.BCLBiome; -import ru.betterend.integration.EndBiomeIntegration; -import ru.betterend.integration.Integrations; -import ru.betterend.integration.byg.biomes.BYGBiomes; -import ru.betterend.integration.byg.features.BYGFeatures; -import ru.betterend.registry.EndBiomes; - -public class BYGIntegration extends ModIntegration implements EndBiomeIntegration { - public BYGIntegration() { - super("byg"); - } - - @Override - public void init() { - Block block = Integrations.BYG.getBlock("ivis_phylium"); - if (block != null) { - TagHelper.addTags(block, TagAPI.END_GROUND, TagAPI.GEN_TERRAIN); - } - BYGBlocks.register(); - BYGFeatures.register(); - BYGBiomes.register(); - } - - @Override - public void addBiomes() { - BYGBiomes.addBiomes(); - - Class biomeClass = this.getClass("corgiaoc.byg.common.world.biome.BYGEndBiome"); - List biomes = this.getStaticFieldValue(biomeClass, "BYG_END_BIOMES"); - - if (biomes != null && biomeClass != null) { - biomes.forEach((obj) -> { - Biome biome = this.getAndExecuteRuntime(biomeClass, obj, "getBiome"); - if (biome != null) { - ResourceLocation biomeID = BuiltinRegistries.BIOME.getKey(biome); - BCLBiome endBiome = BiomeAPI.getBiome(biomeID); - Biome edge = this.getAndExecuteRuntime(biomeClass, obj, "getEdge"); - if (edge != null) { - ResourceLocation edgeID = BuiltinRegistries.BIOME.getKey(edge); - EndBiomes.LAND_BIOMES.removeMutableBiome(edgeID); - EndBiomes.VOID_BIOMES.removeMutableBiome(edgeID); - BCLBiome edgeBiome = BiomeAPI.getBiome(edgeID); - endBiome.setEdge(edgeBiome); - } - else { - Boolean isVoid = this.getAndExecuteRuntime(biomeClass, obj, "isVoid"); - if (isVoid != null && isVoid.booleanValue()) { - EndBiomes.LAND_BIOMES.removeMutableBiome(biomeID); - EndBiomes.VOID_BIOMES.addBiomeMutable(endBiome); - } - WeightedList subBiomes = this.getAndExecuteRuntime(biomeClass, obj, "getHills"); - if (subBiomes != null) { - subBiomes.stream().collect(Collectors.toList()).forEach((id) -> { - BCLBiome subBiome = BiomeAPI.getBiome(id); - EndBiomes.LAND_BIOMES.removeMutableBiome(id); - EndBiomes.VOID_BIOMES.removeMutableBiome(id); - if (!endBiome.containsSubBiome(subBiome)) { - EndBiomes.SUBBIOMES.add(subBiome); - endBiome.addSubBiome(subBiome); - } - }); - } - } - } - }); - } - } -} diff --git a/src/main/java/ru/betterend/integration/byg/biomes/BYGBiomes.java b/src/main/java/ru/betterend/integration/byg/biomes/BYGBiomes.java deleted file mode 100644 index 013afbe9..00000000 --- a/src/main/java/ru/betterend/integration/byg/biomes/BYGBiomes.java +++ /dev/null @@ -1,22 +0,0 @@ -package ru.betterend.integration.byg.biomes; - -import ru.betterend.integration.Integrations; -import ru.betterend.registry.EndBiomes; -import ru.betterend.world.biome.EndBiome; - -public class BYGBiomes { - // New Biomes - public static final EndBiome OLD_BULBIS_GARDENS = EndBiomes.registerSubBiomeIntegration(new OldBulbisGardens()); - public static final EndBiome NIGHTSHADE_REDWOODS = EndBiomes.registerSubBiomeIntegration(new NightshadeRedwoods()); - //public static final EndBiome ETHERIAL_GROVE = EndBiomes.registerSubBiomeIntegration(new EterialGrove()); - - public static void register() { - System.out.println("Registered " + OLD_BULBIS_GARDENS); - } - - public static void addBiomes() { - EndBiomes.addSubBiomeIntegration(OLD_BULBIS_GARDENS, Integrations.BYG.getID("bulbis_gardens")); - EndBiomes.addSubBiomeIntegration(NIGHTSHADE_REDWOODS, Integrations.BYG.getID("nightshade_forest")); - //EndBiomes.addSubBiomeIntegration(ETHERIAL_GROVE, Integrations.BYG.getID("ethereal_islands")); - } -} diff --git a/src/main/java/ru/betterend/integration/byg/biomes/NightshadeRedwoods.java b/src/main/java/ru/betterend/integration/byg/biomes/NightshadeRedwoods.java deleted file mode 100644 index 61e48d18..00000000 --- a/src/main/java/ru/betterend/integration/byg/biomes/NightshadeRedwoods.java +++ /dev/null @@ -1,65 +0,0 @@ -package ru.betterend.integration.byg.biomes; - -import java.util.List; - -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.entity.MobCategory; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSpecialEffects; -import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData; -import net.minecraft.world.level.levelgen.GenerationStep.Decoration; -import ru.bclib.BCLib; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.integration.Integrations; -import ru.betterend.integration.byg.features.BYGFeatures; -import ru.betterend.registry.EndFeatures; -import ru.betterend.world.biome.EndBiome; - -public class NightshadeRedwoods extends EndBiome { - public NightshadeRedwoods() { - super(makeDef()); - } - - private static BCLBiomeDef makeDef() { - Biome biome = Integrations.BYG.getBiome("nightshade_forest"); - BiomeSpecialEffects effects = biome.getSpecialEffects(); - - BCLBiomeDef def = new BCLBiomeDef(BetterEnd.makeID("nightshade_redwoods")) - .setFogColor(140, 108, 47) - .setFogDensity(1.5F) - .setWaterAndFogColor(55, 70, 186) - .setFoliageColor(122, 17, 155) - .setParticles(ParticleTypes.REVERSE_PORTAL, 0.002F) - .setSurface(biome.getGenerationSettings().getSurfaceBuilder().get()) - .setGrassColor(48, 13, 89) - .setPlantsColor(200, 125, 9) - .addFeature(EndFeatures.END_LAKE_RARE) - .addFeature(BYGFeatures.NIGHTSHADE_REDWOOD_TREE) - .addFeature(BYGFeatures.NIGHTSHADE_MOSS_WOOD) - .addFeature(BYGFeatures.NIGHTSHADE_MOSS); - - if (BCLib.isClient()) { - SoundEvent loop = effects.getAmbientLoopSoundEvent().get(); - SoundEvent music = effects.getBackgroundMusic().get().getEvent(); - SoundEvent additions = effects.getAmbientAdditionsSettings().get().getSoundEvent(); - SoundEvent mood = effects.getAmbientMoodSettings().get().getSoundEvent(); - def.setLoop(loop).setMusic(music).setAdditions(additions).setMood(mood); - } - biome.getGenerationSettings().features().forEach((list) -> { - list.forEach((feature) -> { - def.addFeature(Decoration.VEGETAL_DECORATION, feature.get()); - }); - }); - - for (MobCategory group: MobCategory.values()) { - List list = biome.getMobSettings().getMobs(group); - list.forEach((entry) -> { - def.addMobSpawn(entry); - }); - } - - return def; - } -} diff --git a/src/main/java/ru/betterend/integration/byg/biomes/OldBulbisGardens.java b/src/main/java/ru/betterend/integration/byg/biomes/OldBulbisGardens.java deleted file mode 100644 index 27bcd5a0..00000000 --- a/src/main/java/ru/betterend/integration/byg/biomes/OldBulbisGardens.java +++ /dev/null @@ -1,92 +0,0 @@ -package ru.betterend.integration.byg.biomes; - -import java.util.List; -import java.util.function.Supplier; - -import net.minecraft.core.Registry; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.data.BuiltinRegistries; -import net.minecraft.data.worldgen.Features; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.entity.MobCategory; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSpecialEffects; -import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.levelgen.GenerationStep.Decoration; -import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; -import ru.bclib.BCLib; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.integration.Integrations; -import ru.betterend.integration.byg.features.BYGFeatures; -import ru.betterend.registry.EndFeatures; -import ru.betterend.world.biome.EndBiome; - -public class OldBulbisGardens extends EndBiome { - public OldBulbisGardens() { - super(makeDef()); - } - - private static BCLBiomeDef makeDef() { - Biome biome = Integrations.BYG.getBiome("bulbis_gardens"); - BiomeSpecialEffects effects = biome.getSpecialEffects(); - - Block ivis = Integrations.BYG.getBlock("ivis_phylium"); - Block origin = biome.getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial().getBlock(); - BCLBiomeDef def = new BCLBiomeDef(BetterEnd.makeID("old_bulbis_gardens")) - .setFogColor(215, 132, 207) - .setFogDensity(1.8F) - .setWaterAndFogColor(40, 0, 56) - .setFoliageColor(122, 17, 155) - .setParticles(ParticleTypes.REVERSE_PORTAL, 0.002F) - .setSurface(ivis, origin) - .addFeature(EndFeatures.END_LAKE_RARE) - .addFeature(BYGFeatures.OLD_BULBIS_TREE); - - if (BCLib.isClient()) { - SoundEvent loop = effects.getAmbientLoopSoundEvent().get(); - SoundEvent music = effects.getBackgroundMusic().get().getEvent(); - SoundEvent additions = effects.getAmbientAdditionsSettings().get().getSoundEvent(); - SoundEvent mood = effects.getAmbientMoodSettings().get().getSoundEvent(); - def.setLoop(loop).setMusic(music).setAdditions(additions).setMood(mood); - } - - for (MobCategory group: MobCategory.values()) { - List list = biome.getMobSettings().getMobs(group); - list.forEach((entry) -> { - def.addMobSpawn(entry); - }); - } - - List>>> features = biome.getGenerationSettings().features(); - List>> vegetal = features.get(Decoration.VEGETAL_DECORATION.ordinal()); - if (vegetal.size() > 2) { - Supplier> getter; - // Trees (first two features) - // I couldn't process them with conditions, so that's why they are hardcoded (paulevs) - for (int i = 0; i < 2; i++) { - getter = vegetal.get(i); - ConfiguredFeature feature = getter.get(); - ResourceLocation id = BetterEnd.makeID("obg_feature_" + i); - feature = Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, id, feature.decorated(Features.Decorators.HEIGHTMAP_SQUARE).countRandom(1)); - def.addFeature(Decoration.VEGETAL_DECORATION, feature); - } - // Grasses and other features - for (int i = 2; i < vegetal.size(); i++) { - getter = vegetal.get(i); - ConfiguredFeature feature = getter.get(); - def.addFeature(Decoration.VEGETAL_DECORATION, feature); - } - } - - def.addFeature(EndFeatures.PURPLE_POLYPORE) - .addFeature(BYGFeatures.IVIS_MOSS_WOOD) - .addFeature(BYGFeatures.IVIS_MOSS) - .addFeature(BYGFeatures.IVIS_VINE) - .addFeature(BYGFeatures.IVIS_SPROUT); - - return def; - } -} diff --git a/src/main/java/ru/betterend/integration/byg/features/BYGFeatures.java b/src/main/java/ru/betterend/integration/byg/features/BYGFeatures.java deleted file mode 100644 index 1a906683..00000000 --- a/src/main/java/ru/betterend/integration/byg/features/BYGFeatures.java +++ /dev/null @@ -1,31 +0,0 @@ -package ru.betterend.integration.byg.features; - -import net.minecraft.world.level.levelgen.feature.Feature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.world.features.BCLFeature; -import ru.betterend.BetterEnd; -import ru.betterend.integration.Integrations; -import ru.betterend.integration.byg.BYGBlocks; -import ru.betterend.world.features.SinglePlantFeature; -import ru.betterend.world.features.VineFeature; -import ru.betterend.world.features.WallPlantFeature; -import ru.betterend.world.features.WallPlantOnLogFeature; - -public class BYGFeatures { - public static final BCLFeature OLD_BULBIS_TREE = redisterVegetation("old_bulbis_tree", new OldBulbisTreeFeature(), 1); - public static final BCLFeature IVIS_SPROUT = redisterVegetation("ivis_sprout", new SinglePlantFeature(Integrations.BYG.getBlock("ivis_sprout"), 6, 2), 6); - public static final BCLFeature IVIS_VINE = redisterVegetation("ivis_vine", new VineFeature(BYGBlocks.IVIS_VINE, 24), 5); - public static final BCLFeature IVIS_MOSS = redisterVegetation("ivis_moss", new WallPlantFeature(BYGBlocks.IVIS_MOSS, 6), 1); - public static final BCLFeature IVIS_MOSS_WOOD = redisterVegetation("ivis_moss_wood", new WallPlantOnLogFeature(BYGBlocks.IVIS_MOSS, 6), 15); - public static final BCLFeature NIGHTSHADE_MOSS = redisterVegetation("nightshade_moss", new WallPlantFeature(BYGBlocks.NIGHTSHADE_MOSS, 5), 2); - public static final BCLFeature NIGHTSHADE_MOSS_WOOD = redisterVegetation("nightshade_moss_wood", new WallPlantOnLogFeature(BYGBlocks.NIGHTSHADE_MOSS, 5), 8); - - public static final BCLFeature NIGHTSHADE_REDWOOD_TREE = redisterVegetation("nightshade_redwood_tree", new NightshadeRedwoodTreeFeature(), 1); - public static final BCLFeature BIG_ETHER_TREE = redisterVegetation("big_ether_tree", new BigEtherTreeFeature(), 1); - - public static void register() {} - - private static BCLFeature redisterVegetation(String name, Feature feature, int density) { - return BCLFeature.makeVegetationFeature(BetterEnd.makeID(name), feature, density); - } -} diff --git a/src/main/java/ru/betterend/integration/byg/features/BigEtherTreeFeature.java b/src/main/java/ru/betterend/integration/byg/features/BigEtherTreeFeature.java deleted file mode 100644 index 4883e4a5..00000000 --- a/src/main/java/ru/betterend/integration/byg/features/BigEtherTreeFeature.java +++ /dev/null @@ -1,76 +0,0 @@ -package ru.betterend.integration.byg.features; - -import java.util.List; -import java.util.Random; - -import com.google.common.base.Function; -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.integration.Integrations; - -public class BigEtherTreeFeature extends DefaultFeature { - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND)) - return false; - - BlockState log = Integrations.BYG.getDefaultState("ether_log"); - BlockState wood = Integrations.BYG.getDefaultState("ether_wood"); - Function splinePlacer = (bpos) -> { - return log; - }; - Function replace = (state) -> { - return state.is(TagAPI.END_GROUND) || state.getMaterial().equals(Material.PLANT) - || state.getMaterial().isReplaceable(); - }; - - int height = MHelper.randRange(40, 60, random); - List trunk = SplineHelper.makeSpline(0, 0, 0, 0, height, 0, height / 4); - SplineHelper.offsetParts(trunk, random, 2F, 0, 2F); - SDF sdf = SplineHelper.buildSDF(trunk, 2.3F, 0.8F, splinePlacer); - - int count = height / 15; - for (int i = 1; i < count; i++) { - float splinePos = (float) i / (float) count; - float startAngle = random.nextFloat() * MHelper.PI2; - float length = (1 - splinePos) * height * 0.4F; - int points = (int) (length / 3); - List branch = SplineHelper.makeSpline(0, 0, 0, length, 0, 0, points < 2 ? 2 : points); - SplineHelper.powerOffset(branch, length, 2F); - int rotCount = MHelper.randRange(5, 7, random); - Vector3f start = SplineHelper.getPos(trunk, splinePos * (trunk.size() - 1)); - for (int j = 0; j < rotCount; j++) { - float angle = startAngle + (float) j / rotCount * MHelper.PI2; - List br = SplineHelper.copySpline(branch); - SplineHelper.offsetParts(br, random, 0, 1, 1); - SplineHelper.rotateSpline(br, angle); - - SplineHelper.offset(br, start); - SplineHelper.fillSpline(br, world, wood, pos, replace); - } - } - - sdf.setReplaceFunction((state) -> { - return state.is(TagAPI.END_GROUND) || state.getMaterial().equals(Material.PLANT) - || state.getMaterial().isReplaceable(); - }).addPostProcess((info) -> { - if (info.getState().equals(log) && (!info.getStateUp().equals(log) || !info.getStateDown().equals(log))) { - return wood; - } - return info.getState(); - }).fillRecursive(world, pos); - - return true; - } -} diff --git a/src/main/java/ru/betterend/integration/byg/features/NightshadeRedwoodTreeFeature.java b/src/main/java/ru/betterend/integration/byg/features/NightshadeRedwoodTreeFeature.java deleted file mode 100644 index 43cd3689..00000000 --- a/src/main/java/ru/betterend/integration/byg/features/NightshadeRedwoodTreeFeature.java +++ /dev/null @@ -1,190 +0,0 @@ -package ru.betterend.integration.byg.features; - -import java.util.List; -import java.util.Random; - -import com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.LeavesBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.PosInfo; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFFlatWave; -import ru.bclib.sdf.operator.SDFSmoothUnion; -import ru.bclib.sdf.primitive.SDFCappedCone; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.integration.Integrations; - -public class NightshadeRedwoodTreeFeature extends DefaultFeature { - private static final List BRANCH; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND)) - return false; - - BlockState log = Integrations.BYG.getDefaultState("nightshade_log"); - BlockState wood = Integrations.BYG.getDefaultState("nightshade_wood"); - BlockState leaves = Integrations.BYG.getDefaultState("nightshade_leaves"); - BlockState leaves_flower = Integrations.BYG.getDefaultState("flowering_nightshade_leaves"); - - Function splinePlacer = (bpos) -> { - return log; - }; - Function replace = (state) -> { - return state.is(TagAPI.END_GROUND) || state.getMaterial().equals(Material.PLANT) - || state.getMaterial().isReplaceable(); - }; - Function post = (info) -> { - if (info.getState().equals(log) && (!info.getStateUp().equals(log) || !info.getStateDown().equals(log))) { - return wood; - } - return info.getState(); - }; - Function ignore = (state) -> { - return state.equals(log) || state.equals(wood); - }; - - int height = MHelper.randRange(40, 60, random); - List trunk = SplineHelper.makeSpline(0, 0, 0, 0, height, 0, height / 4); - SplineHelper.offsetParts(trunk, random, 0.8F, 0, 0.8F); - - if (!SplineHelper.canGenerate(trunk, pos, world, replace)) { - return false; - } - - int count = height >> 2; - float start = trunk.size() / 3F; - float delta = trunk.size() * 0.6F; - float max = height - 7; - float startAngle = random.nextFloat() * MHelper.PI2; - for (int i = 0; i < count; i++) { - float scale = (float) (count - i) / count * 15; - Vector3f offset = SplineHelper.getPos(trunk, (float) i / count * delta + start); - if (offset.y() > max) { - break; - } - List branch = SplineHelper.copySpline(BRANCH); - SplineHelper.rotateSpline(branch, i * 1.3F + startAngle); - SplineHelper.scale(branch, scale); - SplineHelper.offsetParts(branch, random, 0.3F, 0.3F, 0.3F); - SplineHelper.offset(branch, offset); - SplineHelper.fillSpline(branch, world, wood, pos, replace); - } - - SDF sdf = SplineHelper.buildSDF(trunk, 2.3F, 0.8F, splinePlacer); - SDF roots = new SDFSphere().setRadius(2F).setBlock(log); - roots = new SDFFlatWave().setIntensity(2F).setRaysCount(MHelper.randRange(5, 7, random)) - .setAngle(random.nextFloat() * MHelper.PI2).setSource(roots); - sdf = new SDFSmoothUnion().setRadius(2F).setSourceA(sdf).setSourceB(roots); - sdf.setReplaceFunction(replace).addPostProcess(post).fillRecursive(world, pos); - Vector3f last = SplineHelper.getPos(trunk, trunk.size() - 1.35F); - for (int y = 0; y < 8; y++) { - BlockPos p = pos.offset(last.x() + 0.5, last.y() + y, last.z() + 0.5); - BlocksHelper.setWithoutUpdate(world, p, y == 4 ? wood : log); - } - - for (int y = 0; y < 16; y++) { - BlockPos p = pos.offset(last.x() + 0.5, last.y() + y, last.z() + 0.5); - if (world.isEmptyBlock(p)) { - BlocksHelper.setWithoutUpdate(world, p, leaves); - } - float radius = (1 - y / 16F) * 3F; - int rad = (int) (radius + 1); - radius *= radius; - for (int x = -rad; x <= rad; x++) { - int x2 = x * x; - for (int z = -rad; z <= rad; z++) { - int z2 = z * z; - if (x2 + z2 < radius - random.nextFloat() * rad) { - BlockPos lp = p.offset(x, 0, z); - if (world.isEmptyBlock(lp)) { - BlocksHelper.setWithoutUpdate(world, lp, leaves); - } - } - } - } - } - - MutableBlockPos mut = new MutableBlockPos(); - Function leavesPost1 = (info) -> { - if (info.getState().equals(log) || info.getState().equals(wood)) { - for (int x = -6; x < 7; x++) { - int ax = Math.abs(x); - mut.setX(x + info.getPos().getX()); - for (int z = -6; z < 7; z++) { - int az = Math.abs(z); - mut.setZ(z + info.getPos().getZ()); - for (int y = -6; y < 7; y++) { - int ay = Math.abs(y); - int d = ax + ay + az; - if (d < 7) { - mut.setY(y + info.getPos().getY()); - BlockState state = info.getState(mut); - if (state.getBlock() instanceof LeavesBlock) { - int distance = state.getValue(LeavesBlock.DISTANCE); - if (d < distance) { - info.setState(mut, state.setValue(LeavesBlock.DISTANCE, d)); - } - } - } - } - } - } - } - return info.getState(); - }; - Function leavesPost2 = (info) -> { - if (info.getState().getBlock() instanceof LeavesBlock) { - int distance = info.getState().getValue(LeavesBlock.DISTANCE); - if (distance > MHelper.randRange(2, 4, random)) { - return Blocks.AIR.defaultBlockState(); - } - for (Direction d : BlocksHelper.DIRECTIONS) { - int airCount = 0; - if (info.getState(d).isAir()) { - airCount++; - } - if (airCount > 5) { - return Blocks.AIR.defaultBlockState(); - } - } - if (random.nextInt(8) == 0) { - return leaves_flower.setValue(LeavesBlock.DISTANCE, distance); - } - } - return info.getState(); - }; - - SDF canopy = new SDFCappedCone().setRadius1(12F).setRadius2(1f).setHeight(height * 0.3F).setBlock(leaves); - canopy = new SDFDisplacement().setFunction((vec) -> { - return MHelper.randRange(-3F, 3F, random); - }).setSource(canopy); - canopy.addPostProcess(leavesPost1).addPostProcess(leavesPost2).fillRecursiveIgnore(world, - pos.offset(0, height * 0.75, 0), ignore); - - return true; - } - - static { - BRANCH = Lists.newArrayList(new Vector3f(0, 0, 0), new Vector3f(0.25F, 0.1F, 0), new Vector3f(0.40F, 0.2F, 0), - new Vector3f(0.50F, 0.4F, 0), new Vector3f(0.55F, 0.6F, 0)); - } -} diff --git a/src/main/java/ru/betterend/integration/byg/features/OldBulbisTreeFeature.java b/src/main/java/ru/betterend/integration/byg/features/OldBulbisTreeFeature.java deleted file mode 100644 index 41830663..00000000 --- a/src/main/java/ru/betterend/integration/byg/features/OldBulbisTreeFeature.java +++ /dev/null @@ -1,183 +0,0 @@ -package ru.betterend.integration.byg.features; - -import java.util.List; -import java.util.Random; -import java.util.function.Function; - -import com.google.common.collect.Lists; -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.util.Mth; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.phys.AABB; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.operator.SDFUnion; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.integration.Integrations; -import ru.betterend.noise.OpenSimplexNoise; - -public class OldBulbisTreeFeature extends DefaultFeature { - private static final List SPLINE; - private static final List ROOT; - private static final List LEAF; - private static final List SIDE; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND)) - return false; - if (!world.getBlockState(pos.below(4)).getBlock().is(TagAPI.GEN_TERRAIN)) - return false; - - BlockState stem = Integrations.BYG.getDefaultState("bulbis_stem"); - BlockState wood = Integrations.BYG.getDefaultState("bulbis_wood"); - BlockState cap = Integrations.BYG - .getDefaultState(random.nextBoolean() ? "bulbis_shell" : "purple_bulbis_shell"); - BlockState glow = Integrations.BYG.getDefaultState("purple_shroomlight"); - - Function replacement = (state) -> { - if (state.equals(stem) || state.equals(wood) || state.is(TagAPI.END_GROUND) - || state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - - float size = MHelper.randRange(10, 20, random); - float addSize = MHelper.randRange(1, 1.7F, random); - float addRad = addSize * 0.5F + 0.5F; - int count = (int) (size * 0.15F); - size *= addSize; - float var = MHelper.PI2 / (float) (count * 3); - float start = MHelper.randRange(0, MHelper.PI2, random); - SDF sdf = null; - int x1 = ((pos.getX() >> 4) << 4) - 16; - int z1 = ((pos.getZ() >> 4) << 4) - 16; - AABB limits = new AABB(x1, pos.getY() - 5, z1, x1 + 47, pos.getY() + size * 2, z1 + 47); - for (int i = 0; i < count; i++) { - float angle = (float) i / (float) count * MHelper.PI2 + MHelper.randRange(0, var, random) + start; - List spline = SplineHelper.copySpline(SPLINE); - float sizeXZ = (size + MHelper.randRange(0, size * 0.5F, random)) * 0.7F; - SplineHelper.scale(spline, sizeXZ, sizeXZ * 1.5F + MHelper.randRange(0, size * 0.5F, random), sizeXZ); - SplineHelper.offset(spline, new Vector3f(size * random.nextFloat() * 0.3F, 0, 0)); - SplineHelper.rotateSpline(spline, angle); - SplineHelper.offsetParts(spline, random, 1F, 0, 1F);// 1.3F 0.8F - SDF branch = SplineHelper.buildSDF(spline, 2.3F * addRad, 1.3F * addRad, (bpos) -> { - return stem; - }); - - Vector3f vec = spline.get(spline.size() - 1); - float radius = (size + MHelper.randRange(0, size * 0.5F, random)) * 0.35F; - bigSphere(world, pos.offset(vec.x(), vec.y(), vec.z()), radius, cap, glow, wood, replacement, random); - vec = SplineHelper.getPos(spline, 0.3F); - makeRoots(world, pos.offset(vec.x(), vec.y(), vec.z()), size * 0.4F + 5, random, wood, replacement); - - sdf = (sdf == null) ? branch : new SDFUnion().setSourceA(sdf).setSourceB(branch); - } - - sdf.setReplaceFunction(replacement).addPostProcess((info) -> { - if (info.getState().equals(stem) - && (!info.getStateUp().equals(stem) || !info.getStateDown().equals(stem))) { - return wood; - } - return info.getState(); - }).fillArea(world, pos, limits); - - return true; - } - - private void bigSphere(WorldGenLevel world, BlockPos pos, float radius, BlockState cap, BlockState glow, - BlockState wood, Function replacement, Random random) { - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); - SDF sphere = new SDFSphere().setRadius(radius).setBlock(cap); - - SDF sphereInner = new SDFSphere().setRadius(radius * 0.53F).setBlock(Blocks.AIR); - sphereInner = new SDFDisplacement().setFunction((vec) -> { - return (float) noise.eval(vec.x() * 0.1, vec.y() * 0.1, vec.z() * 0.1); - }).setSource(sphereInner); - - SDF sphereGlow = new SDFSphere().setRadius(radius * 0.6F).setBlock(glow); - sphereGlow = new SDFDisplacement().setFunction((vec) -> { - return (float) noise.eval(vec.x() * 0.1, vec.y() * 0.1, vec.z() * 0.1) * 2F; - }).setSource(sphereGlow); - sphereGlow = new SDFSubtraction().setSourceA(sphereGlow).setSourceB(sphereInner); - - sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sphereGlow); - sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sphereInner); - - float offsetY = radius * 1.7F; - sphere = new SDFUnion().setSourceA(sphere).setSourceB(sphereGlow); - sphere = new SDFTranslate().setTranslate(0, offsetY, 0).setSource(sphere); - - int leafCount = (int) (radius * 0.5F) + 2; - for (int i = 0; i < 4; i++) { - float angle = (float) i / 4 * MHelper.PI2; - List spline = SplineHelper.copySpline(LEAF); - SplineHelper.rotateSpline(spline, angle); - SplineHelper.scale(spline, radius * 1.4F); - SplineHelper.fillSplineForce(spline, world, wood, pos, replacement); - - for (int j = 0; j < leafCount; j++) { - float delta = ((float) j / (float) (leafCount - 1)); - float scale = (float) Math.sin(delta * Math.PI) * 0.8F + 0.2F; - float index = Mth.lerp(delta, 1F, 3.9F); - Vector3f point = SplineHelper.getPos(spline, index); - - List side = SplineHelper.copySpline(SIDE); - SplineHelper.rotateSpline(side, angle); - SplineHelper.scale(side, scale * radius); - BlockPos p = pos.offset(point.x() + 0.5F, point.y() + 0.5F, point.z() + 0.5F); - SplineHelper.fillSplineForce(side, world, wood, p, replacement); - } - } - - sphere.fillArea(world, pos, new AABB(pos.above((int) offsetY)).inflate(radius * 1.3F)); - } - - private void makeRoots(WorldGenLevel world, BlockPos pos, float radius, Random random, BlockState wood, - Function replacement) { - int count = (int) (radius * 1.5F); - for (int i = 0; i < count; i++) { - float angle = (float) i / (float) count * MHelper.PI2; - float scale = radius * MHelper.randRange(0.85F, 1.15F, random); - - List branch = SplineHelper.copySpline(ROOT); - SplineHelper.rotateSpline(branch, angle); - SplineHelper.scale(branch, scale); - Vector3f last = branch.get(branch.size() - 1); - if (world.getBlockState(pos.offset(last.x(), last.y(), last.z())).is(TagAPI.GEN_TERRAIN)) { - SplineHelper.fillSpline(branch, world, wood, pos, replacement); - } - } - } - - static { - SPLINE = Lists.newArrayList(new Vector3f(0.00F, 0.00F, 0.00F), new Vector3f(0.10F, 0.35F, 0.00F), - new Vector3f(0.20F, 0.50F, 0.00F), new Vector3f(0.30F, 0.55F, 0.00F), new Vector3f(0.42F, 0.70F, 0.00F), - new Vector3f(0.50F, 1.00F, 0.00F)); - - ROOT = Lists.newArrayList(new Vector3f(0F, 1F, 0), new Vector3f(0.1F, 0.70F, 0), new Vector3f(0.3F, 0.30F, 0), - new Vector3f(0.7F, 0.05F, 0), new Vector3f(0.8F, -0.20F, 0)); - SplineHelper.offset(ROOT, new Vector3f(0, -0.45F, 0)); - - LEAF = Lists.newArrayList(new Vector3f(0.00F, 0.0F, 0), new Vector3f(0.10F, 0.4F, 0), - new Vector3f(0.40F, 0.8F, 0), new Vector3f(0.75F, 0.9F, 0), new Vector3f(1.00F, 0.8F, 0)); - - SIDE = Lists.newArrayList(new Vector3f(0, -0.3F, -0.5F), new Vector3f(0, -0.1F, -0.3F), - new Vector3f(0, 0.0F, 0.0F), new Vector3f(0, -0.1F, 0.3F), new Vector3f(0, -0.3F, 0.5F)); - } -} diff --git a/src/main/java/ru/betterend/integration/rei/REIAlloyingCategory.java b/src/main/java/ru/betterend/integration/rei/REIAlloyingCategory.java deleted file mode 100644 index 507cfc15..00000000 --- a/src/main/java/ru/betterend/integration/rei/REIAlloyingCategory.java +++ /dev/null @@ -1,89 +0,0 @@ -package ru.betterend.integration.rei; - -import java.text.DecimalFormat; -import java.util.List; - -import org.jetbrains.annotations.NotNull; - -import com.google.common.collect.Lists; -import com.mojang.blaze3d.vertex.PoseStack; - -import it.unimi.dsi.fastutil.ints.IntList; -import me.shedaniel.math.Point; -import me.shedaniel.math.Rectangle; -import me.shedaniel.rei.api.EntryStack; -import me.shedaniel.rei.api.TransferRecipeCategory; -import me.shedaniel.rei.api.widgets.Widgets; -import me.shedaniel.rei.gui.entries.RecipeEntry; -import me.shedaniel.rei.gui.entries.SimpleRecipeEntry; -import me.shedaniel.rei.gui.widget.Widget; -import net.minecraft.client.gui.GuiComponent; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.resources.ResourceLocation; -import ru.betterend.recipe.builders.AlloyingRecipe; -import ru.betterend.registry.EndBlocks; -import ru.betterend.util.LangUtil; - -public class REIAlloyingCategory implements TransferRecipeCategory { - - @Override - public @NotNull ResourceLocation getIdentifier() { - return AlloyingRecipe.ID; - } - - @Override - public @NotNull String getCategoryName() { - return LangUtil.translate(EndBlocks.END_STONE_SMELTER.getDescriptionId()); - } - - @Override - public @NotNull EntryStack getLogo() { - return REIPlugin.END_STONE_SMELTER; - } - - @Override - public @NotNull List setupDisplay(REIAlloyingDisplay display, Rectangle bounds) { - Point startPoint = new Point(bounds.getCenterX() - 41, bounds.y + 10); - double smeltTime = display.getSmeltTime(); - DecimalFormat df = new DecimalFormat("###.##"); - List widgets = Lists.newArrayList(); - widgets.add(Widgets.createRecipeBase(bounds)); - widgets.add(Widgets.createResultSlotBackground(new Point(startPoint.x + 61, startPoint.y + 9))); - widgets.add(Widgets.createBurningFire(new Point(startPoint.x - 9, startPoint.y + 20)).animationDurationMS(10000)); - widgets.add(Widgets.createLabel(new Point(bounds.x + bounds.width - 5, bounds.y + 5), - new TranslatableComponent("category.rei.cooking.time&xp", df.format(display.getXp()), df.format(smeltTime / 20D))).noShadow().rightAligned().color(0xFF404040, 0xFFBBBBBB)); - widgets.add(Widgets.createArrow(new Point(startPoint.x + 24, startPoint.y + 8)).animationDurationTicks(smeltTime)); - List> inputEntries = display.getInputEntries(); - widgets.add(Widgets.createSlot(new Point(startPoint.x - 20, startPoint.y + 1)).entries(inputEntries.get(0)).markInput()); - if (inputEntries.size() > 1) { - widgets.add(Widgets.createSlot(new Point(startPoint.x + 1, startPoint.y + 1)).entries(inputEntries.get(1)).markInput()); - } else { - widgets.add(Widgets.createSlot(new Point(startPoint.x + 1, startPoint.y + 1)).entries(Lists.newArrayList()).markInput()); - } - widgets.add(Widgets.createSlot(new Point(startPoint.x + 61, startPoint.y + 9)).entries(display.getResultingEntries().get(0)).disableBackground().markOutput()); - return widgets; - } - - @Override - public void renderRedSlots(PoseStack matrices, List widgets, Rectangle bounds, REIAlloyingDisplay display, - IntList redSlots) { - Point startPoint = new Point(bounds.getCenterX() - 41, bounds.getCenterY() - 27); - matrices.pushPose(); - matrices.translate(0, 0, 400); - if (redSlots.contains(0)) { - GuiComponent.fill(matrices, startPoint.x - 20, startPoint.y + 1, startPoint.x - 20 + 16, startPoint.y + 1 + 16, 1090453504); - GuiComponent.fill(matrices, startPoint.x + 1, startPoint.y + 1, startPoint.x + 1 + 16, startPoint.y + 1 + 16, 1090453504); - } - matrices.popPose(); - } - - @Override - public @NotNull RecipeEntry getSimpleRenderer(REIAlloyingDisplay recipe) { - return SimpleRecipeEntry.from(recipe.getInputEntries(), recipe.getResultingEntries()); - } - - @Override - public int getDisplayHeight() { - return 49; - } -} diff --git a/src/main/java/ru/betterend/integration/rei/REIAlloyingDisplay.java b/src/main/java/ru/betterend/integration/rei/REIAlloyingDisplay.java deleted file mode 100644 index 5937c021..00000000 --- a/src/main/java/ru/betterend/integration/rei/REIAlloyingDisplay.java +++ /dev/null @@ -1,111 +0,0 @@ -package ru.betterend.integration.rei; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.jetbrains.annotations.NotNull; - -import me.shedaniel.rei.api.EntryStack; -import me.shedaniel.rei.api.TransferRecipeDisplay; -import me.shedaniel.rei.server.ContainerInfo; -import net.minecraft.ChatFormatting; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.crafting.BlastingRecipe; -import net.minecraft.world.item.crafting.Recipe; -import ru.betterend.blocks.entities.EndStoneSmelterBlockEntity; -import ru.betterend.recipe.builders.AlloyingRecipe; - -public class REIAlloyingDisplay implements TransferRecipeDisplay { - - private static List fuel; - - private Recipe recipe; - private List> input; - private List output; - private float xp; - private double smeltTime; - - public REIAlloyingDisplay(AlloyingRecipe recipe) { - this.recipe = recipe; - this.input = EntryStack.ofIngredients(recipe.getIngredients()); - this.output = Collections.singletonList(EntryStack.create(recipe.getResultItem())); - this.xp = recipe.getExperience(); - this.smeltTime = recipe.getSmeltTime(); - } - - public REIAlloyingDisplay(BlastingRecipe recipe) { - this.recipe = recipe; - this.input = EntryStack.ofIngredients(recipe.getIngredients()); - this.output = Collections.singletonList(EntryStack.create(recipe.getResultItem())); - this.xp = recipe.getExperience(); - this.smeltTime = recipe.getCookingTime(); - } - - public static List getFuel() { - return fuel; - } - - @Override - public @NotNull Optional getRecipeLocation() { - return Optional.ofNullable(recipe).map(Recipe::getId); - } - - @Override - public @NotNull List> getInputEntries() { - return this.input; - } - - @Override - public @NotNull List> getResultingEntries() { - return Collections.singletonList(output); - } - - @Override - public @NotNull ResourceLocation getRecipeCategory() { - return AlloyingRecipe.ID; - } - - @Override - public @NotNull List> getRequiredEntries() { - return this.input; - } - - public float getXp() { - return this.xp; - } - - public double getSmeltTime() { - return this.smeltTime; - } - - public Optional> getOptionalRecipe() { - return Optional.ofNullable(recipe); - } - - @Override - public int getWidth() { - return 2; - } - - @Override - public int getHeight() { - return 1; - } - - @Override - public List> getOrganisedInputEntries(ContainerInfo containerInfo, AbstractContainerMenu container) { - return this.input; - } - - static { - fuel = EndStoneSmelterBlockEntity.availableFuels().keySet().stream() - .map(Item::getDefaultInstance).map(EntryStack::create) - .map(e -> e.setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, stack -> Collections.singletonList(new TranslatableComponent("category.rei.smelting.fuel") - .withStyle(ChatFormatting.YELLOW)))).collect(Collectors.toList()); - } -} diff --git a/src/main/java/ru/betterend/integration/rei/REIAlloyingFuelCategory.java b/src/main/java/ru/betterend/integration/rei/REIAlloyingFuelCategory.java deleted file mode 100644 index 8b7a552a..00000000 --- a/src/main/java/ru/betterend/integration/rei/REIAlloyingFuelCategory.java +++ /dev/null @@ -1,92 +0,0 @@ -package ru.betterend.integration.rei; - -import java.text.DecimalFormat; -import java.util.List; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import com.google.common.collect.Lists; -import com.mojang.blaze3d.vertex.PoseStack; - -import me.shedaniel.math.Point; -import me.shedaniel.math.Rectangle; -import me.shedaniel.rei.api.EntryStack; -import me.shedaniel.rei.api.RecipeCategory; -import me.shedaniel.rei.api.widgets.Slot; -import me.shedaniel.rei.api.widgets.Tooltip; -import me.shedaniel.rei.api.widgets.Widgets; -import me.shedaniel.rei.gui.entries.RecipeEntry; -import me.shedaniel.rei.gui.widget.Widget; -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.language.I18n; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Items; - -public class REIAlloyingFuelCategory implements RecipeCategory { - private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##"); - - @Override - public @NotNull ResourceLocation getIdentifier() { - return REIPlugin.ALLOYING_FUEL; - } - - @Override - public @NotNull String getCategoryName() { - return I18n.get("category.rei.fuel"); - } - - @Override - public int getDisplayHeight() { - return 49; - } - - @Override - public @NotNull EntryStack getLogo() { - return EntryStack.create(Items.COAL); - } - - @Override - public @NotNull List setupDisplay(REIAlloyingFuelDisplay recipeDisplay, Rectangle bounds) { - Point startPoint = new Point(bounds.getCenterX() - 41, bounds.getCenterY() - 17); - String burnTime = DECIMAL_FORMAT.format(recipeDisplay.getFuelTime()); - List widgets = Lists.newArrayList(); - widgets.add(Widgets.createRecipeBase(bounds)); - widgets.add(Widgets.createLabel(new Point(bounds.x + 26, bounds.getMaxY() - 15), new TranslatableComponent("category.rei.fuel.time", burnTime)) - .color(0xFF404040, 0xFFBBBBBB).noShadow().leftAligned()); - widgets.add(Widgets.createBurningFire(new Point(bounds.x + 6, startPoint.y + 1)).animationDurationTicks(recipeDisplay.getFuelTime())); - widgets.add(Widgets.createSlot(new Point(bounds.x + 6, startPoint.y + 18)).entries(recipeDisplay.getInputEntries().get(0)).markInput()); - return widgets; - } - - @Override - public @NotNull RecipeEntry getSimpleRenderer(REIAlloyingFuelDisplay recipe) { - Slot slot = Widgets.createSlot(new Point(0, 0)).entries(recipe.getInputEntries().get(0)).disableBackground().disableHighlight(); - String burnItems = DECIMAL_FORMAT.format(recipe.getFuelTime() / 200d); - return new RecipeEntry() { - private TranslatableComponent text = new TranslatableComponent("category.rei.fuel.time_short.items", burnItems); - - @Override - public int getHeight() { - return 22; - } - - @Nullable - @Override - public Tooltip getTooltip(Point point) { - if (slot.containsMouse(point)) - return slot.getCurrentTooltip(point); - return null; - } - - @Override - public void render(PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { - slot.setZ(getZ() + 50); - slot.getBounds().setLocation(bounds.x + 4, bounds.y + 2); - slot.render(matrices, mouseX, mouseY, delta); - Minecraft.getInstance().font.drawShadow(matrices, text.getVisualOrderText(), bounds.x + 25, bounds.y + 8, -1); - } - }; - } -} diff --git a/src/main/java/ru/betterend/integration/rei/REIAlloyingFuelDisplay.java b/src/main/java/ru/betterend/integration/rei/REIAlloyingFuelDisplay.java deleted file mode 100644 index d9e9d827..00000000 --- a/src/main/java/ru/betterend/integration/rei/REIAlloyingFuelDisplay.java +++ /dev/null @@ -1,40 +0,0 @@ -package ru.betterend.integration.rei; - -import java.util.Collections; -import java.util.List; - -import org.jetbrains.annotations.NotNull; - -import me.shedaniel.rei.api.EntryStack; -import me.shedaniel.rei.api.RecipeDisplay; -import net.minecraft.resources.ResourceLocation; - -public class REIAlloyingFuelDisplay implements RecipeDisplay { - private final EntryStack fuel; - private final int fuelTime; - - public REIAlloyingFuelDisplay(EntryStack fuel, int fuelTime) { - this.fuel = fuel; - this.fuelTime = fuelTime; - } - - @Override - public @NotNull List> getInputEntries() { - return Collections.singletonList(Collections.singletonList(fuel)); - } - - @Override - public @NotNull List> getResultingEntries() { - return Collections.emptyList(); - } - - @Override - public @NotNull ResourceLocation getRecipeCategory() { - return REIPlugin.ALLOYING_FUEL; - } - - public int getFuelTime() { - return fuelTime; - } - -} diff --git a/src/main/java/ru/betterend/integration/rei/REIAnvilCategory.java b/src/main/java/ru/betterend/integration/rei/REIAnvilCategory.java deleted file mode 100644 index fddf1a83..00000000 --- a/src/main/java/ru/betterend/integration/rei/REIAnvilCategory.java +++ /dev/null @@ -1,101 +0,0 @@ -package ru.betterend.integration.rei; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import org.jetbrains.annotations.NotNull; - -import com.google.common.collect.Lists; -import com.mojang.blaze3d.vertex.PoseStack; - -import it.unimi.dsi.fastutil.ints.IntList; -import me.shedaniel.math.Point; -import me.shedaniel.math.Rectangle; -import me.shedaniel.rei.api.EntryStack; -import me.shedaniel.rei.api.TransferRecipeCategory; -import me.shedaniel.rei.api.widgets.Widgets; -import me.shedaniel.rei.gui.entries.RecipeEntry; -import me.shedaniel.rei.gui.entries.SimpleRecipeEntry; -import me.shedaniel.rei.gui.widget.Widget; -import net.minecraft.client.gui.GuiComponent; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import ru.betterend.blocks.basis.EndAnvilBlock; -import ru.betterend.util.LangUtil; - -public class REIAnvilCategory implements TransferRecipeCategory { - - @Override - public @NotNull ResourceLocation getIdentifier() { - return REIPlugin.SMITHING; - } - - @Override - public @NotNull String getCategoryName() { - return LangUtil.translate(Blocks.ANVIL.getDescriptionId()); - } - - @Override - public @NotNull EntryStack getLogo() { - return REIPlugin.ANVILS[0]; - } - - @Override - public @NotNull List setupDisplay(REIAnvilDisplay display, Rectangle bounds) { - Point startPoint = new Point(bounds.getCenterX() - 41, bounds.y + 10); - List widgets = Lists.newArrayList(); - widgets.add(Widgets.createRecipeBase(bounds)); - int x = startPoint.x + 10; - int y = startPoint.y; - widgets.add(Widgets.createResultSlotBackground(new Point(x + 61, y + 5))); - List> inputEntries = display.getInputEntries(); - List materials = inputEntries.get(1); - int anvilLevel = display.getAnvilLevel(); - List anvils = Arrays.stream(REIPlugin.ANVILS).filter(anvil -> { - Block block = ((BlockItem) anvil.getItem()).getBlock(); - if (block instanceof EndAnvilBlock) { - return ((EndAnvilBlock) block).getCraftingLevel() >= anvilLevel; - } - return anvilLevel == 1; - }).collect(Collectors.toList()); - materials.forEach(entryStack -> entryStack.setAmount(display.getInputCount())); - widgets.add(Widgets.createArrow(new Point(x + 24, y + 4))); - widgets.add(Widgets.createLabel(new Point(bounds.x + bounds.width - 7, bounds.y + bounds.height - 15), - new TranslatableComponent("category.rei.damage.amount&dmg", display.getDamage())).noShadow().rightAligned().color(0xFF404040, 0xFFBBBBBB)); - widgets.add(Widgets.createSlot(new Point(x - 20, y + 4)).entries(materials).markInput()); - widgets.add(Widgets.createSlot(new Point(x + 1, y + 4)).entries(inputEntries.get(0)).markInput()); - widgets.add(Widgets.createSlot(new Point(x + 61, y + 5)).entries(display.getResultingEntries().get(0)).disableBackground().markOutput()); - widgets.add(Widgets.createSlot(new Point(x - 9, y + 25)).entries(anvils)); - - return widgets; - } - - @Override - public void renderRedSlots(PoseStack matrices, List widgets, Rectangle bounds, REIAnvilDisplay display, - IntList redSlots) { - Point startPoint = new Point(bounds.getCenterX() - 41, bounds.getCenterY() - 27); - matrices.pushPose(); - matrices.translate(0, 0, 400); - if (redSlots.contains(0)) { - GuiComponent.fill(matrices, startPoint.x - 20, startPoint.y + 3, startPoint.x - 20 + 16, startPoint.y + 3 + 16, 1090453504); - GuiComponent.fill(matrices, startPoint.x + 1, startPoint.y + 3, startPoint.x + 1 + 16, startPoint.y + 3 + 16, 1090453504); - } - matrices.popPose(); - } - - @Override - public @NotNull RecipeEntry getSimpleRenderer(REIAnvilDisplay recipe) { - return SimpleRecipeEntry.from(Collections.singletonList(recipe.getInputEntries().get(0)), recipe.getResultingEntries()); - } - - @Override - public int getDisplayHeight() { - return 60; - } - -} diff --git a/src/main/java/ru/betterend/integration/rei/REIAnvilDisplay.java b/src/main/java/ru/betterend/integration/rei/REIAnvilDisplay.java deleted file mode 100644 index 3ca2f929..00000000 --- a/src/main/java/ru/betterend/integration/rei/REIAnvilDisplay.java +++ /dev/null @@ -1,81 +0,0 @@ -package ru.betterend.integration.rei; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import org.jetbrains.annotations.NotNull; - -import me.shedaniel.rei.api.EntryStack; -import me.shedaniel.rei.api.TransferRecipeDisplay; -import me.shedaniel.rei.server.ContainerInfo; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.item.crafting.Recipe; -import ru.betterend.recipe.builders.AnvilRecipe; - -public class REIAnvilDisplay implements TransferRecipeDisplay { - - private final AnvilRecipe recipe; - private final List> input; - private final List output; - - public REIAnvilDisplay(AnvilRecipe recipe) { - this.recipe = recipe; - this.input = EntryStack.ofIngredients(recipe.getIngredients()); - this.output = Collections.singletonList(EntryStack.create(recipe.getResultItem())); - } - - public int getDamage() { - return recipe.getDamage(); - } - - public int getInputCount() { - return recipe.getInputCount(); - } - - public int getAnvilLevel() { - return recipe.getAnvilLevel(); - } - - @Override - public @NotNull Optional getRecipeLocation() { - return Optional.ofNullable(recipe).map(Recipe::getId); - } - - @Override - public @NotNull List> getInputEntries() { - return this.input; - } - - @Override - public @NotNull List> getResultingEntries() { - return Collections.singletonList(output); - } - - @Override - public @NotNull ResourceLocation getRecipeCategory() { - return REIPlugin.SMITHING; - } - - @Override - public @NotNull List> getRequiredEntries() { - return input; - } - - @Override - public int getWidth() { - return 2; - } - - @Override - public int getHeight() { - return 1; - } - - @Override - public List> getOrganisedInputEntries(ContainerInfo containerInfo, - AbstractContainerMenu container) { - return input; - } -} diff --git a/src/main/java/ru/betterend/integration/rei/REIContainer.java b/src/main/java/ru/betterend/integration/rei/REIContainer.java deleted file mode 100644 index 9d6a0118..00000000 --- a/src/main/java/ru/betterend/integration/rei/REIContainer.java +++ /dev/null @@ -1,14 +0,0 @@ -package ru.betterend.integration.rei; - -import me.shedaniel.rei.plugin.containers.CraftingContainerInfoWrapper; -import me.shedaniel.rei.server.ContainerInfoHandler; -import ru.betterend.client.gui.EndStoneSmelterScreenHandler; -import ru.betterend.recipe.builders.AlloyingRecipe; - -public class REIContainer implements Runnable { - - @Override - public void run() { - ContainerInfoHandler.registerContainerInfo(AlloyingRecipe.ID, CraftingContainerInfoWrapper.create(EndStoneSmelterScreenHandler.class)); - } -} diff --git a/src/main/java/ru/betterend/integration/rei/REIInfusionCategory.java b/src/main/java/ru/betterend/integration/rei/REIInfusionCategory.java deleted file mode 100644 index 5acb5b12..00000000 --- a/src/main/java/ru/betterend/integration/rei/REIInfusionCategory.java +++ /dev/null @@ -1,81 +0,0 @@ -package ru.betterend.integration.rei; - -import java.util.List; - -import org.jetbrains.annotations.NotNull; - -import com.google.common.collect.Lists; -import com.mojang.blaze3d.vertex.PoseStack; - -import it.unimi.dsi.fastutil.ints.IntList; -import me.shedaniel.math.Point; -import me.shedaniel.math.Rectangle; -import me.shedaniel.rei.api.EntryStack; -import me.shedaniel.rei.api.TransferRecipeCategory; -import me.shedaniel.rei.api.widgets.Widgets; -import me.shedaniel.rei.gui.entries.RecipeEntry; -import me.shedaniel.rei.gui.entries.SimpleRecipeEntry; -import me.shedaniel.rei.gui.widget.Widget; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.resources.ResourceLocation; -import ru.betterend.BetterEnd; -import ru.betterend.recipe.builders.InfusionRecipe; -import ru.betterend.registry.EndBlocks; -import ru.betterend.util.LangUtil; - -public class REIInfusionCategory implements TransferRecipeCategory { - - private final static ResourceLocation BACKGROUND = BetterEnd.makeID("textures/gui/rei_infusion.png"); - - @Override - public @NotNull ResourceLocation getIdentifier() { - return InfusionRecipe.ID; - } - - @Override - public @NotNull String getCategoryName() { - return LangUtil.translate(EndBlocks.INFUSION_PEDESTAL.getDescriptionId()); - } - - @Override - public @NotNull EntryStack getLogo() { - return REIPlugin.INFUSION_RITUAL; - } - - @Override - public @NotNull RecipeEntry getSimpleRenderer(REIInfusionDisplay recipe) { - return SimpleRecipeEntry.from(recipe.getInputEntries(), recipe.getResultingEntries()); - } - - @Override - public @NotNull List setupDisplay(REIInfusionDisplay display, Rectangle bounds) { - Point centerPoint = new Point(bounds.getCenterX() - 34, bounds.getCenterY() - 2); - List widgets = Lists.newArrayList(); - widgets.add(Widgets.createRecipeBase(bounds)); - List> inputEntries = display.getInputEntries(); - List> outputEntries = display.getResultingEntries(); - widgets.add(Widgets.createTexturedWidget(BACKGROUND, bounds.x, bounds.y, 0, 0, 150, 104, 150, 104)); - widgets.add(Widgets.createSlot(centerPoint).entries(inputEntries.get(0)).disableBackground().markInput()); - widgets.add(Widgets.createSlot(new Point(centerPoint.x, centerPoint.y - 28)).entries(inputEntries.get(1)).disableBackground().markInput()); - widgets.add(Widgets.createSlot(new Point(centerPoint.x + 28, centerPoint.y)).entries(inputEntries.get(3)).disableBackground().markInput()); - widgets.add(Widgets.createSlot(new Point(centerPoint.x, centerPoint.y + 28)).entries(inputEntries.get(5)).disableBackground().markInput()); - widgets.add(Widgets.createSlot(new Point(centerPoint.x - 28, centerPoint.y)).entries(inputEntries.get(7)).disableBackground().markInput()); - widgets.add(Widgets.createSlot(new Point(centerPoint.x + 24, centerPoint.y - 24)).entries(inputEntries.get(2)).disableBackground().markInput()); - widgets.add(Widgets.createSlot(new Point(centerPoint.x + 24, centerPoint.y + 24)).entries(inputEntries.get(4)).disableBackground().markInput()); - widgets.add(Widgets.createSlot(new Point(centerPoint.x - 24, centerPoint.y + 24)).entries(inputEntries.get(6)).disableBackground().markInput()); - widgets.add(Widgets.createSlot(new Point(centerPoint.x - 24, centerPoint.y - 24)).entries(inputEntries.get(8)).disableBackground().markInput()); - widgets.add(Widgets.createSlot(new Point(centerPoint.x + 80, centerPoint.y)).entries(outputEntries.get(0)).disableBackground().markOutput()); - widgets.add(Widgets.createLabel(new Point(bounds.getMaxX() - 5, bounds.y + 6), new TranslatableComponent("category.rei.infusion.time&val", display.getInfusionTime())) - .noShadow().rightAligned().color(0xFF404040, 0xFFBBBBBB)); - return widgets; - } - - @Override - public void renderRedSlots(PoseStack matrices, List widgets, Rectangle bounds, - REIInfusionDisplay display, IntList redSlots) {} - - @Override - public int getDisplayHeight() { - return 104; - } -} diff --git a/src/main/java/ru/betterend/integration/rei/REIInfusionDisplay.java b/src/main/java/ru/betterend/integration/rei/REIInfusionDisplay.java deleted file mode 100644 index d8411bc9..00000000 --- a/src/main/java/ru/betterend/integration/rei/REIInfusionDisplay.java +++ /dev/null @@ -1,81 +0,0 @@ -package ru.betterend.integration.rei; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import org.jetbrains.annotations.NotNull; - -import com.google.common.collect.Lists; - -import me.shedaniel.rei.api.EntryStack; -import me.shedaniel.rei.api.TransferRecipeDisplay; -import me.shedaniel.rei.server.ContainerInfo; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.item.crafting.Recipe; -import ru.betterend.recipe.builders.AlloyingRecipe; -import ru.betterend.recipe.builders.InfusionRecipe; - -public class REIInfusionDisplay implements TransferRecipeDisplay { - - private final InfusionRecipe recipe; - private final List> input; - private final List output; - private final int time; - - public REIInfusionDisplay(InfusionRecipe recipe) { - this.recipe = recipe; - this.input = Lists.newArrayList(); - this.output = Collections.singletonList(EntryStack.create(recipe.getResultItem())); - this.time = recipe.getInfusionTime(); - - recipe.getIngredients().forEach(ingredient -> { - input.add(EntryStack.ofIngredient(ingredient)); - }); - } - - public int getInfusionTime() { - return this.time; - } - - @Override - public @NotNull Optional getRecipeLocation() { - return Optional.ofNullable(recipe).map(Recipe::getId); - } - - @Override - public @NotNull List> getInputEntries() { - return this.input; - } - - @Override - public @NotNull List> getResultingEntries() { - return Collections.singletonList(output); - } - - @Override - public @NotNull ResourceLocation getRecipeCategory() { - return AlloyingRecipe.ID; - } - - @Override - public @NotNull List> getRequiredEntries() { - return this.input; - } - - @Override - public int getWidth() { - return 0; - } - - @Override - public int getHeight() { - return 0; - } - - @Override - public List> getOrganisedInputEntries(ContainerInfo containerInfo, AbstractContainerMenu container) { - return this.input; - } -} diff --git a/src/main/java/ru/betterend/integration/rei/REIPlugin.java b/src/main/java/ru/betterend/integration/rei/REIPlugin.java deleted file mode 100644 index e05fd55d..00000000 --- a/src/main/java/ru/betterend/integration/rei/REIPlugin.java +++ /dev/null @@ -1,89 +0,0 @@ -package ru.betterend.integration.rei; - -import java.util.List; -import java.util.stream.Collectors; - -import com.google.common.collect.Lists; - -import me.shedaniel.rei.api.EntryStack; -import me.shedaniel.rei.api.RecipeHelper; -import me.shedaniel.rei.api.plugins.REIPluginV0; -import me.shedaniel.rei.plugin.DefaultPlugin; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.impl.content.registry.FuelRegistryImpl; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.crafting.BlastingRecipe; -import net.minecraft.world.level.block.Blocks; -import ru.bclib.blocks.BaseFurnaceBlock; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.basis.EndAnvilBlock; -import ru.betterend.recipe.builders.AlloyingRecipe; -import ru.betterend.recipe.builders.AnvilRecipe; -import ru.betterend.recipe.builders.InfusionRecipe; -import ru.betterend.registry.EndBlocks; - -@Environment(EnvType.CLIENT) -public class REIPlugin implements REIPluginV0 { - - public final static ResourceLocation PLUGIN_ID = BetterEnd.makeID("rei_plugin"); - public final static ResourceLocation ALLOYING_FUEL = BetterEnd.makeID("alloying_fuel"); - public final static ResourceLocation ALLOYING = AlloyingRecipe.ID; - public final static ResourceLocation SMITHING = AnvilRecipe.ID; - public final static ResourceLocation INFUSION = InfusionRecipe.ID; - - public final static EntryStack END_STONE_SMELTER = EntryStack.create(EndBlocks.END_STONE_SMELTER); - public final static EntryStack INFUSION_RITUAL = EntryStack.create(EndBlocks.INFUSION_PEDESTAL); - public final static EntryStack[] FURNACES; - public final static EntryStack[] ANVILS; - - @Override - public ResourceLocation getPluginIdentifier() { - return PLUGIN_ID; - } - - @Override - public void registerRecipeDisplays(RecipeHelper recipeHelper) { - recipeHelper.registerRecipes(ALLOYING, AlloyingRecipe.class, REIAlloyingDisplay::new); - recipeHelper.registerRecipes(ALLOYING, BlastingRecipe.class, REIAlloyingDisplay::new); - recipeHelper.registerRecipes(SMITHING, AnvilRecipe.class, REIAnvilDisplay::new); - recipeHelper.registerRecipes(INFUSION, InfusionRecipe.class, REIInfusionDisplay::new); - FuelRegistryImpl.INSTANCE.getFuelTimes().forEach((item, time) -> { - if (time >= 2000) { - recipeHelper.registerDisplay(new REIAlloyingFuelDisplay(EntryStack.create(item), time)); - } - }); - } - - @Override - public void registerOthers(RecipeHelper recipeHelper) { - recipeHelper.registerWorkingStations(ALLOYING_FUEL, END_STONE_SMELTER); - recipeHelper.registerWorkingStations(ALLOYING, END_STONE_SMELTER); - recipeHelper.registerWorkingStations(INFUSION, INFUSION_RITUAL); - recipeHelper.registerWorkingStations(SMITHING, ANVILS); - recipeHelper.removeAutoCraftButton(ALLOYING_FUEL); - recipeHelper.removeAutoCraftButton(SMITHING); - - recipeHelper.registerWorkingStations(DefaultPlugin.SMELTING, FURNACES); - recipeHelper.registerWorkingStations(DefaultPlugin.FUEL, FURNACES); - } - - @Override - public void registerPluginCategories(RecipeHelper recipeHelper) { - recipeHelper.registerCategories( - new REIAlloyingFuelCategory(), - new REIAlloyingCategory(), - new REIInfusionCategory(), - new REIAnvilCategory()); - } - - static { - List anvils = Lists.newArrayList(EntryStack.ofItems(EndBlocks.getModBlocks().stream() - .filter(EndAnvilBlock.class::isInstance).collect(Collectors.toList()))); - anvils.add(0, EntryStack.create(Blocks.ANVIL)); - ANVILS = anvils.toArray(new EntryStack[0]); - FURNACES = Lists.newArrayList(EntryStack.ofItems(EndBlocks.getModBlocks().stream() - .filter(BaseFurnaceBlock.class::isInstance).collect(Collectors.toList()))) - .toArray(new EntryStack[0]); - } -} diff --git a/src/main/java/ru/betterend/interfaces/AnvilScreenHandlerExtended.java b/src/main/java/ru/betterend/interfaces/AnvilScreenHandlerExtended.java deleted file mode 100644 index 9146ab8e..00000000 --- a/src/main/java/ru/betterend/interfaces/AnvilScreenHandlerExtended.java +++ /dev/null @@ -1,33 +0,0 @@ -package ru.betterend.interfaces; - -import java.util.List; - -import ru.betterend.recipe.builders.AnvilRecipe; - -public interface AnvilScreenHandlerExtended { - void be_updateCurrentRecipe(AnvilRecipe recipe); - AnvilRecipe be_getCurrentRecipe(); - List be_getRecipes(); - - default void be_nextRecipe() { - List recipes = be_getRecipes(); - if (recipes.size() < 2) return; - AnvilRecipe current = be_getCurrentRecipe(); - int i = recipes.indexOf(current) + 1; - if (i >= recipes.size()) { - i = 0; - } - be_updateCurrentRecipe(recipes.get(i)); - } - - default void be_previousRecipe() { - List recipes = be_getRecipes(); - if (recipes.size() < 2) return; - AnvilRecipe current = be_getCurrentRecipe(); - int i = recipes.indexOf(current) - 1; - if (i <= 0) { - i = recipes.size() - 1; - } - be_updateCurrentRecipe(recipes.get(i)); - } -} diff --git a/src/main/java/ru/betterend/interfaces/BetterEndRecipe.java b/src/main/java/ru/betterend/interfaces/BetterEndRecipe.java deleted file mode 100644 index 9f939661..00000000 --- a/src/main/java/ru/betterend/interfaces/BetterEndRecipe.java +++ /dev/null @@ -1,3 +0,0 @@ -package ru.betterend.interfaces; - -public interface BetterEndRecipe {} diff --git a/src/main/java/ru/betterend/interfaces/FallFlyingItem.java b/src/main/java/ru/betterend/interfaces/FallFlyingItem.java deleted file mode 100644 index e75888d7..00000000 --- a/src/main/java/ru/betterend/interfaces/FallFlyingItem.java +++ /dev/null @@ -1,8 +0,0 @@ -package ru.betterend.interfaces; - -import net.minecraft.resources.ResourceLocation; - -public interface FallFlyingItem { - ResourceLocation getModelTexture(); - double getMovementFactor(); -} diff --git a/src/main/java/ru/betterend/interfaces/IBiomeArray.java b/src/main/java/ru/betterend/interfaces/IBiomeArray.java deleted file mode 100644 index 9c632b6d..00000000 --- a/src/main/java/ru/betterend/interfaces/IBiomeArray.java +++ /dev/null @@ -1,8 +0,0 @@ -package ru.betterend.interfaces; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.biome.Biome; - -public interface IBiomeArray { - public void be_setBiome(Biome biome, BlockPos pos); -} diff --git a/src/main/java/ru/betterend/interfaces/IBiomeList.java b/src/main/java/ru/betterend/interfaces/IBiomeList.java deleted file mode 100644 index 4dbbfde4..00000000 --- a/src/main/java/ru/betterend/interfaces/IBiomeList.java +++ /dev/null @@ -1,10 +0,0 @@ -package ru.betterend.interfaces; - -import java.util.List; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.level.biome.Biome; - -public interface IBiomeList { - public List> getBiomes(); -} diff --git a/src/main/java/ru/betterend/interfaces/ISlime.java b/src/main/java/ru/betterend/interfaces/ISlime.java deleted file mode 100644 index 7df19bc6..00000000 --- a/src/main/java/ru/betterend/interfaces/ISlime.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.betterend.interfaces; - -public interface ISlime { - public void be_setSlimeSize(int size, boolean heal); -} diff --git a/src/main/java/ru/betterend/interfaces/ISpetialItem.java b/src/main/java/ru/betterend/interfaces/ISpetialItem.java deleted file mode 100644 index ef19bc36..00000000 --- a/src/main/java/ru/betterend/interfaces/ISpetialItem.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.betterend.interfaces; - -public interface ISpetialItem { - public int getStackSize(); - - public boolean canPlaceOnWater(); -} diff --git a/src/main/java/ru/betterend/interfaces/MultiModelItem.java b/src/main/java/ru/betterend/interfaces/MultiModelItem.java deleted file mode 100644 index a486db0a..00000000 --- a/src/main/java/ru/betterend/interfaces/MultiModelItem.java +++ /dev/null @@ -1,19 +0,0 @@ -package ru.betterend.interfaces; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndItems; - -public interface MultiModelItem { - @Environment(EnvType.CLIENT) - void registerModelPredicate(); - - static void register() { - EndItems.getModItems(BetterEnd.MOD_ID).forEach(item -> { - if (item instanceof MultiModelItem) { - ((MultiModelItem) item).registerModelPredicate(); - } - }); - } -} diff --git a/src/main/java/ru/betterend/interfaces/TeleportingEntity.java b/src/main/java/ru/betterend/interfaces/TeleportingEntity.java deleted file mode 100644 index cfd23f30..00000000 --- a/src/main/java/ru/betterend/interfaces/TeleportingEntity.java +++ /dev/null @@ -1,9 +0,0 @@ -package ru.betterend.interfaces; - -import net.minecraft.core.BlockPos; - -public interface TeleportingEntity { - void be_setExitPos(BlockPos pos); - void be_resetExitPos(); - boolean be_canTeleport(); -} diff --git a/src/main/java/ru/betterend/item/ArmoredElytra.java b/src/main/java/ru/betterend/item/ArmoredElytra.java deleted file mode 100644 index b1953792..00000000 --- a/src/main/java/ru/betterend/item/ArmoredElytra.java +++ /dev/null @@ -1,76 +0,0 @@ -package ru.betterend.item; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.client.model.FabricModelPredicateProviderRegistry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.ai.attributes.AttributeModifier; -import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.item.ArmorMaterial; -import net.minecraft.world.item.ElytraItem; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Rarity; -import ru.bclib.items.BaseArmorItem; -import ru.betterend.BetterEnd; -import ru.betterend.interfaces.FallFlyingItem; -import ru.betterend.interfaces.MultiModelItem; -import ru.betterend.registry.EndItems; - -public class ArmoredElytra extends BaseArmorItem implements MultiModelItem, FallFlyingItem { - - private final ResourceLocation wingTexture; - private final Item repairItem; - private final double movementFactor; - private final float toughness; - private final int defense; - - public ArmoredElytra(String name, ArmorMaterial material, Item repairItem, int durability, double movementFactor, boolean fireproof) { - super(material, EquipmentSlot.CHEST, fireproof ? - EndItems.makeEndItemSettings().durability(durability).rarity(Rarity.EPIC).fireResistant() : - EndItems.makeEndItemSettings().durability(durability).rarity(Rarity.EPIC)); - this.wingTexture = BetterEnd.makeID("textures/entity/" + name + ".png"); - this.repairItem = repairItem; - this.movementFactor = movementFactor; - this.defense = (int) ((double) material.getDefenseForSlot(EquipmentSlot.CHEST) / 1.75); - this.toughness = material.getToughness() / 1.75F; - addAttributeModifier(Attributes.ARMOR, new AttributeModifier(ARMOR_MODIFIER_UUID_PER_SLOT[2], - "Armor modifier", defense, AttributeModifier.Operation.ADDITION)); - addAttributeModifier(Attributes.ARMOR_TOUGHNESS, new AttributeModifier(ARMOR_MODIFIER_UUID_PER_SLOT[2], - "Armor toughness", toughness, AttributeModifier.Operation.ADDITION)); - } - - @Override - public double getMovementFactor() { - return movementFactor; - } - - @Override - @Environment(EnvType.CLIENT) - public ResourceLocation getModelTexture() { - return wingTexture; - } - - @Override - public boolean isValidRepairItem(ItemStack itemStack, ItemStack itemStack2) { - return super.isValidRepairItem(itemStack, itemStack2) || itemStack2.getItem() == repairItem; - } - - @Override - public int getDefense() { - return defense; - } - - @Override - public float getToughness() { - return toughness; - } - - @Override - @Environment(EnvType.CLIENT) - public void registerModelPredicate() { - FabricModelPredicateProviderRegistry.register(this, new ResourceLocation("broken"), - (itemStack, clientLevel, livingEntity) -> ElytraItem.isFlyEnabled(itemStack) ? 0.0F : 1.0F); - } -} diff --git a/src/main/java/ru/betterend/item/CrystaliteArmor.java b/src/main/java/ru/betterend/item/CrystaliteArmor.java deleted file mode 100644 index c2e084ff..00000000 --- a/src/main/java/ru/betterend/item/CrystaliteArmor.java +++ /dev/null @@ -1,43 +0,0 @@ -package ru.betterend.item; - -import net.minecraft.ChatFormatting; -import net.minecraft.network.chat.Style; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.ItemStack; -import ru.bclib.items.BaseArmorItem; -import ru.betterend.effects.EndStatusEffects; -import ru.betterend.item.material.EndArmorMaterial; - -public class CrystaliteArmor extends BaseArmorItem { - - public final static TranslatableComponent CHEST_DESC; - public final static TranslatableComponent BOOTS_DESC; - - public CrystaliteArmor(EquipmentSlot equipmentSlot, Properties settings) { - super(EndArmorMaterial.CRYSTALITE, equipmentSlot, settings); - } - - public static boolean hasFullSet(LivingEntity owner) { - for (ItemStack armorStack : owner.getArmorSlots()) { - if (!(armorStack.getItem() instanceof CrystaliteArmor)) { - return false; - } - } - return true; - } - - public static void applySetEffect(LivingEntity owner) { - owner.addEffect(new MobEffectInstance(EndStatusEffects.CRYSTALITE_HEALTH_REGEN)); - } - - static { - Style descStyle = Style.EMPTY.applyFormats(ChatFormatting.DARK_AQUA, ChatFormatting.ITALIC); - CHEST_DESC = new TranslatableComponent("tooltip.armor.crystalite_chest"); - CHEST_DESC.setStyle(descStyle); - BOOTS_DESC = new TranslatableComponent("tooltip.armor.crystalite_boots"); - BOOTS_DESC.setStyle(descStyle); - } -} diff --git a/src/main/java/ru/betterend/item/CrystaliteBoots.java b/src/main/java/ru/betterend/item/CrystaliteBoots.java deleted file mode 100644 index 1b84601e..00000000 --- a/src/main/java/ru/betterend/item/CrystaliteBoots.java +++ /dev/null @@ -1,40 +0,0 @@ -package ru.betterend.item; - -import java.util.List; - -import org.jetbrains.annotations.Nullable; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Rarity; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.level.Level; -import ru.betterend.effects.EndStatusEffects; -import ru.betterend.interfaces.MobEffectApplier; -import ru.betterend.registry.EndItems; - -public class CrystaliteBoots extends CrystaliteArmor implements MobEffectApplier { - - public CrystaliteBoots() { - super(EquipmentSlot.FEET, EndItems.makeEndItemSettings().rarity(Rarity.RARE)); - } - - @Override - public void applyEffect(LivingEntity owner) { - owner.addEffect(new MobEffectInstance(EndStatusEffects.CRYSTALITE_MOVE_SPEED)); - } - - @Override - @Environment(EnvType.CLIENT) - public void appendHoverText(ItemStack stack, @Nullable Level level, List lines, TooltipFlag tooltip) { - super.appendHoverText(stack, level, lines, tooltip); - lines.add(1, TextComponent.EMPTY); - lines.add(2, BOOTS_DESC); - } -} diff --git a/src/main/java/ru/betterend/item/CrystaliteChestplate.java b/src/main/java/ru/betterend/item/CrystaliteChestplate.java deleted file mode 100644 index 920b3706..00000000 --- a/src/main/java/ru/betterend/item/CrystaliteChestplate.java +++ /dev/null @@ -1,40 +0,0 @@ -package ru.betterend.item; - -import java.util.List; - -import org.jetbrains.annotations.Nullable; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Rarity; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.level.Level; -import ru.betterend.effects.EndStatusEffects; -import ru.betterend.interfaces.MobEffectApplier; -import ru.betterend.registry.EndItems; - -public class CrystaliteChestplate extends CrystaliteArmor implements MobEffectApplier { - - public CrystaliteChestplate() { - super(EquipmentSlot.CHEST, EndItems.makeEndItemSettings().rarity(Rarity.RARE)); - } - - @Override - public void applyEffect(LivingEntity owner) { - owner.addEffect(new MobEffectInstance(EndStatusEffects.CRYSTALITE_DIG_SPEED)); - } - - @Override - @Environment(EnvType.CLIENT) - public void appendHoverText(ItemStack stack, @Nullable Level level, List lines, TooltipFlag tooltip) { - super.appendHoverText(stack, level, lines, tooltip); - lines.add(1, TextComponent.EMPTY); - lines.add(2, CHEST_DESC); - } -} diff --git a/src/main/java/ru/betterend/item/CrystaliteElytra.java b/src/main/java/ru/betterend/item/CrystaliteElytra.java deleted file mode 100644 index 489eaf3f..00000000 --- a/src/main/java/ru/betterend/item/CrystaliteElytra.java +++ /dev/null @@ -1,68 +0,0 @@ -package ru.betterend.item; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.object.builder.v1.client.model.FabricModelPredicateProviderRegistry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.ai.attributes.AttributeModifier; -import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.item.ElytraItem; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Rarity; -import ru.betterend.BetterEnd; -import ru.betterend.interfaces.FallFlyingItem; -import ru.betterend.interfaces.MultiModelItem; -import ru.betterend.registry.EndItems; - -public class CrystaliteElytra extends CrystaliteArmor implements MultiModelItem, FallFlyingItem { - - private final ResourceLocation wingTexture; - private final double movementFactor; - private final int defense; - private final float toughness; - - public CrystaliteElytra(int durability, double movementFactor) { - super(EquipmentSlot.CHEST, EndItems.makeEndItemSettings().durability(durability).rarity(Rarity.EPIC)); - this.wingTexture = BetterEnd.makeID("textures/entity/elytra_crystalite.png"); - this.movementFactor = movementFactor; - this.defense = (int) ((double) material.getDefenseForSlot(EquipmentSlot.CHEST) / 1.75); - this.toughness = material.getToughness() / 1.75F; - addAttributeModifier(Attributes.ARMOR, new AttributeModifier(ARMOR_MODIFIER_UUID_PER_SLOT[2], - "Armor modifier", defense, AttributeModifier.Operation.ADDITION)); - addAttributeModifier(Attributes.ARMOR_TOUGHNESS, new AttributeModifier(ARMOR_MODIFIER_UUID_PER_SLOT[2], - "Armor toughness", toughness, AttributeModifier.Operation.ADDITION)); - } - - @Override - public boolean isValidRepairItem(ItemStack itemStack, ItemStack itemStack2) { - return super.isValidRepairItem(itemStack, itemStack2) || itemStack2.getItem() == EndItems.ENCHANTED_MEMBRANE; - } - - @Override - public double getMovementFactor() { - return movementFactor; - } - - @Override - @Environment(EnvType.CLIENT) - public ResourceLocation getModelTexture() { - return wingTexture; - } - - @Override - public int getDefense() { - return defense; - } - - @Override - public float getToughness() { - return toughness; - } - - @Override - public void registerModelPredicate() { - FabricModelPredicateProviderRegistry.register(this, new ResourceLocation("broken"), - (itemStack, clientLevel, livingEntity) -> ElytraItem.isFlyEnabled(itemStack) ? 0.0F : 1.0F); - } -} diff --git a/src/main/java/ru/betterend/item/CrystaliteHelmet.java b/src/main/java/ru/betterend/item/CrystaliteHelmet.java deleted file mode 100644 index ec297001..00000000 --- a/src/main/java/ru/betterend/item/CrystaliteHelmet.java +++ /dev/null @@ -1,18 +0,0 @@ -package ru.betterend.item; - -import java.util.UUID; - -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.ai.attributes.AttributeModifier; -import net.minecraft.world.item.Rarity; -import ru.betterend.registry.EndAttributes; -import ru.betterend.registry.EndItems; - -public class CrystaliteHelmet extends CrystaliteArmor { - - public CrystaliteHelmet() { - super(EquipmentSlot.HEAD, EndItems.makeEndItemSettings().rarity(Rarity.RARE)); - UUID uuid = ARMOR_MODIFIER_UUID_PER_SLOT[EquipmentSlot.HEAD.getIndex()]; - addAttributeModifier(EndAttributes.BLINDNESS_RESISTANCE, new AttributeModifier(uuid, "Helmet blindness resistance", 1.0, AttributeModifier.Operation.ADDITION)); - } -} diff --git a/src/main/java/ru/betterend/item/CrystaliteLeggings.java b/src/main/java/ru/betterend/item/CrystaliteLeggings.java deleted file mode 100644 index 4c8d0613..00000000 --- a/src/main/java/ru/betterend/item/CrystaliteLeggings.java +++ /dev/null @@ -1,18 +0,0 @@ -package ru.betterend.item; - -import java.util.UUID; - -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.ai.attributes.AttributeModifier; -import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.item.Rarity; -import ru.betterend.registry.EndItems; - -public class CrystaliteLeggings extends CrystaliteArmor { - - public CrystaliteLeggings() { - super(EquipmentSlot.LEGS, EndItems.makeEndItemSettings().rarity(Rarity.RARE)); - UUID uuid = ARMOR_MODIFIER_UUID_PER_SLOT[EquipmentSlot.LEGS.getIndex()]; - addAttributeModifier(Attributes.MAX_HEALTH, new AttributeModifier(uuid, "Armor health boost", 4.0, AttributeModifier.Operation.ADDITION)); - } -} diff --git a/src/main/java/ru/betterend/item/EnchantedItem.java b/src/main/java/ru/betterend/item/EnchantedItem.java deleted file mode 100644 index d210c855..00000000 --- a/src/main/java/ru/betterend/item/EnchantedItem.java +++ /dev/null @@ -1,32 +0,0 @@ -package ru.betterend.item; - -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Rarity; -import ru.bclib.client.models.ModelsHelper; -import ru.bclib.items.ModelProviderItem; -import ru.betterend.registry.EndItems; - -public class EnchantedItem extends ModelProviderItem { - - private final Item source; - - public EnchantedItem(Item source) { - super(EndItems.makeEndItemSettings().rarity(Rarity.RARE).stacksTo(16)); - this.source = source; - } - - @Override - public boolean isFoil(ItemStack stack) { - return true; - } - - @Override - public BlockModel getItemModel(ResourceLocation resourceLocation) { - ResourceLocation sourceId = Registry.ITEM.getKey(source); - return ModelsHelper.createItemModel(sourceId); - } -} diff --git a/src/main/java/ru/betterend/item/EndAnvilItem.java b/src/main/java/ru/betterend/item/EndAnvilItem.java deleted file mode 100644 index 9b8b4d04..00000000 --- a/src/main/java/ru/betterend/item/EndAnvilItem.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.betterend.item; - -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.client.models.ItemModelProvider; -import ru.bclib.items.BaseAnvilItem; -import ru.betterend.blocks.basis.EndAnvilBlock; -import ru.betterend.registry.EndBlocks; - -public class EndAnvilItem extends BaseAnvilItem { - - public final static String DURABILITY = "durability"; - - public EndAnvilItem(Block anvilBlock) { - super(anvilBlock, EndBlocks.makeBlockItemSettings()); - } - - @Override - protected BlockState getPlacementState(BlockPlaceContext blockPlaceContext) { - BlockState blockState = super.getPlacementState(blockPlaceContext); - ItemStack stack = blockPlaceContext.getItemInHand(); - int durability = stack.getOrCreateTag().getInt(DURABILITY); - blockState = blockState.setValue(((EndAnvilBlock) blockState.getBlock()).getDurability(), durability); - return blockState; - } - - @Override - public BlockModel getItemModel(ResourceLocation resourceLocation) { - Block block = getBlock(); - ResourceLocation blockId = Registry.BLOCK.getKey(block); - return ((ItemModelProvider) block).getItemModel(blockId); - } -} diff --git a/src/main/java/ru/betterend/item/EndArmorItem.java b/src/main/java/ru/betterend/item/EndArmorItem.java deleted file mode 100644 index 1f4bf969..00000000 --- a/src/main/java/ru/betterend/item/EndArmorItem.java +++ /dev/null @@ -1,49 +0,0 @@ -package ru.betterend.item; - -import java.util.UUID; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; - -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.ai.attributes.Attribute; -import net.minecraft.world.entity.ai.attributes.AttributeModifier; -import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.item.ArmorItem; -import net.minecraft.world.item.ArmorMaterial; -import ru.bclib.client.models.ItemModelProvider; - -public class EndArmorItem extends ArmorItem implements ItemModelProvider { - - protected static final UUID[] ARMOR_MODIFIER_UUID_PER_SLOT = new UUID[] { - UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"), - UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D"), - UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E"), - UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150") - }; - - protected final Multimap defaultModifiers; - - public EndArmorItem(ArmorMaterial material, EquipmentSlot equipmentSlot, Properties settings) { - super(material, equipmentSlot, settings); - this.defaultModifiers = HashMultimap.create(); - UUID uuid = ARMOR_MODIFIER_UUID_PER_SLOT[equipmentSlot.getIndex()]; - addAttributeModifier(Attributes.ARMOR, new AttributeModifier(uuid, "Armor modifier", getDefense(), AttributeModifier.Operation.ADDITION)); - addAttributeModifier(Attributes.ARMOR_TOUGHNESS, new AttributeModifier(uuid, "Armor toughness", getToughness(), AttributeModifier.Operation.ADDITION)); - if (knockbackResistance > 0.0F) { - addAttributeModifier(Attributes.KNOCKBACK_RESISTANCE, new AttributeModifier(uuid, "Armor knockback resistance", knockbackResistance, AttributeModifier.Operation.ADDITION)); - } - } - - @Override - public Multimap getDefaultAttributeModifiers(EquipmentSlot equipmentSlot) { - return equipmentSlot == slot ? defaultModifiers : super.getDefaultAttributeModifiers(equipmentSlot); - } - - protected void addAttributeModifier(Attribute attribute, AttributeModifier modifier) { - if (defaultModifiers.containsKey(attribute)) { - defaultModifiers.removeAll(attribute); - } - defaultModifiers.put(attribute, modifier); - } -} diff --git a/src/main/java/ru/betterend/item/EndAttribute.java b/src/main/java/ru/betterend/item/EndAttribute.java deleted file mode 100644 index 7ddc0bb8..00000000 --- a/src/main/java/ru/betterend/item/EndAttribute.java +++ /dev/null @@ -1,10 +0,0 @@ -package ru.betterend.item; - -import net.minecraft.world.entity.ai.attributes.Attribute; - -public class EndAttribute extends Attribute { - - public EndAttribute(String description, double value) { - super(description, value); - } -} diff --git a/src/main/java/ru/betterend/item/EndBucketItem.java b/src/main/java/ru/betterend/item/EndBucketItem.java deleted file mode 100644 index 7d7a729a..00000000 --- a/src/main/java/ru/betterend/item/EndBucketItem.java +++ /dev/null @@ -1,13 +0,0 @@ -package ru.betterend.item; - -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.item.FishBucketItem; -import net.minecraft.world.level.material.Fluids; -import ru.bclib.client.models.ItemModelProvider; -import ru.betterend.registry.EndItems; - -public class EndBucketItem extends FishBucketItem implements ItemModelProvider { - public EndBucketItem(EntityType type) { - super(type, Fluids.WATER, EndItems.makeEndItemSettings().stacksTo(1)); - } -} diff --git a/src/main/java/ru/betterend/item/EternalCrystalItem.java b/src/main/java/ru/betterend/item/EternalCrystalItem.java deleted file mode 100644 index 9034283d..00000000 --- a/src/main/java/ru/betterend/item/EternalCrystalItem.java +++ /dev/null @@ -1,11 +0,0 @@ -package ru.betterend.item; - -import net.minecraft.world.item.Rarity; -import ru.bclib.items.ModelProviderItem; -import ru.betterend.registry.EndItems; - -public class EternalCrystalItem extends ModelProviderItem { - public EternalCrystalItem() { - super(EndItems.makeEndItemSettings().stacksTo(16).rarity(Rarity.EPIC)); - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/item/material/EndArmorMaterial.java b/src/main/java/ru/betterend/item/material/EndArmorMaterial.java deleted file mode 100644 index 13358a76..00000000 --- a/src/main/java/ru/betterend/item/material/EndArmorMaterial.java +++ /dev/null @@ -1,95 +0,0 @@ -package ru.betterend.item.material; - -import java.util.function.Supplier; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.util.LazyLoadedValue; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.item.ArmorMaterial; -import net.minecraft.world.item.crafting.Ingredient; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public enum EndArmorMaterial implements ArmorMaterial { - THALLASIUM("thallasium", 17, new int[] { 1, 4, 5, 2 }, 12, SoundEvents.ARMOR_EQUIP_IRON, 0.0F, 0.0F, () -> { - return Ingredient.of(EndBlocks.THALLASIUM.ingot); - }), - TERMINITE("terminite", 26, new int[] { 3, 6, 7, 3 }, 14, SoundEvents.ARMOR_EQUIP_IRON, 1.0F, 0.05F, () -> { - return Ingredient.of(EndBlocks.TERMINITE.ingot); - }), - AETERNIUM("aeternium", 40, new int[] { 4, 7, 9, 4 }, 18, SoundEvents.ARMOR_EQUIP_NETHERITE, 3.5F, 0.2F, () -> { - return Ingredient.of(EndItems.AETERNIUM_INGOT); - }), - CRYSTALITE("crystalite", 30, new int[] { 3, 6, 8, 3 }, 24, SoundEvents.ARMOR_EQUIP_DIAMOND, 1.2F, 0.1F, () -> { - return Ingredient.of(EndBlocks.TERMINITE.ingot); - }); - - private static final int[] BASE_DURABILITY = new int[] { 13, 15, 16, 11 }; - private final String name; - private final int durabilityMultiplier; - private final int[] protectionAmounts; - private final int enchantability; - private final SoundEvent equipSound; - private final float toughness; - private final float knockbackResistance; - private final LazyLoadedValue repairIngredient; - - private EndArmorMaterial(String name, int durabilityMultiplier, int[] protectionAmounts, int enchantability, - SoundEvent equipSound, float toughness, float knockbackResistance, - Supplier repairIngredient) { - - this.name = name; - this.durabilityMultiplier = durabilityMultiplier; - this.protectionAmounts = protectionAmounts; - this.enchantability = enchantability; - this.equipSound = equipSound; - this.toughness = toughness; - this.knockbackResistance = knockbackResistance; - this.repairIngredient = new LazyLoadedValue<>(repairIngredient); - } - - @Override - public int getDurabilityForSlot(EquipmentSlot slot) { - return BASE_DURABILITY[slot.getIndex()] * this.durabilityMultiplier; - } - - @Override - public int getDefenseForSlot(EquipmentSlot slot) { - return this.protectionAmounts[slot.getIndex()]; - } - - @Override - public int getEnchantmentValue() { - return this.enchantability; - } - - @Override - public SoundEvent getEquipSound() { - return this.equipSound; - } - - @Override - public Ingredient getRepairIngredient() { - return this.repairIngredient.get(); - } - - @Override - @Environment(EnvType.CLIENT) - public String getName() { - return this.name; - } - - @Override - public float getToughness() { - return this.toughness; - } - - @Override - public float getKnockbackResistance() { - return this.knockbackResistance; - } - -} diff --git a/src/main/java/ru/betterend/item/material/EndToolMaterial.java b/src/main/java/ru/betterend/item/material/EndToolMaterial.java deleted file mode 100644 index 9c0197ae..00000000 --- a/src/main/java/ru/betterend/item/material/EndToolMaterial.java +++ /dev/null @@ -1,70 +0,0 @@ -package ru.betterend.item.material; - -import java.util.function.Supplier; - -import net.minecraft.util.LazyLoadedValue; -import net.minecraft.world.item.Tier; -import net.minecraft.world.item.crafting.Ingredient; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public enum EndToolMaterial implements Tier { - THALLASIUM(2, 320, 7.0F, 1.5F, 12, () -> { - return Ingredient.of(EndBlocks.THALLASIUM.ingot); - }), - TERMINITE(3, 1230, 8.5F, 3.0F, 14, () -> { - return Ingredient.of(EndBlocks.TERMINITE.ingot); - }), - AETERNIUM(5, 2196, 10.0F, 4.5F, 18, () -> { - return Ingredient.of(EndItems.AETERNIUM_INGOT); - }); - - private final int durability; - private final float miningSpeed; - private final float attackDamage; - private final int miningLevel; - private final int enchantability; - private final LazyLoadedValue repairIngredient; - - private EndToolMaterial(int miningLevel, int durability, float miningSpeed, float attackDamage, int enchantability, - Supplier repairIngredient) { - - this.durability = durability; - this.miningSpeed = miningSpeed; - this.attackDamage = attackDamage; - this.miningLevel = miningLevel; - this.enchantability = enchantability; - this.repairIngredient = new LazyLoadedValue<>(repairIngredient); - } - - @Override - public int getUses() { - return this.durability; - } - - @Override - public float getSpeed() { - return this.miningSpeed; - } - - @Override - public float getAttackDamageBonus() { - return this.attackDamage; - } - - @Override - public int getLevel() { - return this.miningLevel; - } - - @Override - public int getEnchantmentValue() { - return this.enchantability; - } - - @Override - public Ingredient getRepairIngredient() { - return this.repairIngredient.get(); - } - -} diff --git a/src/main/java/ru/betterend/item/model/ArmoredElytraModel.java b/src/main/java/ru/betterend/item/model/ArmoredElytraModel.java deleted file mode 100644 index d5b5c1a0..00000000 --- a/src/main/java/ru/betterend/item/model/ArmoredElytraModel.java +++ /dev/null @@ -1,74 +0,0 @@ -package ru.betterend.item.model; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.client.model.AgeableListModel; -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.phys.Vec3; - -public class ArmoredElytraModel extends AgeableListModel { - private final ModelPart rightWing; - private final ModelPart leftWing; - - public ArmoredElytraModel() { - this.leftWing = new ModelPart(this, 22, 0); - this.leftWing.addBox(-10.0F, 0.0F, 0.0F, 10.0F, 20.0F, 2.0F, 1.0F); - this.rightWing = new ModelPart(this, 22, 0); - this.rightWing.mirror = true; - this.rightWing.addBox(0.0F, 0.0F, 0.0F, 10.0F, 20.0F, 2.0F, 1.0F); - } - - protected Iterable headParts() { - return ImmutableList.of(); - } - - protected Iterable bodyParts() { - return ImmutableList.of(leftWing, rightWing); - } - - public void setupAnim(T livingEntity, float f, float g, float h, float i, float j) { - float rotX = 0.2617994F; - float rotZ = -0.2617994F; - float rotY = 0.0F; - float wingY = 0.0F; - if (livingEntity.isFallFlying()) { - float coef = 1.0F; - Vec3 vec3 = livingEntity.getDeltaMovement(); - if (vec3.y < 0.0D) { - Vec3 normalized = vec3.normalize(); - coef = 1.0F - (float) Math.pow(-normalized.y, 2.5D); - } - rotX = coef * 0.34906584F + (1.0F - coef) * rotX; - rotZ = coef * -1.5707964F + (1.0F - coef) * rotZ; - } else if (livingEntity.isCrouching()) { - rotX = 0.6981317F; - rotZ = -0.7853982F; - rotY = 0.08726646F; - wingY = 3.0F; - } - - leftWing.x = 5.0F; - leftWing.y = wingY; - if (livingEntity instanceof AbstractClientPlayer) { - AbstractClientPlayer abstractClientPlayer = (AbstractClientPlayer) livingEntity; - abstractClientPlayer.elytraRotX = (float) ((double) abstractClientPlayer.elytraRotX + (double) (rotX - abstractClientPlayer.elytraRotX) * 0.1D); - abstractClientPlayer.elytraRotY = (float) ((double) abstractClientPlayer.elytraRotY + (double) (rotY - abstractClientPlayer.elytraRotY) * 0.1D); - abstractClientPlayer.elytraRotZ = (float) ((double) abstractClientPlayer.elytraRotZ + (double) (rotZ - abstractClientPlayer.elytraRotZ) * 0.1D); - leftWing.xRot = abstractClientPlayer.elytraRotX; - leftWing.yRot = abstractClientPlayer.elytraRotY; - leftWing.zRot = abstractClientPlayer.elytraRotZ; - } else { - leftWing.xRot = rotX; - leftWing.zRot = rotZ; - leftWing.yRot = rotY; - } - - rightWing.x = -leftWing.x; - rightWing.yRot = -leftWing.yRot; - rightWing.y = leftWing.y; - rightWing.xRot = leftWing.xRot; - rightWing.zRot = -leftWing.zRot; - } -} diff --git a/src/main/java/ru/betterend/item/model/CrystaliteArmorProvider.java b/src/main/java/ru/betterend/item/model/CrystaliteArmorProvider.java deleted file mode 100644 index b631ad7e..00000000 --- a/src/main/java/ru/betterend/item/model/CrystaliteArmorProvider.java +++ /dev/null @@ -1,82 +0,0 @@ -package ru.betterend.item.model; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import com.google.common.collect.Lists; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.client.rendering.v1.ArmorRenderingRegistry.ModelProvider; -import net.fabricmc.fabric.api.client.rendering.v1.ArmorRenderingRegistry.TextureProvider; -import net.minecraft.client.model.HumanoidModel; -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import ru.betterend.item.CrystaliteArmor; -import ru.betterend.registry.EndItems; - -@Environment(EnvType.CLIENT) -public class CrystaliteArmorProvider implements ModelProvider, TextureProvider { - private final static ResourceLocation FIRST_LAYER = new ResourceLocation("textures/models/armor/crystalite_layer_1.png"); - private final static ResourceLocation SECOND_LAYER = new ResourceLocation("textures/models/armor/crystalite_layer_2.png"); - private final static CrystaliteHelmetModel HELMET_MODEL = new CrystaliteHelmetModel(1.0F); - private final static CrystaliteChestplateModel CHEST_MODEL = new CrystaliteChestplateModel(1.0F, false); - private final static CrystaliteChestplateModel CHEST_MODEL_SLIM = new CrystaliteChestplateModel(1.0F, true); - private final static CrystaliteLeggingsModel LEGGINGS_MODEL = new CrystaliteLeggingsModel(1.0F); - private final static CrystaliteBootsModel BOOTS_MODEL = new CrystaliteBootsModel(1.0F); - - @Override - public @NotNull ResourceLocation getArmorTexture(LivingEntity entity, ItemStack stack, EquipmentSlot slot, - boolean secondLayer, @Nullable String suffix, ResourceLocation defaultTexture) { - if (!isStackValid(stack)) return defaultTexture; - if (secondLayer) return SECOND_LAYER; - return FIRST_LAYER; - } - - @Override - public @NotNull HumanoidModel getArmorModel(LivingEntity entity, ItemStack stack, - EquipmentSlot slot, HumanoidModel defaultModel) { - if (!isStackValid(stack)) return defaultModel; - switch(slot) { - case HEAD: { - return HELMET_MODEL; - } - case CHEST: { - if (entity instanceof AbstractClientPlayer && - ((AbstractClientPlayer) entity).getModelName().equals("slim")) { - CHEST_MODEL_SLIM.copyPropertiesTo(defaultModel); - return CHEST_MODEL_SLIM; - } - CHEST_MODEL.copyPropertiesTo(defaultModel); - return CHEST_MODEL; - } - case LEGS: { - return LEGGINGS_MODEL; - } - case FEET: { - BOOTS_MODEL.copyPropertiesTo(defaultModel); - return BOOTS_MODEL; - } - default: { - return defaultModel; - } - } - } - - public Iterable getRenderedItems() { - return Lists.newArrayList( - EndItems.CRYSTALITE_HELMET, - EndItems.CRYSTALITE_CHESTPLATE, - EndItems.CRYSTALITE_ELYTRA, - EndItems.CRYSTALITE_LEGGINGS, - EndItems.CRYSTALITE_BOOTS); - } - - private boolean isStackValid(ItemStack stack) { - return stack.getItem() instanceof CrystaliteArmor; - } -} diff --git a/src/main/java/ru/betterend/item/model/CrystaliteBootsModel.java b/src/main/java/ru/betterend/item/model/CrystaliteBootsModel.java deleted file mode 100644 index d1a37fde..00000000 --- a/src/main/java/ru/betterend/item/model/CrystaliteBootsModel.java +++ /dev/null @@ -1,43 +0,0 @@ -package ru.betterend.item.model; - -import java.util.Collections; - -import com.google.common.collect.Lists; - -import net.minecraft.client.model.HumanoidModel; -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.world.entity.LivingEntity; - -public class CrystaliteBootsModel extends HumanoidModel { - - public ModelPart leftBoot; - public ModelPart rightBoot; - - public CrystaliteBootsModel(float scale) { - super(RenderType::entityTranslucent, scale, 0.0F, 64, 48); - this.leftBoot = new ModelPart(this, 0, 32); - this.leftBoot.addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, scale + 0.25F); - this.leftBoot.setPos(1.9F, 12.0F, 0.0F); - this.rightBoot = new ModelPart(this, 0, 16); - this.rightBoot.addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, scale + 0.25F); - this.rightBoot.setPos(-1.9F, 12.0F, 0.0F); - } - - @Override - public void copyPropertiesTo(HumanoidModel bipedEntityModel) { - super.copyPropertiesTo(bipedEntityModel); - this.leftBoot.copyFrom(leftLeg); - this.rightBoot.copyFrom(rightLeg); - } - - @Override - protected Iterable headParts() { - return Collections::emptyIterator; - } - - @Override - protected Iterable bodyParts() { - return Lists.newArrayList(leftBoot, rightBoot); - } -} diff --git a/src/main/java/ru/betterend/item/model/CrystaliteChestplateModel.java b/src/main/java/ru/betterend/item/model/CrystaliteChestplateModel.java deleted file mode 100644 index 1942f9d6..00000000 --- a/src/main/java/ru/betterend/item/model/CrystaliteChestplateModel.java +++ /dev/null @@ -1,74 +0,0 @@ -package ru.betterend.item.model; - -import java.util.Collections; - -import com.google.common.collect.Lists; -import com.mojang.blaze3d.vertex.PoseStack; - -import net.minecraft.client.model.HumanoidModel; -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.world.entity.HumanoidArm; -import net.minecraft.world.entity.LivingEntity; - -public class CrystaliteChestplateModel extends HumanoidModel { - - public ModelPart leftShoulder; - public ModelPart rightShoulder; - private final boolean thinArms; - - public CrystaliteChestplateModel(float scale, boolean thinArms) { - super(RenderType::entityTranslucent, scale, 0.0F, 64, 48); - this.thinArms = thinArms; - this.body = new ModelPart(this, 16, 16); - this.body.addBox(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, scale + 0.25F); - this.body.setPos(0.0F, 0.0F, 0.0F); - if (thinArms) { - this.leftShoulder = new ModelPart(this, 41, 32); - this.leftShoulder.addBox(-1.0F, -2.5F, -2.0F, 3.0F, 12.0F, 4.0F, scale + 0.35F); - this.leftShoulder.setPos(5.0F, 2.5F, 0.0F); - this.leftShoulder.mirror = true; - this.rightShoulder = new ModelPart(this, 41, 16); - this.rightShoulder.addBox(-2.0F, -2.5F, -2.0F, 3.0F, 12.0F, 4.0F, scale + 0.35F); - this.rightShoulder.setPos(-5.0F, 2.5F, 10.0F); - } else { - this.leftShoulder = new ModelPart(this, 40, 32); - this.leftShoulder.addBox(-1.0F, -2.5F, -2.0F, 4.0F, 12.0F, 4.0F, scale + 0.45F); - this.leftShoulder.setPos(5.0F, 2.0F, 0.0F); - this.leftShoulder.mirror = true; - this.rightShoulder = new ModelPart(this, 40, 16); - this.rightShoulder.addBox(-3.0F, -2.5F, -2.0F, 4.0F, 12.0F, 4.0F, scale + 0.45F); - this.rightShoulder.setPos(-5.0F, 2.0F, 10.0F); - } - } - - @Override - public void copyPropertiesTo(HumanoidModel bipedEntityModel) { - super.copyPropertiesTo(bipedEntityModel); - this.leftShoulder.copyFrom(leftArm); - this.rightShoulder.copyFrom(rightArm); - } - - @Override - protected Iterable headParts() { - return Collections::emptyIterator; - } - - @Override - protected Iterable bodyParts() { - return Lists.newArrayList(body, leftShoulder, rightShoulder); - } - - @Override - public void translateToHand(HumanoidArm arm, PoseStack matrices) { - ModelPart modelPart = this.getArm(arm); - if (this.thinArms) { - float f = 0.5F * (float)(arm == HumanoidArm.RIGHT ? 1 : -1); - modelPart.x += f; - modelPart.translateAndRotate(matrices); - modelPart.x -= f; - } else { - modelPart.translateAndRotate(matrices); - } - } -} diff --git a/src/main/java/ru/betterend/item/model/CrystaliteHelmetModel.java b/src/main/java/ru/betterend/item/model/CrystaliteHelmetModel.java deleted file mode 100644 index 3513c2f4..00000000 --- a/src/main/java/ru/betterend/item/model/CrystaliteHelmetModel.java +++ /dev/null @@ -1,33 +0,0 @@ -package ru.betterend.item.model; - -import java.util.Collections; - -import com.google.common.collect.Lists; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.model.HumanoidModel; -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.world.entity.LivingEntity; - -@Environment(EnvType.CLIENT) -public class CrystaliteHelmetModel extends HumanoidModel { - - public CrystaliteHelmetModel(float scale) { - super(RenderType::entityTranslucent, scale, 0.0F, 64, 48); - this.hat = new ModelPart(this, 0, 0); - this.hat.addBox(-4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F, scale + 0.5F); - this.hat.setPos(0.0F, 0.0F, 0.0F); - } - - @Override - protected Iterable headParts() { - return Collections::emptyIterator; - } - - @Override - protected Iterable bodyParts() { - return Lists.newArrayList(hat); - } -} diff --git a/src/main/java/ru/betterend/item/model/CrystaliteLeggingsModel.java b/src/main/java/ru/betterend/item/model/CrystaliteLeggingsModel.java deleted file mode 100644 index 54772ebd..00000000 --- a/src/main/java/ru/betterend/item/model/CrystaliteLeggingsModel.java +++ /dev/null @@ -1,36 +0,0 @@ -package ru.betterend.item.model; - -import java.util.Collections; - -import com.google.common.collect.Lists; - -import net.minecraft.client.model.HumanoidModel; -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.world.entity.LivingEntity; - -public class CrystaliteLeggingsModel extends HumanoidModel { - - public CrystaliteLeggingsModel(float scale) { - super(RenderType::entityTranslucent, scale, 0.0F, 64, 48); - this.body = new ModelPart(this, 16, 16); - this.body.addBox(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, scale); - this.body.setPos(0.0F, 0.0F, 0.0F); - this.leftLeg = new ModelPart(this, 0, 32); - this.leftLeg.addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, scale); - this.leftLeg.setPos(1.9F, 12.0F, 0.0F); - this.rightLeg = new ModelPart(this, 0, 16); - this.rightLeg.addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, scale); - this.rightLeg.setPos(-1.9F, 12.0F, 0.0F); - } - - @Override - protected Iterable headParts() { - return Collections::emptyIterator; - } - - @Override - protected Iterable bodyParts() { - return Lists.newArrayList(body, rightLeg, leftLeg); - } -} diff --git a/src/main/java/ru/betterend/item/tool/EndHammerItem.java b/src/main/java/ru/betterend/item/tool/EndHammerItem.java deleted file mode 100644 index fa990cf9..00000000 --- a/src/main/java/ru/betterend/item/tool/EndHammerItem.java +++ /dev/null @@ -1,139 +0,0 @@ -package ru.betterend.item.tool; - -import java.util.UUID; - -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableMultimap.Builder; -import com.google.common.collect.Multimap; -import com.google.common.collect.Sets; - -import io.netty.util.internal.ThreadLocalRandom; -import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.Tag; -import net.minecraft.util.Mth; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.ai.attributes.Attribute; -import net.minecraft.world.entity.ai.attributes.AttributeModifier; -import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.DiggerItem; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Tier; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import ru.bclib.client.models.ItemModelProvider; -import ru.bclib.client.models.ModelsHelper; -import ru.betterend.registry.EndTags; - -public class EndHammerItem extends DiggerItem implements DynamicAttributeTool, ItemModelProvider { - public final static UUID ATTACK_KNOCKBACK_MODIFIER_ID = Mth.createInsecureUUID(ThreadLocalRandom.current()); - - private final Multimap attributeModifiers; - - public EndHammerItem(Tier material, float attackDamage, float attackSpeed, double knockback, Properties settings) { - super(attackDamage, attackSpeed, material, Sets.newHashSet(), settings); - - Builder builder = ImmutableMultimap.builder(); - builder.put(Attributes.ATTACK_DAMAGE, new AttributeModifier(BASE_ATTACK_DAMAGE_UUID, "Weapon modifier", attackDamage + material.getAttackDamageBonus(), AttributeModifier.Operation.ADDITION)); - builder.put(Attributes.ATTACK_SPEED, new AttributeModifier(BASE_ATTACK_SPEED_UUID, "Weapon modifier", attackSpeed, AttributeModifier.Operation.ADDITION)); - builder.put(Attributes.ATTACK_KNOCKBACK, new AttributeModifier(ATTACK_KNOCKBACK_MODIFIER_ID, "Weapon modifier", knockback, AttributeModifier.Operation.ADDITION)); - this.attributeModifiers = builder.build(); - } - - @Override - public boolean canAttackBlock(BlockState state, Level world, BlockPos pos, Player miner) { - return state.getMaterial().equals(Material.STONE) || - state.getMaterial().equals(Material.GLASS) || - state.is(Blocks.DIAMOND_BLOCK) || - state.is(Blocks.EMERALD_BLOCK) || - state.is(Blocks.LAPIS_BLOCK) || - state.is(Blocks.REDSTONE_BLOCK); - } - - @Override - public boolean hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) { - stack.hurtAndBreak(1, attacker, ((entity) -> entity.broadcastBreakEvent(EquipmentSlot.MAINHAND))); - - return true; - } - - @Override - public boolean mineBlock(ItemStack stack, Level world, BlockState state, BlockPos pos, LivingEntity miner) { - if (state.getDestroySpeed(world, pos) != 0.0F) { - stack.hurtAndBreak(1, miner, ((entity) -> entity.broadcastBreakEvent(EquipmentSlot.MAINHAND))); - } - - return true; - } - - @Override - public float getDestroySpeed(ItemStack stack, BlockState state) { - if (state.getMaterial().equals(Material.GLASS)) { - return this.getTier().getSpeed() * 2.0F; - } - if (isCorrectToolForDrops(state)) { - float mult; - if (state.is(Blocks.DIAMOND_BLOCK) || state.is(Blocks.EMERALD_BLOCK) || state.is(Blocks.LAPIS_BLOCK) || state.is(Blocks.REDSTONE_BLOCK)) { - mult = this.getTier().getSpeed(); - } else { - mult = this.getTier().getSpeed() / 2.0F; - } - return Math.max(mult, 1.0F); - } - return 1.0F; - } - - @Override - public float getMiningSpeedMultiplier(Tag tag, BlockState state, ItemStack stack, LivingEntity user) { - if (tag.equals(EndTags.HAMMERS)) { - return this.getDestroySpeed(stack, state); - } - return 1.0F; - } - - @Override - public int getMiningLevel(Tag tag, BlockState state, ItemStack stack, LivingEntity user) { - if (tag.equals(EndTags.HAMMERS)) { - return this.getTier().getLevel(); - } - return 0; - } - - @Override - public boolean isCorrectToolForDrops(BlockState state) { - if (state.getMaterial().equals(Material.GLASS)) { - return true; - } - if (!state.is(Blocks.REDSTONE_BLOCK) && !state.is(Blocks.DIAMOND_BLOCK) && !state.is(Blocks.EMERALD_BLOCK) && !state.is(Blocks.LAPIS_BLOCK) && !state.getMaterial().equals(Material.STONE)) { - return false; - } - int level = this.getTier().getLevel(); - if (state.is(Blocks.IRON_ORE) || state.is(Blocks.LAPIS_BLOCK) || state.is(Blocks.LAPIS_ORE)) { - return level >= 1; - } - if (state.is(Blocks.DIAMOND_BLOCK) && !state.is(Blocks.DIAMOND_ORE) || state.is(Blocks.EMERALD_ORE) || state.is(Blocks.EMERALD_BLOCK) || state.is(Blocks.GOLD_ORE) || state.is(Blocks.REDSTONE_ORE)) { - return level >= 2; - } - if (state.is(Blocks.OBSIDIAN) || state.is(Blocks.CRYING_OBSIDIAN) || state.is(Blocks.RESPAWN_ANCHOR) || state.is(Blocks.ANCIENT_DEBRIS)) { - return level >= 3; - } - return true; - } - - @Override - public Multimap getDefaultAttributeModifiers(EquipmentSlot slot) { - return slot == EquipmentSlot.MAINHAND ? this.attributeModifiers : super.getDefaultAttributeModifiers(slot); - } - - @Override - public BlockModel getItemModel(ResourceLocation resourceLocation) { - return ModelsHelper.createHandheldItem(resourceLocation); - } -} diff --git a/src/main/java/ru/betterend/mixin/client/AnvilScreenMixin.java b/src/main/java/ru/betterend/mixin/client/AnvilScreenMixin.java deleted file mode 100644 index 2efb8696..00000000 --- a/src/main/java/ru/betterend/mixin/client/AnvilScreenMixin.java +++ /dev/null @@ -1,96 +0,0 @@ -package ru.betterend.mixin.client; - -import java.util.List; - -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.google.common.collect.Lists; -import com.mojang.blaze3d.vertex.PoseStack; - -import net.minecraft.client.gui.components.AbstractWidget; -import net.minecraft.client.gui.components.Button; -import net.minecraft.client.gui.components.EditBox; -import net.minecraft.client.gui.screens.inventory.AnvilScreen; -import net.minecraft.client.gui.screens.inventory.ItemCombinerScreen; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.inventory.AnvilMenu; -import net.minecraft.world.item.ItemStack; -import ru.betterend.interfaces.AnvilScreenHandlerExtended; - -@Mixin(AnvilScreen.class) -public class AnvilScreenMixin extends ItemCombinerScreen { - - @Shadow - private EditBox name; - - private final List be_buttons = Lists.newArrayList(); - - public AnvilScreenMixin(AnvilMenu handler, Inventory playerInventory, Component title, - ResourceLocation texture) { - super(handler, playerInventory, title, texture); - } - - @Inject(method = "subInit", at = @At("TAIL")) - protected void be_subInit(CallbackInfo info) { - int x = (width - imageWidth) / 2; - int y = (height - imageHeight) / 2; - be_buttons.clear(); - be_buttons.add(new Button(x + 8, y + 45, 15, 20, new TextComponent("<"), b -> be_previousRecipe())); - be_buttons.add(new Button(x + 154, y + 45, 15, 20, new TextComponent(">"), b -> be_nextRecipe())); - } - - @Inject(method = "renderFg", at = @At("TAIL")) - protected void be_renderForeground(PoseStack matrices, int mouseX, int mouseY, float delta, CallbackInfo info) { - be_buttons.forEach(button -> { - button.render(matrices, mouseX, mouseY, delta); - }); - } - - @Inject(method = "slotChanged", at = @At("HEAD"), cancellable = true) - public void be_onSlotUpdate(AbstractContainerMenu handler, int slotId, ItemStack stack, CallbackInfo info) { - AnvilScreenHandlerExtended anvilHandler = (AnvilScreenHandlerExtended) handler; - if (anvilHandler.be_getCurrentRecipe() != null) { - if (anvilHandler.be_getRecipes().size() > 1) { - be_buttons.forEach(button -> button.visible = true); - } else { - be_buttons.forEach(button -> button.visible = false); - } - name.setValue(""); - info.cancel(); - } else { - be_buttons.forEach(button -> button.visible = false); - } - } - - private void be_nextRecipe() { - ((AnvilScreenHandlerExtended) menu).be_nextRecipe(); - } - - private void be_previousRecipe() { - ((AnvilScreenHandlerExtended) menu).be_previousRecipe(); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (minecraft != null) { - for (AbstractWidget elem : be_buttons) { - if (elem.visible && elem.mouseClicked(mouseX, mouseY, button)) { - if (minecraft.gameMode != null) { - int i = be_buttons.indexOf(elem); - minecraft.gameMode.handleInventoryButtonClick(menu.containerId, i); - return true; - } - } - } - } - return super.mouseClicked(mouseX, mouseY, button); - } -} diff --git a/src/main/java/ru/betterend/mixin/client/ArmorStandRendererMixin.java b/src/main/java/ru/betterend/mixin/client/ArmorStandRendererMixin.java deleted file mode 100644 index d3e11b1a..00000000 --- a/src/main/java/ru/betterend/mixin/client/ArmorStandRendererMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package ru.betterend.mixin.client; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import net.minecraft.client.model.ArmorStandArmorModel; -import net.minecraft.client.renderer.entity.ArmorStandRenderer; -import net.minecraft.client.renderer.entity.EntityRenderDispatcher; -import net.minecraft.client.renderer.entity.LivingEntityRenderer; -import net.minecraft.world.entity.decoration.ArmorStand; -import ru.betterend.client.render.ArmoredElytraLayer; - -@Mixin(ArmorStandRenderer.class) -public abstract class ArmorStandRendererMixin extends LivingEntityRenderer { - - public ArmorStandRendererMixin(EntityRenderDispatcher entityRenderDispatcher, ArmorStandArmorModel entityModel, float f) { - super(entityRenderDispatcher, entityModel, f); - } - - @Inject(method = "*", at = @At("TAIL")) - public void be_addCustomLayer(EntityRenderDispatcher entityRenderDispatcher, CallbackInfo info) { - addLayer(new ArmoredElytraLayer<>(this)); - } -} diff --git a/src/main/java/ru/betterend/mixin/client/BiomeColorsMixin.java b/src/main/java/ru/betterend/mixin/client/BiomeColorsMixin.java deleted file mode 100644 index e15ed5fe..00000000 --- a/src/main/java/ru/betterend/mixin/client/BiomeColorsMixin.java +++ /dev/null @@ -1,67 +0,0 @@ -package ru.betterend.mixin.client; - -import java.awt.Point; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.BiomeColors; -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.BlockAndTintGetter; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.ColorUtil; -import ru.betterend.client.ClientOptions; -import ru.betterend.registry.EndBlocks; - -@Mixin(BiomeColors.class) -public class BiomeColorsMixin { - private static final int POISON_COLOR = ColorUtil.color(92, 160, 78); - private static final int STREAM_COLOR = ColorUtil.color(105, 213, 244); - private static final Point[] OFFSETS; - private static final boolean HAS_SODIUM; - - @Inject(method = "getAverageWaterColor", at = @At("RETURN"), cancellable = true) - private static void be_getWaterColor(BlockAndTintGetter world, BlockPos pos, CallbackInfoReturnable info) { - if (ClientOptions.useSulfurWaterColor()) { - BlockAndTintGetter view = HAS_SODIUM ? Minecraft.getInstance().level : world; - MutableBlockPos mut = new MutableBlockPos(); - mut.setY(pos.getY()); - for (int i = 0; i < OFFSETS.length; i++) { - mut.setX(pos.getX() + OFFSETS[i].x); - mut.setZ(pos.getZ() + OFFSETS[i].y); - if ((view.getBlockState(mut).is(EndBlocks.BRIMSTONE))) { - info.setReturnValue(i < 16 ? STREAM_COLOR : POISON_COLOR); - info.cancel(); - return; - } - } - } - } - - static { - HAS_SODIUM = FabricLoader.getInstance().isModLoaded("sodium"); - - OFFSETS = new Point[20]; - for (int i = 0; i < 3; i++) { - int p = i - 1; - OFFSETS[i] = new Point(p, -2); - OFFSETS[i + 3] = new Point(p, 2); - OFFSETS[i + 6] = new Point(-2, p); - OFFSETS[i + 9] = new Point(2, p); - } - - for (int i = 0; i < 4; i++) { - int inner = i + 16; - Direction dir = BlocksHelper.HORIZONTAL[i]; - OFFSETS[inner] = new Point(dir.getStepX(), dir.getStepZ()); - dir = BlocksHelper.HORIZONTAL[(i + 1) & 3]; - OFFSETS[i + 12] = new Point(OFFSETS[inner].x + dir.getStepX(), OFFSETS[inner].y + dir.getStepZ()); - } - } -} diff --git a/src/main/java/ru/betterend/mixin/client/CapeLayerMixin.java b/src/main/java/ru/betterend/mixin/client/CapeLayerMixin.java deleted file mode 100644 index 3e0e5dd5..00000000 --- a/src/main/java/ru/betterend/mixin/client/CapeLayerMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package ru.betterend.mixin.client; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.mojang.blaze3d.vertex.PoseStack; - -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.entity.layers.CapeLayer; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.item.ItemStack; -import ru.betterend.item.ArmoredElytra; - -@Mixin(CapeLayer.class) -public class CapeLayerMixin { - - @Inject(method = "render", at = @At("HEAD"), cancellable = true) - public void be_checkCustomElytra(PoseStack poseStack, MultiBufferSource multiBufferSource, int i, AbstractClientPlayer abstractClientPlayer, float f, float g, float h, float j, float k, float l, CallbackInfo info) { - ItemStack itemStack = abstractClientPlayer.getItemBySlot(EquipmentSlot.CHEST); - if (itemStack.getItem() instanceof ArmoredElytra) { - info.cancel(); - } - } -} diff --git a/src/main/java/ru/betterend/mixin/client/ClientPlayNetworkHandlerMixin.java b/src/main/java/ru/betterend/mixin/client/ClientPlayNetworkHandlerMixin.java deleted file mode 100644 index 6acaf8e9..00000000 --- a/src/main/java/ru/betterend/mixin/client/ClientPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package ru.betterend.mixin.client; - -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.network.protocol.PacketUtils; -import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket; -import net.minecraft.world.level.block.entity.BlockEntity; -import ru.bclib.blockentities.BaseSignBlockEntity; -import ru.bclib.client.gui.BlockSignEditScreen; - -@Mixin(ClientPacketListener.class) -public class ClientPlayNetworkHandlerMixin -{ - @Shadow - private Minecraft minecraft; - - @Shadow - private ClientLevel level; - - @Inject(method = "handleOpenSignEditor", at = @At(value = "HEAD"), cancellable = true) - public void be_openSignEditor(ClientboundOpenSignEditorPacket packet, CallbackInfo info) { - PacketUtils.ensureRunningOnSameThread(packet, ClientPacketListener.class.cast(this), minecraft); - BlockEntity blockEntity = level.getBlockEntity(packet.getPos()); - if (blockEntity instanceof BaseSignBlockEntity) { - BaseSignBlockEntity sign = (BaseSignBlockEntity) blockEntity; - minecraft.setScreen(new BlockSignEditScreen(sign)); - info.cancel(); - } - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/mixin/client/ClientRecipeBookMixin.java b/src/main/java/ru/betterend/mixin/client/ClientRecipeBookMixin.java deleted file mode 100644 index 4fd3d635..00000000 --- a/src/main/java/ru/betterend/mixin/client/ClientRecipeBookMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package ru.betterend.mixin.client; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.client.ClientRecipeBook; -import net.minecraft.client.RecipeBookCategories; -import net.minecraft.world.item.crafting.Recipe; -import ru.betterend.interfaces.BetterEndRecipe; - -@Mixin(ClientRecipeBook.class) -public abstract class ClientRecipeBookMixin { - @Inject(method = "getCategory", at = @At("HEAD"), cancellable = true) - private static void be_getGroupForRecipe(Recipe recipe, CallbackInfoReturnable info) { - if (recipe instanceof BetterEndRecipe) { - info.setReturnValue(RecipeBookCategories.UNKNOWN); - } - } -} diff --git a/src/main/java/ru/betterend/mixin/client/ContextGsonAccessor.java b/src/main/java/ru/betterend/mixin/client/ContextGsonAccessor.java deleted file mode 100644 index 484b3a65..00000000 --- a/src/main/java/ru/betterend/mixin/client/ContextGsonAccessor.java +++ /dev/null @@ -1,14 +0,0 @@ -package ru.betterend.mixin.client; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import com.google.gson.Gson; - -import net.minecraft.client.renderer.block.model.BlockModelDefinition; - -@Mixin(BlockModelDefinition.Context.class) -public interface ContextGsonAccessor { - @Accessor - Gson getGson(); -} diff --git a/src/main/java/ru/betterend/mixin/client/HumanoidMobRendererMixin.java b/src/main/java/ru/betterend/mixin/client/HumanoidMobRendererMixin.java deleted file mode 100644 index cc034cd5..00000000 --- a/src/main/java/ru/betterend/mixin/client/HumanoidMobRendererMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package ru.betterend.mixin.client; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import net.minecraft.client.model.HumanoidModel; -import net.minecraft.client.renderer.entity.EntityRenderDispatcher; -import net.minecraft.client.renderer.entity.HumanoidMobRenderer; -import net.minecraft.client.renderer.entity.MobRenderer; -import net.minecraft.world.entity.Mob; -import ru.betterend.client.render.ArmoredElytraLayer; - -@Mixin(HumanoidMobRenderer.class) -public abstract class HumanoidMobRendererMixin> extends MobRenderer { - - public HumanoidMobRendererMixin(EntityRenderDispatcher entityRenderDispatcher, M entityModel, float f) { - super(entityRenderDispatcher, entityModel, f); - } - - @Inject(method = "*", at = @At("TAIL")) - public void be_addCustomLayer(EntityRenderDispatcher entityRenderDispatcher, M humanoidModel, float f, float g, float h, float i, CallbackInfo info) { - addLayer(new ArmoredElytraLayer<>(this)); - } -} diff --git a/src/main/java/ru/betterend/mixin/client/ItemStackMixin.java b/src/main/java/ru/betterend/mixin/client/ItemStackMixin.java deleted file mode 100644 index d5f52a97..00000000 --- a/src/main/java/ru/betterend/mixin/client/ItemStackMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package ru.betterend.mixin.client; - -import java.util.List; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.network.chat.Component; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; -import ru.betterend.events.ItemTooltipCallback; - -@Mixin(ItemStack.class) -public class ItemStackMixin { - @Inject(method = "getTooltipLines", at = @At("RETURN")) - private void be_getTooltip(Player entity, TooltipFlag tooltipContext, CallbackInfoReturnable> info) { - ItemTooltipCallback.EVENT.invoker().getTooltip(entity, ItemStack.class.cast(this), tooltipContext, info.getReturnValue()); - } -} diff --git a/src/main/java/ru/betterend/mixin/client/LocalPlayerMixin.java b/src/main/java/ru/betterend/mixin/client/LocalPlayerMixin.java deleted file mode 100644 index 49badc32..00000000 --- a/src/main/java/ru/betterend/mixin/client/LocalPlayerMixin.java +++ /dev/null @@ -1,43 +0,0 @@ -package ru.betterend.mixin.client; - -import org.spongepowered.asm.mixin.Final; -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.At.Shift; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.mojang.authlib.GameProfile; - -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.player.LocalPlayer; -import net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.item.ElytraItem; -import net.minecraft.world.item.ItemStack; -import ru.betterend.interfaces.FallFlyingItem; - -@Mixin(LocalPlayer.class) -public abstract class LocalPlayerMixin extends AbstractClientPlayer { - - public LocalPlayerMixin(ClientLevel clientLevel, GameProfile gameProfile) { - super(clientLevel, gameProfile); - } - - @Final - @Shadow - public ClientPacketListener connection; - - @Inject(method = "aiStep", at = @At(value = "INVOKE", - target = "Lnet/minecraft/client/player/LocalPlayer;getItemBySlot(Lnet/minecraft/world/entity/EquipmentSlot;)Lnet/minecraft/world/item/ItemStack;", - shift = Shift.AFTER)) - public void be_aiStep(CallbackInfo info) { - ItemStack itemStack = getItemBySlot(EquipmentSlot.CHEST); - if (itemStack.getItem() instanceof FallFlyingItem && ElytraItem.isFlyEnabled(itemStack) && tryToStartFallFlying()) { - connection.send(new ServerboundPlayerCommandPacket(LocalPlayer.class.cast(this), ServerboundPlayerCommandPacket.Action.START_FALL_FLYING)); - } - } -} diff --git a/src/main/java/ru/betterend/mixin/client/MinecraftClientMixin.java b/src/main/java/ru/betterend/mixin/client/MinecraftClientMixin.java deleted file mode 100644 index 81e2e2e4..00000000 --- a/src/main/java/ru/betterend/mixin/client/MinecraftClientMixin.java +++ /dev/null @@ -1,76 +0,0 @@ -package ru.betterend.mixin.client; - -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.color.block.BlockColors; -import net.minecraft.client.color.item.ItemColors; -import net.minecraft.client.gui.Gui; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.gui.screens.WinScreen; -import net.minecraft.client.main.GameConfig; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.player.LocalPlayer; -import net.minecraft.core.Registry; -import net.minecraft.sounds.Music; -import net.minecraft.sounds.Musics; -import net.minecraft.world.level.Level; -import ru.bclib.interfaces.IColorProvider; -import ru.bclib.util.MHelper; - -@Mixin(Minecraft.class) -public class MinecraftClientMixin { - @Shadow - public LocalPlayer player; - - @Shadow - public Screen screen; - - @Final - @Shadow - public Gui gui; - - @Shadow - public ClientLevel level; - - @Final - @Shadow - private BlockColors blockColors; - - @Final - @Shadow - private ItemColors itemColors; - - @Inject(method = "*", at = @At("TAIL")) - private void be_onInit(GameConfig args, CallbackInfo info) { - Registry.BLOCK.forEach(block -> { - if (block instanceof IColorProvider) { - IColorProvider provider = (IColorProvider) block; - blockColors.register(provider.getProvider(), block); - itemColors.register(provider.getItemProvider(), block.asItem()); - } - }); - } - - @Inject(method = "getSituationalMusic", at = @At("HEAD"), cancellable = true) - private void be_getEndMusic(CallbackInfoReturnable info) { - if (!(this.screen instanceof WinScreen) && this.player != null) { - if (this.player.level.dimension() == Level.END) { - if (this.gui.getBossOverlay().shouldPlayMusic() && MHelper.lengthSqr(this.player.getX(), this.player.getZ()) < 250000) { - info.setReturnValue(Musics.END_BOSS); - } - else { - Music sound = (Music) this.level.getBiomeManager().getNoiseBiomeAtPosition(this.player.blockPosition()).getBackgroundMusic().orElse(Musics.END); - info.setReturnValue(sound); - } - info.cancel(); - } - } - } -} diff --git a/src/main/java/ru/betterend/mixin/client/ModelLoaderMixin.java b/src/main/java/ru/betterend/mixin/client/ModelLoaderMixin.java deleted file mode 100644 index 4c65b28b..00000000 --- a/src/main/java/ru/betterend/mixin/client/ModelLoaderMixin.java +++ /dev/null @@ -1,23 +0,0 @@ -package ru.betterend.mixin.client; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -import net.minecraft.client.resources.model.ModelBakery; -import net.minecraft.resources.ResourceLocation; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(ModelBakery.class) -public abstract class ModelLoaderMixin { - - @ModifyVariable(method = "loadModel", ordinal = 2, at = @At(value = "INVOKE")) - public ResourceLocation be_switchModel(ResourceLocation id) { - if (GeneratorOptions.changeChorusPlant() && id.getNamespace().equals("minecraft") && - id.getPath().startsWith("blockstates/") && id.getPath().contains("chorus") && - !id.getPath().contains("custom_")) { - id = new ResourceLocation(id.getPath().replace("chorus", "custom_chorus")); - } - return id; - } -} diff --git a/src/main/java/ru/betterend/mixin/client/MusicTrackerMixin.java b/src/main/java/ru/betterend/mixin/client/MusicTrackerMixin.java deleted file mode 100644 index 7af64b12..00000000 --- a/src/main/java/ru/betterend/mixin/client/MusicTrackerMixin.java +++ /dev/null @@ -1,98 +0,0 @@ -package ru.betterend.mixin.client; - -import java.util.Random; - -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.sounds.AbstractSoundInstance; -import net.minecraft.client.resources.sounds.SoundInstance; -import net.minecraft.client.sounds.MusicManager; -import net.minecraft.sounds.Music; -import net.minecraft.util.Mth; -import net.minecraft.world.level.Level; -import ru.betterend.client.ClientOptions; - -@Mixin(MusicManager.class) -public abstract class MusicTrackerMixin { - @Final - @Shadow - private Minecraft minecraft; - - @Final - @Shadow - private Random random; - - @Shadow - private SoundInstance currentMusic; - - @Shadow - private int nextSongDelay; - - private static float volume = 1; - private static float srcVolume = 0; - private static long time; - - @Inject(method = "tick", at = @At("HEAD"), cancellable = true) - public void be_onTick(CallbackInfo info) { - if (ClientOptions.blendBiomeMusic()) { - Music musicSound = minecraft.getSituationalMusic(); - if (be_checkNullSound(musicSound) && volume > 0 && be_isInEnd() && be_shouldChangeSound(musicSound)) { - if (volume > 0) { - if (srcVolume < 0) { - srcVolume = currentMusic.getVolume(); - } - if (currentMusic instanceof AbstractSoundInstance) { - ((AbstractSoundInstanceAccessor) currentMusic).setVolume(volume); - } - minecraft.getSoundManager().updateSourceVolume(currentMusic.getSource(), currentMusic.getVolume() * volume); - long t = System.currentTimeMillis(); - if (volume == 1 && time == 0) { - time = t; - } - float delta = (t - time) * 0.0005F; - time = t; - volume -= delta; - if (volume < 0) { - volume = 0; - } - } - if (volume == 0) { - volume = 1; - time = 0; - srcVolume = -1; - this.minecraft.getSoundManager().stop(this.currentMusic); - this.nextSongDelay = Mth.nextInt(this.random, 0, musicSound.getMinDelay() / 2); - this.currentMusic = null; - } - if (this.currentMusic == null && this.nextSongDelay-- <= 0) { - this.startPlaying(musicSound); - } - info.cancel(); - } - else { - volume = 1; - } - } - } - - private boolean be_isInEnd() { - return minecraft.level != null && minecraft.level.dimension().equals(Level.END); - } - - private boolean be_shouldChangeSound(Music musicSound) { - return currentMusic != null && !musicSound.getEvent().getLocation().equals(this.currentMusic.getLocation()) && musicSound.replaceCurrentMusic(); - } - - private boolean be_checkNullSound(Music musicSound) { - return musicSound != null && musicSound.getEvent() != null; - } - - @Shadow - public abstract void startPlaying(Music type); -} diff --git a/src/main/java/ru/betterend/mixin/client/PlayerRendererMixin.java b/src/main/java/ru/betterend/mixin/client/PlayerRendererMixin.java deleted file mode 100644 index d435dd52..00000000 --- a/src/main/java/ru/betterend/mixin/client/PlayerRendererMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package ru.betterend.mixin.client; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import net.minecraft.client.model.PlayerModel; -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.renderer.entity.EntityRenderDispatcher; -import net.minecraft.client.renderer.entity.LivingEntityRenderer; -import net.minecraft.client.renderer.entity.player.PlayerRenderer; -import ru.betterend.client.render.ArmoredElytraLayer; - -@Mixin(PlayerRenderer.class) -public abstract class PlayerRendererMixin extends LivingEntityRenderer> { - - public PlayerRendererMixin(EntityRenderDispatcher entityRenderDispatcher, PlayerModel entityModel, float f) { - super(entityRenderDispatcher, entityModel, f); - } - - @Inject(method = "(Lnet/minecraft/client/renderer/entity/EntityRenderDispatcher;Z)V", at = @At("TAIL")) - public void be_addCustomLayer(EntityRenderDispatcher entityRenderDispatcher, boolean bl, CallbackInfo info) { - addLayer(new ArmoredElytraLayer<>(this)); - } -} diff --git a/src/main/java/ru/betterend/mixin/client/WorldRendererMixin.java b/src/main/java/ru/betterend/mixin/client/WorldRendererMixin.java deleted file mode 100644 index b24d3517..00000000 --- a/src/main/java/ru/betterend/mixin/client/WorldRendererMixin.java +++ /dev/null @@ -1,427 +0,0 @@ -package ru.betterend.mixin.client; - -import java.util.Random; - -import org.lwjgl.opengl.GL11; -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.Tesselator; -import com.mojang.blaze3d.vertex.VertexBuffer; -import com.mojang.blaze3d.vertex.VertexFormat; -import com.mojang.math.Quaternion; -import com.mojang.math.Vector3f; - -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.DimensionSpecialEffects; -import net.minecraft.client.renderer.FogRenderer; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.RenderBuffers; -import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.resources.ResourceLocation; -import ru.bclib.util.BackgroundInfo; -import ru.bclib.util.MHelper; -import ru.betterend.BetterEnd; -import ru.betterend.client.ClientOptions; - -@Mixin(LevelRenderer.class) -public class WorldRendererMixin { - private static final ResourceLocation NEBULA_1 = BetterEnd.makeID("textures/sky/nebula_2.png"); - private static final ResourceLocation NEBULA_2 = BetterEnd.makeID("textures/sky/nebula_3.png"); - private static final ResourceLocation HORIZON = BetterEnd.makeID("textures/sky/nebula_1.png"); - private static final ResourceLocation STARS = BetterEnd.makeID("textures/sky/stars.png"); - private static final ResourceLocation FOG = BetterEnd.makeID("textures/sky/fog.png"); - - private static VertexBuffer stars1; - private static VertexBuffer stars2; - private static VertexBuffer stars3; - private static VertexBuffer stars4; - private static VertexBuffer nebulas1; - private static VertexBuffer nebulas2; - private static VertexBuffer horizon; - private static VertexBuffer fog; - private static Vector3f axis1; - private static Vector3f axis2; - private static Vector3f axis3; - private static Vector3f axis4; - private static float time; - private static float time2; - private static float time3; - private static float blind02; - private static float blind06; - private static boolean directOpenGL = false; - - @Shadow - @Final - private Minecraft minecraft; - - @Shadow - @Final - private TextureManager textureManager; - - @Shadow - private ClientLevel level; - - @Shadow - private int ticks; - - @Inject(method = "*", at = @At("TAIL")) - private void be_onInit(Minecraft client, RenderBuffers bufferBuilders, CallbackInfo info) { - be_initStars(); - Random random = new Random(131); - axis1 = new Vector3f(random.nextFloat(), random.nextFloat(), random.nextFloat()); - axis2 = new Vector3f(random.nextFloat(), random.nextFloat(), random.nextFloat()); - axis3 = new Vector3f(random.nextFloat(), random.nextFloat(), random.nextFloat()); - axis4 = new Vector3f(random.nextFloat(), random.nextFloat(), random.nextFloat()); - axis1.normalize(); - axis2.normalize(); - axis3.normalize(); - axis4.normalize(); - - directOpenGL = FabricLoader.getInstance().isModLoaded("optifabric") || FabricLoader.getInstance().isModLoaded("immersive_portals"); - } - - @Inject(method = "renderSky", at = @At("HEAD"), cancellable = true) - private void be_renderBetterEndSky(PoseStack matrices, float tickDelta, CallbackInfo info) { - if (ClientOptions.isCustomSky() && minecraft.level.effects().skyType() == DimensionSpecialEffects.SkyType.END) { - time = (ticks % 360000) * 0.000017453292F; - time2 = time * 2; - time3 = time * 3; - - FogRenderer.levelFogColor(); - RenderSystem.enableTexture(); - - if (directOpenGL) { - GL11.glEnable(GL11.GL_ALPHA_TEST); - GL11.glAlphaFunc(516, 0.0F); - GL11.glEnable(GL11.GL_BLEND); - RenderSystem.depthMask(false); - } - else { - RenderSystem.enableAlphaTest(); - RenderSystem.alphaFunc(516, 0.0F); - RenderSystem.enableBlend(); - } - - float blindA = 1F - BackgroundInfo.blindness; - blind02 = blindA * 0.2F; - blind06 = blindA * 0.6F; - - if (blindA > 0) { - matrices.pushPose(); - matrices.mulPose(new Quaternion(0, time, 0, false)); - textureManager.bind(HORIZON); - be_renderBuffer(matrices, horizon, DefaultVertexFormat.POSITION_TEX, 0.77F, 0.31F, 0.73F, 0.7F * blindA); - matrices.popPose(); - - matrices.pushPose(); - matrices.mulPose(new Quaternion(0, -time, 0, false)); - textureManager.bind(NEBULA_1); - be_renderBuffer(matrices, nebulas1, DefaultVertexFormat.POSITION_TEX, 0.77F, 0.31F, 0.73F, blind02); - matrices.popPose(); - - matrices.pushPose(); - matrices.mulPose(new Quaternion(0, time2, 0, false)); - textureManager.bind(NEBULA_2); - be_renderBuffer(matrices, nebulas2, DefaultVertexFormat.POSITION_TEX, 0.77F, 0.31F, 0.73F, blind02); - matrices.popPose(); - - textureManager.bind(STARS); - - matrices.pushPose(); - matrices.mulPose(axis3.rotation(time)); - be_renderBuffer(matrices, stars3, DefaultVertexFormat.POSITION_TEX, 0.77F, 0.31F, 0.73F, blind06); - matrices.popPose(); - - matrices.pushPose(); - matrices.mulPose(axis4.rotation(time2)); - be_renderBuffer(matrices, stars4, DefaultVertexFormat.POSITION_TEX, 1F, 1F, 1F, blind06); - matrices.popPose(); - } - - float a = (BackgroundInfo.fogDensity - 1F); - if (a > 0) { - if (a > 1) a = 1; - textureManager.bind(FOG); - be_renderBuffer(matrices, fog, DefaultVertexFormat.POSITION_TEX, BackgroundInfo.fogColorRed, BackgroundInfo.fogColorGreen, BackgroundInfo.fogColorBlue, a); - } - - RenderSystem.disableTexture(); - - if (blindA > 0) { - matrices.pushPose(); - matrices.mulPose(axis1.rotation(time3)); - be_renderBuffer(matrices, stars1, DefaultVertexFormat.POSITION, 1, 1, 1, blind06); - matrices.popPose(); - - matrices.pushPose(); - matrices.mulPose(axis2.rotation(time2)); - be_renderBuffer(matrices, stars2, DefaultVertexFormat.POSITION, 0.95F, 0.64F, 0.93F, blind06); - matrices.popPose(); - } - - RenderSystem.enableTexture(); - RenderSystem.depthMask(true); - - info.cancel(); - } - } - - private void be_renderBuffer(PoseStack matrices, VertexBuffer buffer, VertexFormat format, float r, float g, float b, float a) { - RenderSystem.color4f(r, g, b, a); - buffer.bind(); - format.setupBufferState(0L); - buffer.draw(matrices.last().pose(), 7); - VertexBuffer.unbind(); - format.clearBufferState(); - } - - private void be_initStars() { - BufferBuilder buffer = Tesselator.getInstance().getBuilder(); - stars1 = be_buildBufferStars(buffer, stars1, 0.1, 0.30, 3500, 41315); - stars2 = be_buildBufferStars(buffer, stars2, 0.1, 0.35, 2000, 35151); - stars3 = be_buildBufferUVStars(buffer, stars3, 0.4, 1.2, 1000, 61354); - stars4 = be_buildBufferUVStars(buffer, stars4, 0.4, 1.2, 1000, 61355); - nebulas1 = be_buildBufferFarFog(buffer, nebulas1, 40, 60, 30, 11515); - nebulas2 = be_buildBufferFarFog(buffer, nebulas2, 40, 60, 10, 14151); - horizon = be_buildBufferHorizon(buffer, horizon); - fog = be_buildBufferFog(buffer, fog); - } - - private VertexBuffer be_buildBufferStars(BufferBuilder bufferBuilder, VertexBuffer buffer, double minSize, double maxSize, int count, long seed) { - if (buffer != null) { - buffer.close(); - } - - buffer = new VertexBuffer(DefaultVertexFormat.POSITION); - be_makeStars(bufferBuilder, minSize, maxSize, count, seed); - bufferBuilder.end(); - buffer.upload(bufferBuilder); - - return buffer; - } - - private VertexBuffer be_buildBufferUVStars(BufferBuilder bufferBuilder, VertexBuffer buffer, double minSize, double maxSize, int count, long seed) { - if (buffer != null) { - buffer.close(); - } - - buffer = new VertexBuffer(DefaultVertexFormat.POSITION_TEX); - be_makeUVStars(bufferBuilder, minSize, maxSize, count, seed); - bufferBuilder.end(); - buffer.upload(bufferBuilder); - - return buffer; - } - - private VertexBuffer be_buildBufferFarFog(BufferBuilder bufferBuilder, VertexBuffer buffer, double minSize, double maxSize, int count, long seed) { - if (buffer != null) { - buffer.close(); - } - - buffer = new VertexBuffer(DefaultVertexFormat.POSITION_TEX); - be_makeFarFog(bufferBuilder, minSize, maxSize, count, seed); - bufferBuilder.end(); - buffer.upload(bufferBuilder); - - return buffer; - } - - private VertexBuffer be_buildBufferHorizon(BufferBuilder bufferBuilder, VertexBuffer buffer) { - if (buffer != null) { - buffer.close(); - } - - buffer = new VertexBuffer(DefaultVertexFormat.POSITION_TEX); - be_makeCylinder(bufferBuilder, 16, 50, 100); - bufferBuilder.end(); - buffer.upload(bufferBuilder); - - return buffer; - } - - private VertexBuffer be_buildBufferFog(BufferBuilder bufferBuilder, VertexBuffer buffer) { - if (buffer != null) { - buffer.close(); - } - - buffer = new VertexBuffer(DefaultVertexFormat.POSITION_TEX); - be_makeCylinder(bufferBuilder, 16, 50, 70); - bufferBuilder.end(); - buffer.upload(bufferBuilder); - - return buffer; - } - - private void be_makeStars(BufferBuilder buffer, double minSize, double maxSize, int count, long seed) { - Random random = new Random(seed); - buffer.begin(7, DefaultVertexFormat.POSITION); - - for (int i = 0; i < count; ++i) { - double posX = random.nextDouble() * 2.0 - 1.0; - double posY = random.nextDouble() * 2.0 - 1.0; - double posZ = random.nextDouble() * 2.0 - 1.0; - double size = MHelper.randRange(minSize, maxSize, random); - double length = posX * posX + posY * posY + posZ * posZ; - if (length < 1.0 && length > 0.001) { - length = 1.0 / Math.sqrt(length); - posX *= length; - posY *= length; - posZ *= length; - double j = posX * 100.0; - double k = posY * 100.0; - double l = posZ * 100.0; - double m = Math.atan2(posX, posZ); - double n = Math.sin(m); - double o = Math.cos(m); - double p = Math.atan2(Math.sqrt(posX * posX + posZ * posZ), posY); - double q = Math.sin(p); - double r = Math.cos(p); - double s = random.nextDouble() * Math.PI * 2.0; - double t = Math.sin(s); - double u = Math.cos(s); - - for (int v = 0; v < 4; ++v) { - double x = (double) ((v & 2) - 1) * size; - double y = (double) ((v + 1 & 2) - 1) * size; - double aa = x * u - y * t; - double ab = y * u + x * t; - double ad = aa * q + 0.0 * r; - double ae = 0.0 * q - aa * r; - double af = ae * n - ab * o; - double ah = ab * n + ae * o; - buffer.vertex(j + af, k + ad, l + ah).endVertex(); - } - } - } - } - - private void be_makeUVStars(BufferBuilder buffer, double minSize, double maxSize, int count, long seed) { - Random random = new Random(seed); - buffer.begin(7, DefaultVertexFormat.POSITION_TEX); - - for (int i = 0; i < count; ++i) { - double posX = random.nextDouble() * 2.0 - 1.0; - double posY = random.nextDouble() * 2.0 - 1.0; - double posZ = random.nextDouble() * 2.0 - 1.0; - double size = MHelper.randRange(minSize, maxSize, random); - double length = posX * posX + posY * posY + posZ * posZ; - if (length < 1.0 && length > 0.001) { - length = 1.0 / Math.sqrt(length); - posX *= length; - posY *= length; - posZ *= length; - double j = posX * 100.0; - double k = posY * 100.0; - double l = posZ * 100.0; - double m = Math.atan2(posX, posZ); - double n = Math.sin(m); - double o = Math.cos(m); - double p = Math.atan2(Math.sqrt(posX * posX + posZ * posZ), posY); - double q = Math.sin(p); - double r = Math.cos(p); - double s = random.nextDouble() * Math.PI * 2.0; - double t = Math.sin(s); - double u = Math.cos(s); - - int pos = 0; - float minV = random.nextInt(4) / 4F; - for (int v = 0; v < 4; ++v) { - double x = (double) ((v & 2) - 1) * size; - double y = (double) ((v + 1 & 2) - 1) * size; - double aa = x * u - y * t; - double ab = y * u + x * t; - double ad = aa * q + 0.0 * r; - double ae = 0.0 * q - aa * r; - double af = ae * n - ab * o; - double ah = ab * n + ae * o; - float texU = (pos >> 1) & 1; - float texV = (((pos + 1) >> 1) & 1) / 4F + minV; - pos ++; - buffer.vertex(j + af, k + ad, l + ah).uv(texU, texV).endVertex(); - } - } - } - } - - private void be_makeFarFog(BufferBuilder buffer, double minSize, double maxSize, int count, long seed) { - Random random = new Random(seed); - buffer.begin(7, DefaultVertexFormat.POSITION_TEX); - - for (int i = 0; i < count; ++i) { - double posX = random.nextDouble() * 2.0 - 1.0; - double posY = random.nextDouble() - 0.5; - double posZ = random.nextDouble() * 2.0 - 1.0; - double size = MHelper.randRange(minSize, maxSize, random); - double length = posX * posX + posY * posY + posZ * posZ; - double distance = 2.0; - double delta = 1.0 / count; - if (length < 1.0 && length > 0.001) { - length = distance / Math.sqrt(length); - size *= distance; - distance -= delta; - posX *= length; - posY *= length; - posZ *= length; - double j = posX * 100.0; - double k = posY * 100.0; - double l = posZ * 100.0; - double m = Math.atan2(posX, posZ); - double n = Math.sin(m); - double o = Math.cos(m); - double p = Math.atan2(Math.sqrt(posX * posX + posZ * posZ), posY); - double q = Math.sin(p); - double r = Math.cos(p); - double s = random.nextDouble() * Math.PI * 2.0; - double t = Math.sin(s); - double u = Math.cos(s); - - int pos = 0; - for (int v = 0; v < 4; ++v) { - double x = (double) ((v & 2) - 1) * size; - double y = (double) ((v + 1 & 2) - 1) * size; - double aa = x * u - y * t; - double ab = y * u + x * t; - double ad = aa * q + 0.0 * r; - double ae = 0.0 * q - aa * r; - double af = ae * n - ab * o; - double ah = ab * n + ae * o; - float texU = (pos >> 1) & 1; - float texV = ((pos + 1) >> 1) & 1; - pos ++; - buffer.vertex(j + af, k + ad, l + ah).uv(texU, texV).endVertex(); - } - } - } - } - - private void be_makeCylinder(BufferBuilder buffer, int segments, double height, double radius) { - buffer.begin(7, DefaultVertexFormat.POSITION_TEX); - for (int i = 0; i < segments; i ++) { - double a1 = (double) i * Math.PI * 2.0 / (double) segments; - double a2 = (double) (i + 1) * Math.PI * 2.0 / (double) segments; - double px1 = Math.sin(a1) * radius; - double pz1 = Math.cos(a1) * radius; - double px2 = Math.sin(a2) * radius; - double pz2 = Math.cos(a2) * radius; - - float u0 = (float) i / (float) segments; - float u1 = (float) (i + 1) / (float) segments; - - buffer.vertex(px1, -height, pz1).uv(u0, 0).endVertex(); - buffer.vertex(px1, height, pz1).uv(u0, 1).endVertex(); - buffer.vertex(px2, height, pz2).uv(u1, 1).endVertex(); - buffer.vertex(px2, -height, pz2).uv(u1, 0).endVertex(); - } - } -} diff --git a/src/main/java/ru/betterend/mixin/common/AnvilMenuMixin.java b/src/main/java/ru/betterend/mixin/common/AnvilMenuMixin.java deleted file mode 100644 index 41683dec..00000000 --- a/src/main/java/ru/betterend/mixin/common/AnvilMenuMixin.java +++ /dev/null @@ -1,152 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.tags.BlockTags; -import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.AnvilMenu; -import net.minecraft.world.inventory.ContainerLevelAccess; -import net.minecraft.world.inventory.DataSlot; -import net.minecraft.world.inventory.ItemCombinerMenu; -import net.minecraft.world.inventory.MenuType; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.RecipeManager; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import ru.betterend.blocks.basis.EndAnvilBlock; -import ru.betterend.interfaces.AnvilScreenHandlerExtended; -import ru.betterend.recipe.builders.AnvilRecipe; - -@Mixin(AnvilMenu.class) -public abstract class AnvilMenuMixin extends ItemCombinerMenu implements AnvilScreenHandlerExtended { - private List be_recipes = Collections.emptyList(); - private AnvilRecipe be_currentRecipe; - private DataSlot anvilLevel; - - public AnvilMenuMixin(int syncId, Inventory playerInventory) { - super(MenuType.ANVIL, syncId, playerInventory, ContainerLevelAccess.NULL); - } - - @Inject(method = "(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/inventory/ContainerLevelAccess;)V", at = @At("TAIL")) - public void be_initAnvilLevel(int syncId, Inventory inventory, ContainerLevelAccess context, CallbackInfo info) { - this.anvilLevel = addDataSlot(DataSlot.standalone()); - if (context != ContainerLevelAccess.NULL) { - int level = context.evaluate((world, blockPos) -> { - Block anvilBlock = world.getBlockState(blockPos).getBlock(); - if (anvilBlock instanceof EndAnvilBlock) { - return ((EndAnvilBlock) anvilBlock).getCraftingLevel(); - } - return 1; - }, 1); - anvilLevel.set(level); - } else { - anvilLevel.set(1); - } - } - - @Shadow - public abstract void createResult(); - - @Inject(method = "mayPickup", at = @At("HEAD"), cancellable = true) - protected void be_canTakeOutput(Player player, boolean present, CallbackInfoReturnable info) { - if (be_currentRecipe != null) { - info.setReturnValue(be_currentRecipe.checkHammerDurability(inputSlots, player)); - } - } - - @Inject(method = "onTake", at = @At("HEAD"), cancellable = true) - protected void be_onTakeOutput(Player player, ItemStack stack, CallbackInfoReturnable info) { - if (be_currentRecipe != null) { - inputSlots.getItem(0).shrink(be_currentRecipe.getInputCount()); - stack = be_currentRecipe.craft(inputSlots, player); - slotsChanged(inputSlots); - access.execute((world, blockPos) -> { - BlockState anvilState = world.getBlockState(blockPos); - if (!player.abilities.instabuild && anvilState.is(BlockTags.ANVIL) && player.getRandom().nextDouble() < 0.1) { - BlockState landingState = EndAnvilBlock.applyDamage(anvilState); - if (landingState == null) { - world.removeBlock(blockPos, false); - world.levelEvent(1029, blockPos, 0); - } else { - world.setBlock(blockPos, landingState, 2); - world.levelEvent(1030, blockPos, 0); - } - } else { - world.levelEvent(1030, blockPos, 0); - } - }); - info.setReturnValue(stack); - } - } - - @Inject(method = "createResult", at = @At("HEAD"), cancellable = true) - public void be_updateOutput(CallbackInfo info) { - RecipeManager recipeManager = this.player.level.getRecipeManager(); - be_recipes = recipeManager.getRecipesFor(AnvilRecipe.TYPE, inputSlots, player.level); - if (be_recipes.size() > 0) { - int anvilLevel = this.anvilLevel.get(); - be_recipes = be_recipes.stream().filter(recipe -> - anvilLevel >= recipe.getAnvilLevel()).collect(Collectors.toList()); - if (be_recipes.size() > 0) { - if (be_currentRecipe == null || !be_recipes.contains(be_currentRecipe)) { - be_currentRecipe = be_recipes.get(0); - } - be_updateResult(); - info.cancel(); - } else { - be_currentRecipe = null; - } - } - } - - @Inject(method = "setItemName", at = @At("HEAD"), cancellable = true) - public void be_setNewItemName(String string, CallbackInfo info) { - if (be_currentRecipe != null) { - info.cancel(); - } - } - - @Override - public boolean clickMenuButton(Player player, int id) { - if (id == 0) { - be_previousRecipe(); - return true; - } else if (id == 1) { - be_nextRecipe(); - return true; - } - return super.clickMenuButton(player, id); - } - - private void be_updateResult() { - if (be_currentRecipe == null) return; - resultSlots.setItem(0, be_currentRecipe.assemble(inputSlots)); - broadcastChanges(); - } - - @Override - public void be_updateCurrentRecipe(AnvilRecipe recipe) { - this.be_currentRecipe = recipe; - be_updateResult(); - } - - @Override - public AnvilRecipe be_getCurrentRecipe() { - return be_currentRecipe; - } - - @Override - public List be_getRecipes() { - return be_recipes; - } -} diff --git a/src/main/java/ru/betterend/mixin/common/BiomeGenerationSettingsAccessor.java b/src/main/java/ru/betterend/mixin/common/BiomeGenerationSettingsAccessor.java deleted file mode 100644 index eb1f962b..00000000 --- a/src/main/java/ru/betterend/mixin/common/BiomeGenerationSettingsAccessor.java +++ /dev/null @@ -1,26 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.List; -import java.util.function.Supplier; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import net.minecraft.world.level.biome.BiomeGenerationSettings; -import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; -import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; - -@Mixin(BiomeGenerationSettings.class) -public interface BiomeGenerationSettingsAccessor { - @Accessor("features") - List>>> be_getFeatures(); - - @Accessor("features") - void be_setFeatures(List>>> features); - - @Accessor("structureStarts") - List>> be_getStructures(); - - @Accessor("structureStarts") - void be_setStructures(List>> structures); -} diff --git a/src/main/java/ru/betterend/mixin/common/BlockBehaviourMixin.java b/src/main/java/ru/betterend/mixin/common/BlockBehaviourMixin.java deleted file mode 100644 index ebc0c0bd..00000000 --- a/src/main/java/ru/betterend/mixin/common/BlockBehaviourMixin.java +++ /dev/null @@ -1,48 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.List; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import com.google.common.collect.Lists; - -import net.minecraft.util.Mth; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.Enchantments; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import ru.bclib.util.MHelper; -import ru.betterend.item.tool.EndHammerItem; - -@Mixin(BlockBehaviour.class) -public abstract class BlockBehaviourMixin { - @Inject(method = "getDrops", at = @At("HEAD"), cancellable = true) - public void be_getDroppedStacks(BlockState state, LootContext.Builder builder, CallbackInfoReturnable> info) { - if (state.is(Blocks.GLOWSTONE)) { - ItemStack tool = builder.getParameter(LootContextParams.TOOL); - if (tool != null && tool.getItem() instanceof EndHammerItem) { - int min = 3; - int max = 4; - int count = 0; - int fortune = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, tool); - if (fortune > 0) { - fortune /= Enchantments.BLOCK_FORTUNE.getMaxLevel(); - min = Mth.clamp(min + fortune, min, max); - if (min == max) { - info.setReturnValue(Lists.newArrayList(new ItemStack(Items.GLOWSTONE_DUST, max))); - } - } - count = MHelper.randRange(min, max, MHelper.RANDOM); - info.setReturnValue(Lists.newArrayList(new ItemStack(Items.GLOWSTONE_DUST, count))); - } - } - } -} diff --git a/src/main/java/ru/betterend/mixin/common/ChorusFlowerBlockMixin.java b/src/main/java/ru/betterend/mixin/common/ChorusFlowerBlockMixin.java deleted file mode 100644 index dcd4bc58..00000000 --- a/src/main/java/ru/betterend/mixin/common/ChorusFlowerBlockMixin.java +++ /dev/null @@ -1,112 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.Random; - -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.ChorusFlowerBlock; -import net.minecraft.world.level.block.ChorusPlantBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.betterend.blocks.VanillaBlockProperties; -import ru.betterend.registry.EndBlocks; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(value = ChorusFlowerBlock.class, priority = 100) -public abstract class ChorusFlowerBlockMixin extends Block { - private static final VoxelShape SHAPE_FULL = Block.box(0, 0, 0, 16, 16, 16); - private static final VoxelShape SHAPE_HALF = Block.box(0, 0, 0, 16, 4, 16); - - public ChorusFlowerBlockMixin(Properties settings) { - super(settings); - } - - @Final - @Shadow - private ChorusPlantBlock plant; - - @Inject(method = "canSurvive", at = @At("HEAD"), cancellable = true) - private void be_canSurvive(BlockState state, LevelReader world, BlockPos pos, CallbackInfoReturnable info) { - if (world.getBlockState(pos.below()).is(EndBlocks.CHORUS_NYLIUM)) { - info.setReturnValue(true); - info.cancel(); - } - } - - @Inject(method = "randomTick", at = @At("HEAD"), cancellable = true) - private void be_randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random, CallbackInfo info) { - if (world.getBlockState(pos.below()).is(TagAPI.END_GROUND)) { - BlockPos up = pos.above(); - if (world.isEmptyBlock(up) && up.getY() < 256) { - int i = state.getValue(ChorusFlowerBlock.AGE); - if (i < 5) { - this.placeGrownFlower(world, up, i + 1); - if (GeneratorOptions.changeChorusPlant()) { - BlocksHelper.setWithoutUpdate(world, pos, plant.defaultBlockState().setValue(ChorusPlantBlock.UP, true).setValue(ChorusPlantBlock.DOWN, true).setValue(VanillaBlockProperties.ROOTS, true)); - } - else { - BlocksHelper.setWithoutUpdate(world, pos, plant.defaultBlockState().setValue(ChorusPlantBlock.UP, true).setValue(ChorusPlantBlock.DOWN, true)); - } - info.cancel(); - } - } - } - } - - @Inject(method = "generatePlant", at = @At("RETURN"), cancellable = true) - private static void be_generatePlant(LevelAccessor world, BlockPos pos, Random random, int size, CallbackInfo info) { - BlockState state = world.getBlockState(pos); - if (GeneratorOptions.changeChorusPlant() && state.is(Blocks.CHORUS_PLANT)) { - BlocksHelper.setWithoutUpdate(world, pos, state.setValue(VanillaBlockProperties.ROOTS, true)); - } - } - - @Shadow - private static boolean allNeighborsEmpty(LevelReader world, BlockPos pos, @Nullable Direction exceptDirection) { return false; } - - @Shadow - private void placeGrownFlower(Level world, BlockPos pos, int age) {} - - @Shadow - private void placeDeadFlower(Level world, BlockPos pos) {} - - @Override - public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { - if (GeneratorOptions.changeChorusPlant()) { - return state.getValue(ChorusFlowerBlock.AGE) == 5 ? SHAPE_HALF : SHAPE_FULL; - } - else { - return super.getShape(state, world, pos, context); - } - } - - @Inject(method = "placeDeadFlower", at = @At("HEAD"), cancellable = true) - private void be_placeDeadFlower(Level world, BlockPos pos, CallbackInfo info) { - BlockState down = world.getBlockState(pos.below()); - if (down.is(Blocks.CHORUS_PLANT) || down.is(TagAPI.GEN_TERRAIN)) { - world.setBlock(pos, this.defaultBlockState().setValue(BlockStateProperties.AGE_5, 5), 2); - world.levelEvent(1034, pos, 0); - } - info.cancel(); - } -} diff --git a/src/main/java/ru/betterend/mixin/common/ChorusPlantBlockMixin.java b/src/main/java/ru/betterend/mixin/common/ChorusPlantBlockMixin.java deleted file mode 100644 index 43427483..00000000 --- a/src/main/java/ru/betterend/mixin/common/ChorusPlantBlockMixin.java +++ /dev/null @@ -1,122 +0,0 @@ -package ru.betterend.mixin.common; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.ChorusPlantBlock; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import ru.bclib.api.TagAPI; -import ru.betterend.blocks.VanillaBlockProperties; -import ru.betterend.registry.EndBlocks; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(value = ChorusPlantBlock.class, priority = 100) -public abstract class ChorusPlantBlockMixin extends Block { - public ChorusPlantBlockMixin(Properties settings) { - super(settings); - } - - @Inject(method = "*", at = @At("TAIL")) - private void beOnInit(BlockBehaviour.Properties settings, CallbackInfo info) { - if (GeneratorOptions.changeChorusPlant()) { - this.registerDefaultState(this.defaultBlockState().setValue(VanillaBlockProperties.ROOTS, false)); - } - } - - @Inject(method = "createBlockStateDefinition", at = @At("TAIL")) - private void be_createBlockStateDefinition(StateDefinition.Builder builder, CallbackInfo info) { - GeneratorOptions.init(); - if (GeneratorOptions.changeChorusPlant()) { - builder.add(VanillaBlockProperties.ROOTS); - } - } - - @Inject(method = "getStateForPlacement", at = @At("RETURN"), cancellable = true) - private void be_getStateForPlacement(BlockPlaceContext ctx, CallbackInfoReturnable info) { - BlockPos pos = ctx.getClickedPos(); - Level world = ctx.getLevel(); - BlockState plant = info.getReturnValue(); - if (ctx.canPlace() && plant.is(Blocks.CHORUS_PLANT) && world.getBlockState(pos.below()).is(TagAPI.END_GROUND)) { - if (GeneratorOptions.changeChorusPlant()) { - info.setReturnValue(plant.setValue(VanillaBlockProperties.ROOTS, true).setValue(BlockStateProperties.DOWN, true)); - } - else { - info.setReturnValue(plant.setValue(BlockStateProperties.DOWN, true)); - } - info.cancel(); - } - } - - @Inject(method = "Lnet/minecraft/world/level/block/ChorusPlantBlock;getStateForPlacement" + - "(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)" + - "Lnet/minecraft/world/level/block/state/BlockState;", - at = @At("RETURN"), cancellable = true) - private void be_getStateForPlacement(BlockGetter blockGetter, BlockPos blockPos, CallbackInfoReturnable info) { - BlockState plant = info.getReturnValue(); - if (plant.is(Blocks.CHORUS_PLANT)) { - if (blockGetter.getBlockState(blockPos.below()).is(TagAPI.END_GROUND)) { - if (GeneratorOptions.changeChorusPlant()) { - info.setReturnValue(plant.setValue(BlockStateProperties.DOWN, true).setValue(VanillaBlockProperties.ROOTS, true)); - } - else { - info.setReturnValue(plant.setValue(BlockStateProperties.DOWN, true)); - } - info.cancel(); - } - else { - if (GeneratorOptions.changeChorusPlant()) { - info.setReturnValue(plant.setValue(VanillaBlockProperties.ROOTS, false)); - } - info.cancel(); - } - } - } - - @Inject(method = "canSurvive", at = @At("HEAD"), cancellable = true) - private void be_canSurvive(BlockState state, LevelReader world, BlockPos pos, CallbackInfoReturnable info) { - BlockState down = world.getBlockState(pos.below()); - if (down.is(EndBlocks.CHORUS_NYLIUM) || down.is(Blocks.END_STONE)) { - info.setReturnValue(true); - info.cancel(); - } - } - - @Inject(method = "updateShape", at = @At("RETURN"), cancellable = true) - private void be_updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom, CallbackInfoReturnable info) { - BlockState plant = info.getReturnValue(); - if (plant.is(Blocks.CHORUS_PLANT)) { - if (world.getBlockState(pos.below()).is(TagAPI.END_GROUND)) { - if (GeneratorOptions.changeChorusPlant()) { - plant = plant.setValue(BlockStateProperties.DOWN, true).setValue(VanillaBlockProperties.ROOTS, true); - } - else { - plant = plant.setValue(BlockStateProperties.DOWN, true); - } - info.cancel(); - } - else { - if (GeneratorOptions.changeChorusPlant()) { - plant = plant.setValue(VanillaBlockProperties.ROOTS, false); - } - info.cancel(); - } - info.setReturnValue(plant); - info.cancel(); - } - } -} diff --git a/src/main/java/ru/betterend/mixin/common/ChorusPlantFeatureMixin.java b/src/main/java/ru/betterend/mixin/common/ChorusPlantFeatureMixin.java deleted file mode 100644 index 044538ce..00000000 --- a/src/main/java/ru/betterend/mixin/common/ChorusPlantFeatureMixin.java +++ /dev/null @@ -1,43 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.Random; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.ChorusFlowerBlock; -import net.minecraft.world.level.block.PipeBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.ChorusPlantFeature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.blocks.VanillaBlockProperties; -import ru.betterend.registry.EndBlocks; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(ChorusPlantFeature.class) -public class ChorusPlantFeatureMixin { - @Inject(method = "place", at = @At("HEAD"), cancellable = true) - private void be_place(WorldGenLevel structureWorldAccess, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, NoneFeatureConfiguration defaultFeatureConfig, CallbackInfoReturnable info) { - if (structureWorldAccess.isEmptyBlock(blockPos) && structureWorldAccess.getBlockState(blockPos.below()).is(EndBlocks.CHORUS_NYLIUM)) { - ChorusFlowerBlock.generatePlant(structureWorldAccess, blockPos, random, MHelper.randRange(8, 16, random)); - BlockState bottom = structureWorldAccess.getBlockState(blockPos); - if (bottom.is(Blocks.CHORUS_PLANT)) { - if ((GeneratorOptions.changeChorusPlant())) { - BlocksHelper.setWithoutUpdate(structureWorldAccess, blockPos, bottom.setValue(VanillaBlockProperties.ROOTS, true).setValue(PipeBlock.DOWN, true)); - } - else { - BlocksHelper.setWithoutUpdate(structureWorldAccess, blockPos, bottom.setValue(PipeBlock.DOWN, true)); - } - } - info.setReturnValue(true); - } - } -} diff --git a/src/main/java/ru/betterend/mixin/common/ChunkBiomeContainerMixin.java b/src/main/java/ru/betterend/mixin/common/ChunkBiomeContainerMixin.java deleted file mode 100644 index 4ff99959..00000000 --- a/src/main/java/ru/betterend/mixin/common/ChunkBiomeContainerMixin.java +++ /dev/null @@ -1,120 +0,0 @@ -package ru.betterend.mixin.common; - -import java.lang.reflect.Field; - -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.core.BlockPos; -import net.minecraft.util.BitStorage; -import net.minecraft.util.Mth; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.chunk.ChunkBiomeContainer; -import ru.betterend.BetterEnd; -import ru.betterend.integration.Integrations; -import ru.betterend.interfaces.IBiomeArray; - -@Mixin(ChunkBiomeContainer.class) -public class ChunkBiomeContainerMixin implements IBiomeArray { - @Final - @Shadow - private Biome[] biomes; - - @Final - @Shadow - private static int WIDTH_BITS; - - @Final - @Shadow - public static int HORIZONTAL_MASK; - - @Final - @Shadow - public static int VERTICAL_MASK; - - @Override - public void be_setBiome(Biome biome, BlockPos pos) { - int biomeX = pos.getX() >> 2; - int biomeY = pos.getY() >> 2; - int biomeZ = pos.getZ() >> 2; - int index = be_getArrayIndex(biomeX, biomeY, biomeZ); - - if (Integrations.hasHydrogen()) { - try { - ChunkBiomeContainer self = (ChunkBiomeContainer) (Object) this; - BitStorage storage = be_getHydrogenStorage(self); - Biome[] palette = be_getHydrogenPalette(self); - int paletteIndex = be_getHydrogenPaletteIndex(biome, palette); - if (paletteIndex == -1) { - Biome[] newPalette = new Biome[palette.length + 1]; - System.arraycopy(palette, 0, newPalette, 0, palette.length); - paletteIndex = palette.length; - palette = newPalette; - palette[paletteIndex] = biome; - be_setHydrogenPalette(self, palette); - } - try { - storage.set(index, paletteIndex); - } - catch (Exception e) { - int size = storage.getSize(); - int bits = Mth.ceillog2(palette.length); - BitStorage newStorage = new BitStorage(bits, size); - for (int i = 0; i < size; i++) { - newStorage.set(i, storage.get(i)); - } - storage = newStorage; - storage.set(index, paletteIndex); - be_setHydrogenStorage(self, storage); - } - } - catch (Exception e) { - BetterEnd.LOGGER.warning(e.getLocalizedMessage()); - } - return; - } - - biomes[index] = biome; - } - - private int be_getArrayIndex(int biomeX, int biomeY, int biomeZ) { - int i = biomeX & HORIZONTAL_MASK; - int j = Mth.clamp(biomeY, 0, VERTICAL_MASK); - int k = biomeZ & HORIZONTAL_MASK; - return j << WIDTH_BITS + WIDTH_BITS | k << WIDTH_BITS | i; - } - - private Field be_getField(String name) throws Exception { - Field field = ChunkBiomeContainer.class.getDeclaredField(name); - field.setAccessible(true); - return field; - } - - private BitStorage be_getHydrogenStorage(ChunkBiomeContainer container) throws Exception { - return (BitStorage) be_getField("intArray").get(container); - } - - private Biome[] be_getHydrogenPalette(ChunkBiomeContainer container) throws Exception { - return (Biome[]) be_getField("palette").get(container); - } - - private int be_getHydrogenPaletteIndex(Biome biome, Biome[] palette) { - int index = -1; - for (int i = 0; i < palette.length; i++) { - if (palette[i] == biome) { - index = i; - break; - } - } - return index; - } - - private void be_setHydrogenPalette(ChunkBiomeContainer container, Biome[] palette) throws Exception { - be_getField("palette").set(container, palette); - } - - private void be_setHydrogenStorage(ChunkBiomeContainer container, BitStorage storage) throws Exception { - be_getField("intArray").set(container, storage); - } -} diff --git a/src/main/java/ru/betterend/mixin/common/ComposterBlockAccessor.java b/src/main/java/ru/betterend/mixin/common/ComposterBlockAccessor.java deleted file mode 100644 index 1d754b20..00000000 --- a/src/main/java/ru/betterend/mixin/common/ComposterBlockAccessor.java +++ /dev/null @@ -1,15 +0,0 @@ -package ru.betterend.mixin.common; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -import net.minecraft.world.level.ItemLike; -import net.minecraft.world.level.block.ComposterBlock; - -@Mixin(ComposterBlock.class) -public interface ComposterBlockAccessor { - @Invoker - static void callAdd(float levelIncreaseChance, ItemLike item) { - throw new AssertionError("@Invoker dummy body called"); - } -} diff --git a/src/main/java/ru/betterend/mixin/common/DimensionTypeMixin.java b/src/main/java/ru/betterend/mixin/common/DimensionTypeMixin.java deleted file mode 100644 index 5e0ac980..00000000 --- a/src/main/java/ru/betterend/mixin/common/DimensionTypeMixin.java +++ /dev/null @@ -1,31 +0,0 @@ -package ru.betterend.mixin.common; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.core.Registry; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.dimension.DimensionType; -import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; -import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; -import ru.betterend.world.generator.BetterEndBiomeSource; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(value = DimensionType.class, priority = 100) -public class DimensionTypeMixin { - @Inject(method = "defaultEndGenerator", at = @At("HEAD"), cancellable = true) - private static void be_replaceGenerator(Registry biomeRegistry, Registry chunkGeneratorSettingsRegistry, long seed, CallbackInfoReturnable info) { - info.setReturnValue(new NoiseBasedChunkGenerator(new BetterEndBiomeSource(biomeRegistry, seed), seed, - () -> chunkGeneratorSettingsRegistry.getOrThrow(NoiseGeneratorSettings.END))); - } - - @Inject(method = "createDragonFight", at = @At("HEAD"), cancellable = true) - private void be_hasEnderDragonFight(CallbackInfoReturnable info) { - if (!GeneratorOptions.hasDragonFights()) { - info.setReturnValue(false); - } - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/mixin/common/EnchantmentMenuMixin.java b/src/main/java/ru/betterend/mixin/common/EnchantmentMenuMixin.java deleted file mode 100644 index 3848fb27..00000000 --- a/src/main/java/ru/betterend/mixin/common/EnchantmentMenuMixin.java +++ /dev/null @@ -1,140 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.List; -import java.util.Random; - -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import net.minecraft.core.Registry; -import net.minecraft.world.Container; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.inventory.ContainerLevelAccess; -import net.minecraft.world.inventory.DataSlot; -import net.minecraft.world.inventory.EnchantmentMenu; -import net.minecraft.world.inventory.MenuType; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.EnchantmentInstance; -import ru.bclib.api.TagAPI; - -@Mixin(EnchantmentMenu.class) -public abstract class EnchantmentMenuMixin extends AbstractContainerMenu { - @Final - @Shadow - private Container enchantSlots; - - @Final - @Shadow - private ContainerLevelAccess access; - - @Final - @Shadow - private Random random; - - @Final - @Shadow - private DataSlot enchantmentSeed; - - @Shadow - @Final - public int[] costs; - - @Shadow - @Final - public int[] enchantClue; - - @Shadow - @Final - public int[] levelClue; - - protected EnchantmentMenuMixin(MenuType type, int syncId) { - super(type, syncId); - } - - @Inject(method = "slotsChanged", at = @At("HEAD"), cancellable = true) - private void be_slotsChanged(Container inventory, CallbackInfo info) { - if (inventory == this.enchantSlots) { - ItemStack itemStack = inventory.getItem(0); - if (!itemStack.isEmpty() && itemStack.isEnchantable()) { - this.access.execute((world, blockPos) -> { - int i = 0; - - int j; - for (j = -1; j <= 1; ++j) { - for (int k = -1; k <= 1; ++k) { - if ((j != 0 || k != 0) && world.isEmptyBlock(blockPos.offset(k, 0, j)) && world.isEmptyBlock(blockPos.offset(k, 1, j))) { - if (world.getBlockState(blockPos.offset(k * 2, 0, j * 2)).is(TagAPI.BOOKSHELVES)) { - ++i; - } - - if (world.getBlockState(blockPos.offset(k * 2, 1, j * 2)).is(TagAPI.BOOKSHELVES)) { - ++i; - } - - if (k != 0 && j != 0) { - if (world.getBlockState(blockPos.offset(k * 2, 0, j)).is(TagAPI.BOOKSHELVES)) { - ++i; - } - - if (world.getBlockState(blockPos.offset(k * 2, 1, j)).is(TagAPI.BOOKSHELVES)) { - ++i; - } - - if (world.getBlockState(blockPos.offset(k, 0, j * 2)).is(TagAPI.BOOKSHELVES)) { - ++i; - } - - if (world.getBlockState(blockPos.offset(k, 1, j * 2)).is(TagAPI.BOOKSHELVES)) { - ++i; - } - } - } - } - } - - random.setSeed(enchantmentSeed.get()); - - for (j = 0; j < 3; ++j) { - costs[j] = EnchantmentHelper.getEnchantmentCost(this.random, j, i, itemStack); - enchantClue[j] = -1; - levelClue[j] = -1; - if (costs[j] < j + 1) { - costs[j] = 0; - } - } - - for (j = 0; j < 3; ++j) { - if (this.costs[j] > 0) { - List list = this.getEnchantmentList(itemStack, j, this.costs[j]); - if (list != null && !list.isEmpty()) { - EnchantmentInstance enchantmentLevelEntry = (EnchantmentInstance) list.get(this.random.nextInt(list.size())); - enchantClue[j] = Registry.ENCHANTMENT.getId(enchantmentLevelEntry.enchantment); - levelClue[j] = enchantmentLevelEntry.level; - } - } - } - - broadcastChanges(); - }); - } - else { - for (int i = 0; i < 3; ++i) { - costs[i] = 0; - enchantClue[i] = -1; - levelClue[i] = -1; - } - } - info.cancel(); - } - } - - @Shadow - private List getEnchantmentList(ItemStack stack, int slot, int level) { - return null; - } -} diff --git a/src/main/java/ru/betterend/mixin/common/EndCityFeatureMixin.java b/src/main/java/ru/betterend/mixin/common/EndCityFeatureMixin.java deleted file mode 100644 index e91f8949..00000000 --- a/src/main/java/ru/betterend/mixin/common/EndCityFeatureMixin.java +++ /dev/null @@ -1,43 +0,0 @@ -package ru.betterend.mixin.common; - -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.WorldgenRandom; -import net.minecraft.world.level.levelgen.feature.EndCityFeature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(EndCityFeature.class) -public class EndCityFeatureMixin { - @Inject(method = "isFeatureChunk", at = @At("HEAD"), cancellable = true) - private void be_isFeatureChunk(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long l, WorldgenRandom chunkRandom, int i, int j, Biome biome, ChunkPos chunkPos, NoneFeatureConfiguration defaultFeatureConfig, CallbackInfoReturnable info) { - if (GeneratorOptions.useNewGenerator()) { - int chance = GeneratorOptions.getEndCityFailChance(); - if (chance == 0) { - info.setReturnValue(getYPositionForFeature(i, j, chunkGenerator) >= 60); - info.cancel(); - } - else if (chunkRandom.nextInt(chance) == 0){ - info.setReturnValue(getYPositionForFeature(i, j, chunkGenerator) >= 60); - info.cancel(); - } - else { - info.setReturnValue(false); - info.cancel(); - } - } - } - - @Shadow - private static int getYPositionForFeature(int chunkX, int chunkZ, ChunkGenerator chunkGenerator) { - return 0; - } -} diff --git a/src/main/java/ru/betterend/mixin/common/EndDragonFightMixin.java b/src/main/java/ru/betterend/mixin/common/EndDragonFightMixin.java deleted file mode 100644 index a4dc5b6a..00000000 --- a/src/main/java/ru/betterend/mixin/common/EndDragonFightMixin.java +++ /dev/null @@ -1,100 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.List; - -import org.apache.logging.log4j.Logger; -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.google.common.collect.Lists; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.boss.enderdragon.EndCrystal; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.pattern.BlockPattern; -import net.minecraft.world.level.dimension.end.DragonRespawnAnimation; -import net.minecraft.world.level.dimension.end.EndDragonFight; -import net.minecraft.world.phys.AABB; -import ru.bclib.util.BlocksHelper; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(EndDragonFight.class) -public class EndDragonFightMixin { - @Shadow - private DragonRespawnAnimation respawnStage; - @Shadow - private boolean dragonKilled; - @Shadow - private BlockPos portalLocation; - @Final - @Shadow - private static Logger LOGGER; - @Final - @Shadow - private ServerLevel level; - - @Shadow - private BlockPattern.BlockPatternMatch findExitPortal() { - return null; - } - - @Shadow - private void spawnExitPortal(boolean bl) {} - - @Shadow - private void respawnDragon(List list) {} - - @Inject(method = "tryRespawn", at = @At("HEAD"), cancellable = true) - private void be_tryRespawnDragon(CallbackInfo info) { - if (GeneratorOptions.replacePortal() && GeneratorOptions.hasDragonFights() && this.dragonKilled && this.respawnStage == null) { - BlockPos blockPos = portalLocation; - if (blockPos == null) { - LOGGER.debug("Tried to respawn, but need to find the portal first."); - BlockPattern.BlockPatternMatch blockPatternMatch = this.findExitPortal(); - if (blockPatternMatch == null) { - LOGGER.debug("Couldn't find a portal, so we made one."); - spawnExitPortal(true); - } - else { - LOGGER.debug("Found the exit portal & temporarily using it."); - } - - blockPos = portalLocation; - } - - List crystals = Lists.newArrayList(); - BlockPos center = GeneratorOptions.getPortalPos().above(5); - for (Direction dir : BlocksHelper.HORIZONTAL) { - BlockPos central = center.relative(dir, 4); - List crystalList = level.getEntitiesOfClass(EndCrystal.class, new AABB(central.below(10).south().west(), central.above(10).north().east())); - - int count = crystalList.size(); - for (int n = 0; n < count; n++) { - EndCrystal crystal = crystalList.get(n); - if (!level.getBlockState(crystal.blockPosition().below()).is(Blocks.BEDROCK)) { - crystalList.remove(n); - count--; - n--; - } - } - - if (crystalList.isEmpty()) { - info.cancel(); - return; - } - - crystals.addAll(crystalList); - } - - LOGGER.debug("Found all crystals, respawning dragon."); - respawnDragon(crystals); - info.cancel(); - } - } -} diff --git a/src/main/java/ru/betterend/mixin/common/EndPodiumFeatureMixin.java b/src/main/java/ru/betterend/mixin/common/EndPodiumFeatureMixin.java deleted file mode 100644 index 20c73a27..00000000 --- a/src/main/java/ru/betterend/mixin/common/EndPodiumFeatureMixin.java +++ /dev/null @@ -1,73 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.Random; - -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.ModifyVariable; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.feature.EndPodiumFeature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; -import ru.bclib.api.WorldDataAPI; -import ru.bclib.util.StructureHelper; -import ru.betterend.BetterEnd; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(EndPodiumFeature.class) -public class EndPodiumFeatureMixin { - @Final - @Shadow - private boolean active; - - @Inject(method = "place", at = @At("HEAD"), cancellable = true) - private void be_place(WorldGenLevel world, ChunkGenerator generator, Random random, BlockPos blockPos, NoneFeatureConfiguration config, CallbackInfoReturnable info) { - if (!GeneratorOptions.hasPortal()) { - info.setReturnValue(false); - info.cancel(); - } - else if (GeneratorOptions.replacePortal()) { - blockPos = be_updatePos(blockPos, world); - StructureTemplate structure = StructureHelper.readStructure(BetterEnd.makeID(active ? "portal/end_portal_active" : "portal/end_portal_inactive")); - BlockPos size = structure.getSize(); - blockPos = blockPos.offset(-(size.getX() >> 1), -1, -(size.getZ() >> 1)); - structure.placeInWorldChunk(world, blockPos, new StructurePlaceSettings(), random); - info.setReturnValue(true); - info.cancel(); - } - } - - @ModifyVariable(method = "place", ordinal = 0, at = @At("HEAD")) - private BlockPos be_setPosOnGround(BlockPos blockPos, WorldGenLevel world) { - return be_updatePos(blockPos, world); - } - - private BlockPos be_updatePos(BlockPos blockPos, WorldGenLevel world) { - if (GeneratorOptions.useNewGenerator()) { - BlockPos pos = GeneratorOptions.getPortalPos(); - if (pos.equals(BlockPos.ZERO)) { - int y = world.getChunk(0, 0, ChunkStatus.FULL).getHeight(Types.WORLD_SURFACE, blockPos.getX(), blockPos.getZ()); - if (y < 1) { - y = 65; - } - pos = new BlockPos(pos.getX(), y, pos.getZ()); - GeneratorOptions.setPortalPos(pos); - WorldDataAPI.getRootTag(BetterEnd.MOD_ID).put("portal", NbtUtils.writeBlockPos(pos)); - WorldDataAPI.saveFile(BetterEnd.MOD_ID); - } - return pos; - } - return blockPos; - } -} diff --git a/src/main/java/ru/betterend/mixin/common/EndSpikeMixin.java b/src/main/java/ru/betterend/mixin/common/EndSpikeMixin.java deleted file mode 100644 index 94361158..00000000 --- a/src/main/java/ru/betterend/mixin/common/EndSpikeMixin.java +++ /dev/null @@ -1,44 +0,0 @@ -package ru.betterend.mixin.common; - -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.levelgen.feature.SpikeFeature.EndSpike; -import ru.bclib.api.WorldDataAPI; -import ru.betterend.BetterEnd; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(EndSpike.class) -public class EndSpikeMixin { - @Final - @Shadow - private int height; - - @Inject(method = "getHeight", at = @At("HEAD"), cancellable = true) - private void be_getSpikeHeight(CallbackInfoReturnable info) { - if (!GeneratorOptions.isDirectSpikeHeight()) { - int x = getCenterX(); - int z = getCenterZ(); - String pillarID = String.format("%d_%d", x, z); - CompoundTag pillar = WorldDataAPI.getCompoundTag(BetterEnd.MOD_ID, "pillars"); - int minY = pillar.contains(pillarID) ? pillar.getInt(pillarID) : 65; - int maxY = minY + height - 54; - info.setReturnValue(maxY); - } - } - - @Shadow - public int getCenterX() { - return 0; - } - - @Shadow - public int getCenterZ() { - return 0; - } -} diff --git a/src/main/java/ru/betterend/mixin/common/EnderManMixin.java b/src/main/java/ru/betterend/mixin/common/EnderManMixin.java deleted file mode 100644 index 4102fef9..00000000 --- a/src/main/java/ru/betterend/mixin/common/EnderManMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package ru.betterend.mixin.common; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.monster.EnderMan; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import ru.betterend.effects.EndEnchantments; -import ru.betterend.effects.EndStatusEffects; - -@Mixin(EnderMan.class) -public abstract class EnderManMixin { - @Inject(method = "isLookingAtMe", at = @At("HEAD"), cancellable = true) - private void be_isLookingAtMe(Player player, CallbackInfoReturnable info) { - if (player.isCreative() || player.hasEffect(EndStatusEffects.END_VEIL) || - EnchantmentHelper.getItemEnchantmentLevel(EndEnchantments.END_VEIL, player.getItemBySlot(EquipmentSlot.HEAD)) > 0) { - info.setReturnValue(false); - } - } -} diff --git a/src/main/java/ru/betterend/mixin/common/EntityMixin.java b/src/main/java/ru/betterend/mixin/common/EntityMixin.java deleted file mode 100644 index 4f9372b8..00000000 --- a/src/main/java/ru/betterend/mixin/common/EntityMixin.java +++ /dev/null @@ -1,93 +0,0 @@ -package ru.betterend.mixin.common; - -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.portal.PortalInfo; -import net.minecraft.world.phys.Vec3; -import ru.betterend.interfaces.TeleportingEntity; - -@Mixin(Entity.class) -public abstract class EntityMixin implements TeleportingEntity { - @Shadow - public float yRot; - @Shadow - public float xRot; - @Shadow - public boolean removed; - @Shadow - public Level level; - - @Final - @Shadow - public abstract void unRide(); - - @Shadow - public abstract Vec3 getDeltaMovement(); - - @Shadow - public abstract EntityType getType(); - - @Shadow - protected abstract PortalInfo findDimensionEntryPoint(ServerLevel destination); - - private BlockPos exitPos; - - @Inject(method = "changeDimension", at = @At("HEAD"), cancellable = true) - public void be_changeDimension(ServerLevel destination, CallbackInfoReturnable info) { - if (!removed && be_canTeleport() && level instanceof ServerLevel) { - unRide(); - level.getProfiler().push("changeDimension"); - level.getProfiler().push("reposition"); - PortalInfo teleportTarget = findDimensionEntryPoint(destination); - if (teleportTarget != null) { - level.getProfiler().popPush("reloading"); - Entity entity = getType().create(destination); - if (entity != null) { - entity.restoreFrom(Entity.class.cast(this)); - entity.moveTo(teleportTarget.pos.x, teleportTarget.pos.y, teleportTarget.pos.z, teleportTarget.yRot, entity.xRot); - entity.setDeltaMovement(teleportTarget.speed); - destination.addFromAnotherDimension(entity); - } - removed = true; - level.getProfiler().pop(); - ((ServerLevel) level).resetEmptyTime(); - destination.resetEmptyTime(); - level.getProfiler().pop(); - be_resetExitPos(); - info.setReturnValue(entity); - } - } - } - - @Inject(method = "findDimensionEntryPoint", at = @At("HEAD"), cancellable = true) - protected void be_findDimensionEntryPoint(ServerLevel destination, CallbackInfoReturnable info) { - if (be_canTeleport()) { - info.setReturnValue(new PortalInfo(new Vec3(exitPos.getX() + 0.5, exitPos.getY(), exitPos.getZ() + 0.5), getDeltaMovement(), yRot, xRot)); - } - } - - @Override - public void be_setExitPos(BlockPos pos) { - this.exitPos = pos.immutable(); - } - - @Override - public void be_resetExitPos() { - this.exitPos = null; - } - - @Override - public boolean be_canTeleport() { - return this.exitPos != null; - } -} diff --git a/src/main/java/ru/betterend/mixin/common/LivingEntityMixin.java b/src/main/java/ru/betterend/mixin/common/LivingEntityMixin.java deleted file mode 100644 index b4e430d6..00000000 --- a/src/main/java/ru/betterend/mixin/common/LivingEntityMixin.java +++ /dev/null @@ -1,201 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.Collection; - -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.At.Shift; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.sounds.SoundEvent; -import net.minecraft.util.Mth; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.effect.MobEffect; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.effect.MobEffects; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.MoverType; -import net.minecraft.world.entity.ai.attributes.AttributeMap; -import net.minecraft.world.entity.ai.attributes.AttributeModifier; -import net.minecraft.world.entity.ai.attributes.AttributeSupplier; -import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.animal.FlyingAnimal; -import net.minecraft.world.item.ElytraItem; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.phys.Vec3; -import ru.betterend.interfaces.FallFlyingItem; -import ru.betterend.interfaces.MobEffectApplier; -import ru.betterend.item.CrystaliteArmor; -import ru.betterend.registry.EndAttributes; - -@Mixin(LivingEntity.class) -public abstract class LivingEntityMixin extends Entity { - - public LivingEntityMixin(EntityType entityType, Level level) { - super(entityType, level); - } - - @Shadow - protected int fallFlyTicks; - - @Shadow - public abstract boolean hasEffect(MobEffect mobEffect); - - @Shadow - public abstract ItemStack getItemBySlot(EquipmentSlot equipmentSlot); - - @Shadow - public abstract void calculateEntityAnimation(LivingEntity livingEntity, boolean b); - - @Shadow - protected abstract SoundEvent getFallDamageSound(int i); - - @Shadow - public abstract boolean isFallFlying(); - - @Shadow - public abstract AttributeMap getAttributes(); - - private Entity lastAttacker; - - @Inject(method = "createLivingAttributes", at = @At("RETURN"), cancellable = true) - private static void be_addLivingAttributes(CallbackInfoReturnable info) { - EndAttributes.addLivingEntityAttributes(info.getReturnValue()); - } - - @Inject(method = "tickEffects", at = @At("HEAD")) - protected void be_applyEffects(CallbackInfo info) { - if (!level.isClientSide()) { - LivingEntity owner = LivingEntity.class.cast(this); - if (CrystaliteArmor.hasFullSet(owner)) { - CrystaliteArmor.applySetEffect(owner); - } - getArmorSlots().forEach(itemStack -> { - if (itemStack.getItem() instanceof MobEffectApplier) { - ((MobEffectApplier) itemStack.getItem()).applyEffect(owner); - } - }); - } - } - - @Inject(method = "canBeAffected", at = @At("HEAD"), cancellable = true) - public void be_canBeAffected(MobEffectInstance mobEffectInstance, CallbackInfoReturnable info) { - if (mobEffectInstance.getEffect() == MobEffects.BLINDNESS && getAttributes().getValue(EndAttributes.BLINDNESS_RESISTANCE) > 0.0) { - info.setReturnValue(false); - } - } - - @Inject(method = "hurt", at = @At("HEAD")) - public void be_hurt(DamageSource source, float amount, CallbackInfoReturnable info) { - this.lastAttacker = source.getEntity(); - } - - @ModifyArg(method = "hurt", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;knockback(FDD)V")) - private float be_increaseKnockback(float value, double x, double z) { - if (lastAttacker != null && lastAttacker instanceof LivingEntity) { - LivingEntity attacker = (LivingEntity) lastAttacker; - value += this.be_getKnockback(attacker.getMainHandItem().getItem()); - } - return value; - } - - @Inject(method = "updateFallFlying", at = @At("HEAD"), cancellable = true) - private void be_updateFallFlying(CallbackInfo info) { - ItemStack itemStack = getItemBySlot(EquipmentSlot.CHEST); - if (!level.isClientSide && itemStack.getItem() instanceof FallFlyingItem) { - boolean isFlying = getSharedFlag(7); - if (isFlying && !onGround && !isPassenger() && !hasEffect(MobEffects.LEVITATION)) { - if (ElytraItem.isFlyEnabled(itemStack)) { - if ((fallFlyTicks + 1) % 20 == 0) { - itemStack.hurtAndBreak(1, LivingEntity.class.cast(this), - livingEntity -> livingEntity.broadcastBreakEvent(EquipmentSlot.CHEST)); - } - isFlying = true; - } else { - isFlying = false; - } - } else { - isFlying = false; - } - setSharedFlag(7, isFlying); - info.cancel(); - } - } - - @Inject(method = "travel", at = @At(value = "INVOKE", - target = "Lnet/minecraft/world/entity/LivingEntity;isFallFlying()Z", - shift = Shift.AFTER), cancellable = true) - public void be_travel(Vec3 vec3, CallbackInfo info) { - ItemStack itemStack = getItemBySlot(EquipmentSlot.CHEST); - if (isFallFlying() && itemStack.getItem() instanceof FallFlyingItem) { - Vec3 moveDelta = getDeltaMovement(); - if (moveDelta.y > -0.5D) { - fallDistance = 1.0F; - } - - Vec3 lookAngle = getLookAngle(); - double d = 0.08D; - float rotX = xRot * 0.017453292F; - double k = Math.sqrt(lookAngle.x * lookAngle.x + lookAngle.z * lookAngle.z); - double l = Math.sqrt(getHorizontalDistanceSqr(moveDelta)); - double lookLen = lookAngle.length(); - float n = Mth.cos(rotX); - n = (float) (n * n * Math.min(1.0D, lookLen / 0.4D)); - moveDelta = getDeltaMovement().add(0.0D, d * (-1.0D + (double) n * 0.75D), 0.0D); - double coef; - if (moveDelta.y < 0.0D && k > 0.0D) { - coef = moveDelta.y * -0.1D * (double) n; - moveDelta = moveDelta.add(lookAngle.x * coef / k, coef, lookAngle.z * coef / k); - } - - if (rotX < 0.0F && k > 0.0D) { - coef = l * (double) (-Mth.sin(rotX)) * 0.04D; - moveDelta = moveDelta.add(-lookAngle.x * coef / k, coef * 3.2D, -lookAngle.z * coef / k); - } - - if (k > 0.0D) { - moveDelta = moveDelta.add((lookAngle.x / k * l - moveDelta.x) * 0.1D, 0.0D, (lookAngle.z / k * l - moveDelta.z) * 0.1D); - } - moveDelta = moveDelta.multiply(0.9900000095367432D, 0.9800000190734863D, 0.9900000095367432D); - double movementFactor = ((FallFlyingItem) itemStack.getItem()).getMovementFactor(); - moveDelta = moveDelta.multiply(movementFactor, 1.0D, movementFactor); - setDeltaMovement(moveDelta); - move(MoverType.SELF, moveDelta); - if (!level.isClientSide) { - if (horizontalCollision) { - coef = Math.sqrt(getHorizontalDistanceSqr(moveDelta)); - double r = l - coef; - float dmg = (float) (r * 10.0D - 3.0D); - if (dmg > 0.0F) { - playSound(getFallDamageSound((int) dmg), 1.0F, 1.0F); - hurt(DamageSource.FLY_INTO_WALL, dmg); - } - } - if (onGround) { - setSharedFlag(7, false); - } - } - - calculateEntityAnimation(LivingEntity.class.cast(this), this instanceof FlyingAnimal); - info.cancel(); - } - } - - private double be_getKnockback(Item tool) { - if (tool == null) return 0.0D; - Collection modifiers = tool.getDefaultAttributeModifiers(EquipmentSlot.MAINHAND).get(Attributes.ATTACK_KNOCKBACK); - if (modifiers.size() > 0) { - return modifiers.iterator().next().getAmount(); - } - return 0.0D; - } -} diff --git a/src/main/java/ru/betterend/mixin/common/MinecraftServerMixin.java b/src/main/java/ru/betterend/mixin/common/MinecraftServerMixin.java deleted file mode 100644 index 1c3d5f0a..00000000 --- a/src/main/java/ru/betterend/mixin/common/MinecraftServerMixin.java +++ /dev/null @@ -1,78 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.Map; - -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.ServerResources; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.server.players.PlayerList; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.storage.ServerLevelData; -import net.minecraft.world.level.storage.WorldData; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(MinecraftServer.class) -public class MinecraftServerMixin { - @Shadow - private ServerResources resources; - - @Final - @Shadow - private Map, ServerLevel> levels; - - @Final - @Shadow - protected WorldData worldData; - - @Inject(method = "overworld", at = @At(value = "HEAD"), cancellable = true) - private final void be_overworld(CallbackInfoReturnable info) { - if (GeneratorOptions.swapOverworldToEnd()) { - ServerLevel world = levels.get(Level.END); - if (world == null) { - world = levels.get(Level.OVERWORLD); - } - info.setReturnValue(world); - info.cancel(); - } - } - - @Inject(method = "createLevels", at = @At(value = "TAIL")) - private final void be_createLevels(ChunkProgressListener worldGenerationProgressListener, CallbackInfo info) { - if (GeneratorOptions.swapOverworldToEnd()) { - ServerLevel world = levels.get(Level.END); - if (world == null) { - world = levels.get(Level.OVERWORLD); - } - this.getPlayerList().setLevel(world); - ServerLevelData serverWorldProperties = worldData.overworldData(); - net.minecraft.world.level.levelgen.WorldGenSettings generatorOptions = worldData.worldGenSettings(); - boolean bl = generatorOptions.isDebug(); - setInitialSpawn(world, serverWorldProperties, generatorOptions.generateBonusChest(), bl, true); - } - } - - @Inject(method = "setInitialSpawn", at = @At(value = "HEAD"), cancellable = true) - private static void be_setInitialSpawn(ServerLevel world, ServerLevelData serverWorldProperties, boolean bonusChest, boolean debugWorld, boolean bl, CallbackInfo info) { - if (GeneratorOptions.swapOverworldToEnd() && world.dimension() == Level.OVERWORLD) { - info.cancel(); - } - } - - @Shadow - private static void setInitialSpawn(ServerLevel world, ServerLevelData serverWorldProperties, boolean bonusChest, boolean debugWorld, boolean bl) {} - - @Shadow - public PlayerList getPlayerList() { - return null; - } -} diff --git a/src/main/java/ru/betterend/mixin/common/MonsterMixin.java b/src/main/java/ru/betterend/mixin/common/MonsterMixin.java deleted file mode 100644 index b2d77c7c..00000000 --- a/src/main/java/ru/betterend/mixin/common/MonsterMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.List; -import java.util.Random; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.MobSpawnType; -import net.minecraft.world.entity.monster.EnderMan; -import net.minecraft.world.entity.monster.Monster; -import net.minecraft.world.level.ServerLevelAccessor; -import net.minecraft.world.phys.AABB; - -@Mixin(Monster.class) -public class MonsterMixin { - @Inject(method = "checkMonsterSpawnRules", at = @At(value = "RETURN"), cancellable = true) - private static void be_checkMonsterSpawnRules(EntityType type, ServerLevelAccessor serverWorldAccess, MobSpawnType spawnReason, BlockPos pos, Random random, CallbackInfoReturnable info) { - boolean canSpawn = info.getReturnValue(); - if (canSpawn && spawnReason == MobSpawnType.NATURAL && type == EntityType.ENDERMAN) { - AABB box = new AABB(pos).inflate(16); - List entities = serverWorldAccess.getEntitiesOfClass(EnderMan.class, box, (entity) -> { return true; }); - info.setReturnValue(entities.size() < 6); - } - } -} diff --git a/src/main/java/ru/betterend/mixin/common/NoiseBasedChunkGeneratorMixin.java b/src/main/java/ru/betterend/mixin/common/NoiseBasedChunkGeneratorMixin.java deleted file mode 100644 index 8d59913e..00000000 --- a/src/main/java/ru/betterend/mixin/common/NoiseBasedChunkGeneratorMixin.java +++ /dev/null @@ -1,42 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.function.Supplier; - -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; -import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; -import net.minecraft.world.level.levelgen.StructureSettings; -import ru.betterend.world.generator.GeneratorOptions; -import ru.betterend.world.generator.TerrainGenerator; - -@Mixin(NoiseBasedChunkGenerator.class) -public abstract class NoiseBasedChunkGeneratorMixin extends ChunkGenerator { - @Final - @Shadow - protected Supplier settings; - - public NoiseBasedChunkGeneratorMixin(BiomeSource populationSource, BiomeSource biomeSource, StructureSettings structuresConfig, long worldSeed) { - super(populationSource, biomeSource, structuresConfig, worldSeed); - } - - @Inject(method = "(Lnet/minecraft/world/level/biome/BiomeSource;Lnet/minecraft/world/level/biome/BiomeSource;JLjava/util/function/Supplier;)V", at = @At("TAIL")) - private void beOnInit(BiomeSource populationSource, BiomeSource biomeSource, long seed, Supplier settings, CallbackInfo info) { - TerrainGenerator.initNoise(seed); - } - - @Inject(method = "fillNoiseColumn([DII)V", at = @At("HEAD"), cancellable = true, allow = 2) - private void be_fillNoiseColumn(double[] buffer, int x, int z, CallbackInfo info) { - if (GeneratorOptions.useNewGenerator() && settings.get().stable(NoiseGeneratorSettings.END)) { - TerrainGenerator.fillTerrainDensity(buffer, x, z, getBiomeSource()); - info.cancel(); - } - } -} diff --git a/src/main/java/ru/betterend/mixin/common/PlayerAdvancementsMixin.java b/src/main/java/ru/betterend/mixin/common/PlayerAdvancementsMixin.java deleted file mode 100644 index 6ddf6f04..00000000 --- a/src/main/java/ru/betterend/mixin/common/PlayerAdvancementsMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package ru.betterend.mixin.common; - -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.At.Shift; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.advancements.Advancement; -import net.minecraft.server.PlayerAdvancements; -import net.minecraft.server.level.ServerPlayer; -import ru.betterend.events.PlayerAdvancementsCallback; - -@Mixin(PlayerAdvancements.class) -public abstract class PlayerAdvancementsMixin { - @Shadow - private ServerPlayer player; - - @Inject(method = "award", at = @At( - value = "INVOKE", - target = "Lnet/minecraft/advancements/AdvancementRewards;grant(Lnet/minecraft/server/level/ServerPlayer;)V", - shift = Shift.AFTER)) - public void be_award(Advancement advancement, String criterionName, CallbackInfoReturnable info) { - PlayerAdvancementsCallback.PLAYER_ADVANCEMENT_COMPLETE.invoker().onAdvancementComplete(player, advancement, criterionName); - } -} diff --git a/src/main/java/ru/betterend/mixin/common/PlayerListMixin.java b/src/main/java/ru/betterend/mixin/common/PlayerListMixin.java deleted file mode 100644 index 408fb3fa..00000000 --- a/src/main/java/ru/betterend/mixin/common/PlayerListMixin.java +++ /dev/null @@ -1,258 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.mojang.authlib.GameProfile; -import com.mojang.serialization.DataResult; -import com.mojang.serialization.Dynamic; - -import io.netty.buffer.Unpooled; -import net.minecraft.ChatFormatting; -import net.minecraft.Util; -import net.minecraft.core.RegistryAccess; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtOps; -import net.minecraft.nbt.Tag; -import net.minecraft.network.Connection; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.chat.ChatType; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket; -import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket; -import net.minecraft.network.protocol.game.ClientboundLoginPacket; -import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket; -import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket; -import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket; -import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket; -import net.minecraft.network.protocol.game.ClientboundUpdateRecipesPacket; -import net.minecraft.network.protocol.game.ClientboundUpdateTagsPacket; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.ServerScoreboard; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import net.minecraft.server.players.GameProfileCache; -import net.minecraft.server.players.PlayerList; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.GameRules; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.dimension.DimensionType; -import net.minecraft.world.level.storage.LevelData; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(PlayerList.class) -public class PlayerListMixin { - @Final - @Shadow - private static Logger LOGGER; - - @Final - @Shadow - private MinecraftServer server; - - @Final - @Shadow - private RegistryAccess.RegistryHolder registryHolder; - - @Shadow - private int viewDistance; - - @Final - @Shadow - private List players; - - @Final - @Shadow - private Map playersByUUID; - - @Inject(method = "placeNewPlayer", at = @At(value = "HEAD"), cancellable = true) - public void be_placeNewPlayer(Connection connection, ServerPlayer player, CallbackInfo info) { - if (GeneratorOptions.swapOverworldToEnd()) { - GameProfile gameProfile = player.getGameProfile(); - GameProfileCache userCache = this.server.getProfileCache(); - GameProfile gameProfile2 = userCache.get(gameProfile.getId()); - String string = gameProfile2 == null ? gameProfile.getName() : gameProfile2.getName(); - userCache.add(gameProfile); - CompoundTag compoundTag = this.load(player); - ResourceKey var23; - if (compoundTag != null) { - DataResult> var10000 = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, compoundTag.get("Dimension"))); - Logger var10001 = LOGGER; - var10001.getClass(); - var23 = (ResourceKey) var10000.resultOrPartial(var10001::error).orElse(Level.END); - } - else { - var23 = Level.END; - } - - ResourceKey registryKey = var23; - ServerLevel serverWorld = this.server.getLevel(registryKey); - ServerLevel serverWorld3; - if (serverWorld == null) { - LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", registryKey); - serverWorld3 = this.server.overworld(); - } - else { - serverWorld3 = serverWorld; - } - - player.setLevel(serverWorld3); - player.gameMode.setLevel((ServerLevel) player.level); - String string2 = "local"; - if (connection.getRemoteAddress() != null) { - string2 = connection.getRemoteAddress().toString(); - } - - LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", player.getName().getString(), string2, player.getId(), player.getX(), player.getY(), player.getZ()); - LevelData worldProperties = serverWorld3.getLevelData(); - this.updatePlayerGameMode(player, (ServerPlayer) null, serverWorld3); - ServerGamePacketListenerImpl serverPlayNetworkHandler = new ServerGamePacketListenerImpl(this.server, connection, player); - GameRules gameRules = serverWorld3.getGameRules(); - boolean bl = gameRules.getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN); - boolean bl2 = gameRules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO); - serverPlayNetworkHandler.send(new ClientboundLoginPacket(player.getId(), player.gameMode.getGameModeForPlayer(), player.gameMode.getPreviousGameModeForPlayer(), BiomeManager.obfuscateSeed(serverWorld3.getSeed()), - worldProperties.isHardcore(), this.server.levelKeys(), this.registryHolder, serverWorld3.dimensionType(), serverWorld3.dimension(), this.getPlayerCount(), this.viewDistance, bl2, !bl, - serverWorld3.isDebug(), serverWorld3.isFlat())); - serverPlayNetworkHandler.send(new ClientboundCustomPayloadPacket(ClientboundCustomPayloadPacket.BRAND, (new FriendlyByteBuf(Unpooled.buffer())).writeUtf(this.getServer().getServerModName()))); - serverPlayNetworkHandler.send(new ClientboundChangeDifficultyPacket(worldProperties.getDifficulty(), worldProperties.isDifficultyLocked())); - serverPlayNetworkHandler.send(new ClientboundPlayerAbilitiesPacket(player.abilities)); - serverPlayNetworkHandler.send(new ClientboundSetCarriedItemPacket(player.inventory.selected)); - serverPlayNetworkHandler.send(new ClientboundUpdateRecipesPacket(this.server.getRecipeManager().getRecipes())); - serverPlayNetworkHandler.send(new ClientboundUpdateTagsPacket(this.server.getTags())); - this.sendPlayerPermissionLevel(player); - player.getStats().markAllDirty(); - player.getRecipeBook().sendInitialRecipeBook(player); - this.updateEntireScoreboard(serverWorld3.getScoreboard(), player); - this.server.invalidateStatus(); - TranslatableComponent mutableText2; - if (player.getGameProfile().getName().equalsIgnoreCase(string)) { - mutableText2 = new TranslatableComponent("multiplayer.player.joined", new Object[] { player.getDisplayName() }); - } - else { - mutableText2 = new TranslatableComponent("multiplayer.player.joined.renamed", new Object[] { player.getDisplayName(), string }); - } - - this.broadcastMessage(mutableText2.withStyle(ChatFormatting.YELLOW), ChatType.SYSTEM, Util.NIL_UUID); - serverPlayNetworkHandler.teleport(player.getX(), player.getY(), player.getZ(), player.yRot, player.xRot); - this.players.add(player); - this.playersByUUID.put(player.getUUID(), player); - this.broadcastAll(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { player })); - - for (int i = 0; i < this.players.size(); ++i) { - player.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { (ServerPlayer) this.players.get(i) })); - } - - serverWorld3.addNewPlayer(player); - this.server.getCustomBossEvents().onPlayerConnect(player); - this.sendLevelInfo(player, serverWorld3); - if (!this.server.getResourcePack().isEmpty()) { - player.sendTexturePack(this.server.getResourcePack(), this.server.getResourcePackHash()); - } - - Iterator var24 = player.getActiveEffects().iterator(); - - while (var24.hasNext()) { - MobEffectInstance statusEffectInstance = (MobEffectInstance) var24.next(); - serverPlayNetworkHandler.send(new ClientboundUpdateMobEffectPacket(player.getId(), statusEffectInstance)); - } - - if (compoundTag != null && compoundTag.contains("RootVehicle", 10)) { - CompoundTag compoundTag2 = compoundTag.getCompound("RootVehicle"); - Entity entity = EntityType.loadEntityRecursive(compoundTag2.getCompound("Entity"), serverWorld3, (vehicle) -> { - return !serverWorld3.addWithUUID(vehicle) ? null : vehicle; - }); - if (entity != null) { - UUID uUID2; - if (compoundTag2.hasUUID("Attach")) { - uUID2 = compoundTag2.getUUID("Attach"); - } - else { - uUID2 = null; - } - - Iterator var21; - Entity entity3; - if (entity.getUUID().equals(uUID2)) { - player.startRiding(entity, true); - } - else { - var21 = entity.getIndirectPassengers().iterator(); - - while (var21.hasNext()) { - entity3 = (Entity) var21.next(); - if (entity3.getUUID().equals(uUID2)) { - player.startRiding(entity3, true); - break; - } - } - } - - if (!player.isPassenger()) { - LOGGER.warn("Couldn't reattach entity to player"); - serverWorld3.despawn(entity); - var21 = entity.getIndirectPassengers().iterator(); - - while (var21.hasNext()) { - entity3 = (Entity) var21.next(); - serverWorld3.despawn(entity3); - } - } - } - } - - player.initMenu(); - info.cancel(); - } - } - - @Shadow - public CompoundTag load(ServerPlayer player) { - return null; - } - - @Shadow - private void updatePlayerGameMode(ServerPlayer player, @Nullable ServerPlayer oldPlayer, ServerLevel world) {} - - @Shadow - public void sendPlayerPermissionLevel(ServerPlayer player) {} - - @Shadow - public int getPlayerCount() { - return 0; - } - - @Shadow - public MinecraftServer getServer() { - return null; - } - - @Shadow - protected void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) {} - - @Shadow - public void broadcastMessage(Component message, ChatType type, UUID senderUuid) {} - - @Shadow - public void broadcastAll(Packet packet) {} - - @Shadow - public void sendLevelInfo(ServerPlayer player, ServerLevel world) {} -} diff --git a/src/main/java/ru/betterend/mixin/common/PlayerMixin.java b/src/main/java/ru/betterend/mixin/common/PlayerMixin.java deleted file mode 100644 index e8ee2a4c..00000000 --- a/src/main/java/ru/betterend/mixin/common/PlayerMixin.java +++ /dev/null @@ -1,79 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.Optional; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.effect.MobEffects; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ElytraItem; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.Vec3; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.interfaces.FallFlyingItem; -import ru.betterend.registry.EndBlocks; - -@Mixin(Player.class) -public abstract class PlayerMixin extends LivingEntity { - - protected PlayerMixin(EntityType entityType, Level level) { - super(entityType, level); - } - - private static Direction[] horizontal; - - @Inject(method = "findRespawnPositionAndUseSpawnBlock", at = @At(value = "HEAD"), cancellable = true) - private static void be_findRespawnPositionAndUseSpawnBlock(ServerLevel world, BlockPos pos, float f, boolean bl, boolean bl2, CallbackInfoReturnable> info) { - BlockState blockState = world.getBlockState(pos); - if (blockState.is(EndBlocks.RESPAWN_OBELISK)) { - info.setReturnValue(be_obeliskRespawnPosition(world, pos, blockState)); - info.cancel(); - } - } - - @Inject(method = "tryToStartFallFlying", at = @At("HEAD"), cancellable = true) - public void be_tryToStartFlying(CallbackInfoReturnable info) { - if (!onGround && !isFallFlying() && !isInWater() && !hasEffect(MobEffects.LEVITATION)) { - ItemStack itemStack = getItemBySlot(EquipmentSlot.CHEST); - if (itemStack.getItem() instanceof FallFlyingItem && ElytraItem.isFlyEnabled(itemStack)) { - setSharedFlag(7, true); - info.setReturnValue(true); - } - } - } - - private static Optional be_obeliskRespawnPosition(ServerLevel world, BlockPos pos, BlockState state) { - if (state.getValue(BlockProperties.TRIPLE_SHAPE) == TripleShape.TOP) { - pos = pos.below(2); - } - else if (state.getValue(BlockProperties.TRIPLE_SHAPE) == TripleShape.MIDDLE) { - pos = pos.below(); - } - if (horizontal == null) { - horizontal = BlocksHelper.makeHorizontal(); - } - MHelper.shuffle(horizontal, world.getRandom()); - for (Direction dir: horizontal) { - BlockPos p = pos.relative(dir); - BlockState state2 = world.getBlockState(p); - if (!state2.getMaterial().blocksMotion() && state2.getCollisionShape(world, pos).isEmpty()) { - return Optional.of(Vec3.atLowerCornerOf(p).add(0.5, 0, 0.5)); - } - } - return Optional.empty(); - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/mixin/common/PotionBrewingAccessor.java b/src/main/java/ru/betterend/mixin/common/PotionBrewingAccessor.java deleted file mode 100644 index 49366687..00000000 --- a/src/main/java/ru/betterend/mixin/common/PotionBrewingAccessor.java +++ /dev/null @@ -1,16 +0,0 @@ -package ru.betterend.mixin.common; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -import net.minecraft.world.item.Item; -import net.minecraft.world.item.alchemy.Potion; -import net.minecraft.world.item.alchemy.PotionBrewing; - -@Mixin(PotionBrewing.class) -public interface PotionBrewingAccessor { - @Invoker - static void callAddMix(Potion input, Item item, Potion output) { - throw new AssertionError("@Invoker dummy body called"); - } -} diff --git a/src/main/java/ru/betterend/mixin/common/ServerLevelMixin.java b/src/main/java/ru/betterend/mixin/common/ServerLevelMixin.java deleted file mode 100644 index ce71752f..00000000 --- a/src/main/java/ru/betterend/mixin/common/ServerLevelMixin.java +++ /dev/null @@ -1,81 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.List; -import java.util.concurrent.Executor; -import java.util.function.Supplier; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.util.profiling.ProfilerFiller; -import net.minecraft.world.level.CustomSpawner; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.dimension.DimensionType; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraft.world.level.storage.ServerLevelData; -import net.minecraft.world.level.storage.WritableLevelData; -import ru.bclib.api.BiomeAPI; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBiomes; -import ru.betterend.registry.EndBlocks; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(ServerLevel.class) -public abstract class ServerLevelMixin extends Level { - private static String be_lastWorld = null; - - protected ServerLevelMixin(WritableLevelData writableLevelData, ResourceKey resourceKey, DimensionType dimensionType, Supplier supplier, boolean bl, boolean bl2, long l) { - super(writableLevelData, resourceKey, dimensionType, supplier, bl, bl2, l); - } - - @Inject(method = "*", at = @At("TAIL")) - private void be_onServerWorldInit(MinecraftServer server, Executor workerExecutor, LevelStorageSource.LevelStorageAccess session, ServerLevelData properties, ResourceKey registryKey, DimensionType dimensionType, ChunkProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List list, boolean bl, CallbackInfo info) { - if (be_lastWorld != null && be_lastWorld.equals(session.getLevelId())) { - return; - } - - be_lastWorld = session.getLevelId(); - ServerLevel world = ServerLevel.class.cast(this); - EndBiomes.onWorldLoad(world.getSeed()); - } - - @Inject(method = "getSharedSpawnPos", at = @At("HEAD"), cancellable = true) - private void be_getSharedSpawnPos(CallbackInfoReturnable info) { - if (GeneratorOptions.changeSpawn()) { - if (ServerLevel.class.cast(this).dimension() == Level.END) { - info.setReturnValue(GeneratorOptions.getSpawn()); - info.cancel(); - } - } - } - - @ModifyArg( - method = "tickChunk", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/level/ServerLevel;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z" - ) - ) - private BlockState be_modifyTickState(BlockPos pos, BlockState state) { - if (state.is(Blocks.ICE)) { - ResourceLocation biome = BiomeAPI.getBiomeID(getBiome(pos)); - if (biome.getNamespace().equals(BetterEnd.MOD_ID)) { - state = EndBlocks.EMERALD_ICE.defaultBlockState(); - } - } - return state; - } -} diff --git a/src/main/java/ru/betterend/mixin/common/ServerPlayerMixin.java b/src/main/java/ru/betterend/mixin/common/ServerPlayerMixin.java deleted file mode 100644 index 1f85de89..00000000 --- a/src/main/java/ru/betterend/mixin/common/ServerPlayerMixin.java +++ /dev/null @@ -1,158 +0,0 @@ -package ru.betterend.mixin.common; - -import org.spongepowered.asm.mixin.Final; -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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import com.mojang.authlib.GameProfile; - -import net.minecraft.core.BlockPos; -import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket; -import net.minecraft.network.protocol.game.ClientboundLevelEventPacket; -import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket; -import net.minecraft.network.protocol.game.ClientboundRespawnPacket; -import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.level.ServerPlayerGameMode; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import net.minecraft.server.players.PlayerList; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.portal.PortalInfo; -import net.minecraft.world.level.storage.LevelData; -import net.minecraft.world.phys.Vec3; -import ru.betterend.interfaces.TeleportingEntity; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(ServerPlayer.class) -public abstract class ServerPlayerMixin extends Player implements TeleportingEntity { - @Shadow - public ServerGamePacketListenerImpl connection; - @Final - @Shadow - public ServerPlayerGameMode gameMode; - @Final - @Shadow - public MinecraftServer server; - @Shadow - private boolean isChangingDimension; - @Shadow - private float lastSentHealth; - @Shadow - private int lastSentFood; - @Shadow - private int lastSentExp; - - private BlockPos exitPos; - private int be_teleportDelay = 0; - - public ServerPlayerMixin(Level world, BlockPos pos, float yaw, GameProfile profile) { - super(world, pos, yaw, profile); - } - - @Inject(method = "createEndPlatform", at = @At("HEAD"), cancellable = true) - private void be_createEndSpawnPlatform(ServerLevel world, BlockPos centerPos, CallbackInfo info) { - if (!GeneratorOptions.generateObsidianPlatform()) { - info.cancel(); - } - } - - @Inject(method = "findDimensionEntryPoint", at = @At("HEAD"), cancellable = true) - protected void be_getTeleportTarget(ServerLevel destination, CallbackInfoReturnable info) { - if (be_canTeleport()) { - info.setReturnValue(new PortalInfo(new Vec3(exitPos.getX() + 0.5, exitPos.getY(), exitPos.getZ() + 0.5), getDeltaMovement(), yRot, xRot)); - } - } - - @Inject(method = "changeDimension", at = @At("HEAD"), cancellable = true) - public void be_changeDimension(ServerLevel destination, CallbackInfoReturnable info) { - if (be_canTeleport() && level instanceof ServerLevel) { - isChangingDimension = true; - ServerLevel serverWorld = getLevel(); - LevelData worldProperties = destination.getLevelData(); - ServerPlayer player = ServerPlayer.class.cast(this); - connection.send(new ClientboundRespawnPacket(destination.dimensionType(), destination.dimension(), BiomeManager.obfuscateSeed(destination.getSeed()), - gameMode.getGameModeForPlayer(),gameMode.getPreviousGameModeForPlayer(), destination.isDebug(), destination.isFlat(), true)); - connection.send(new ClientboundChangeDifficultyPacket(worldProperties.getDifficulty(), worldProperties.isDifficultyLocked())); - PlayerList playerManager = server.getPlayerList(); - playerManager.sendPlayerPermissionLevel(player); - serverWorld.removePlayerImmediately(player); - removed = false; - PortalInfo teleportTarget = findDimensionEntryPoint(destination); - if (teleportTarget != null) { - serverWorld.getProfiler().push("moving"); - serverWorld.getProfiler().pop(); - serverWorld.getProfiler().push("placing"); - setLevel(destination); - destination.addDuringPortalTeleport(player); - setRot(teleportTarget.yRot, teleportTarget.xRot); - moveTo(teleportTarget.pos.x, teleportTarget.pos.y, teleportTarget.pos.z); - serverWorld.getProfiler().pop(); - triggerDimensionChangeTriggers(serverWorld); - gameMode.setLevel(destination); - connection.send(new ClientboundPlayerAbilitiesPacket(abilities)); - playerManager.sendLevelInfo(player, destination); - playerManager.sendAllPlayerInfo(player); - - for (MobEffectInstance statusEffectInstance : getActiveEffects()) { - connection.send(new ClientboundUpdateMobEffectPacket(getId(), statusEffectInstance)); - } - - connection.send(new ClientboundLevelEventPacket(1032, BlockPos.ZERO, 0, false)); - lastSentExp = -1; - lastSentHealth = -1.0F; - lastSentFood = -1; - } - be_teleportDelay = 100; - be_resetExitPos(); - info.setReturnValue(player); - } - } - - @Inject(method = "tick", at = @At("TAIL")) - public void be_decreaseCooldawn(CallbackInfo info) { - if (be_teleportDelay > 0) be_teleportDelay--; - } - - @Override - public int getDimensionChangingDelay() { - if (be_teleportDelay > 0) { - return be_teleportDelay; - } - return super.getDimensionChangingDelay(); - } - - @Shadow - abstract ServerLevel getLevel(); - - @Shadow - abstract void triggerDimensionChangeTriggers(ServerLevel origin); - - @Shadow - @Override - protected abstract PortalInfo findDimensionEntryPoint(ServerLevel destination); - - @Override - public void be_setExitPos(BlockPos pos) { - this.exitPos = pos.immutable(); - } - - @Override - public void be_resetExitPos() { - this.exitPos = null; - } - - @Override - public boolean be_canTeleport() { - return this.exitPos != null; - } -} diff --git a/src/main/java/ru/betterend/mixin/common/SlimeMixin.java b/src/main/java/ru/betterend/mixin/common/SlimeMixin.java deleted file mode 100644 index 5d5ba94f..00000000 --- a/src/main/java/ru/betterend/mixin/common/SlimeMixin.java +++ /dev/null @@ -1,18 +0,0 @@ -package ru.betterend.mixin.common; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.world.entity.monster.Slime; -import ru.betterend.interfaces.ISlime; - -@Mixin(Slime.class) -public class SlimeMixin implements ISlime { - @Shadow - protected void setSize(int size, boolean heal) {} - - @Override - public void be_setSlimeSize(int size, boolean heal) { - setSize(size, heal); - } -} diff --git a/src/main/java/ru/betterend/mixin/common/SpikeFeatureMixin.java b/src/main/java/ru/betterend/mixin/common/SpikeFeatureMixin.java deleted file mode 100644 index 58b3001e..00000000 --- a/src/main/java/ru/betterend/mixin/common/SpikeFeatureMixin.java +++ /dev/null @@ -1,164 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.Random; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.util.Mth; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.boss.enderdragon.EndCrystal; -import net.minecraft.world.level.ServerLevelAccessor; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.IronBarsBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.feature.SpikeFeature; -import net.minecraft.world.level.levelgen.feature.configurations.SpikeConfiguration; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; -import ru.bclib.api.WorldDataAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.StructureHelper; -import ru.betterend.BetterEnd; -import ru.betterend.world.generator.GeneratorOptions; - -@Mixin(SpikeFeature.class) -public class SpikeFeatureMixin { - @Inject(method = "place", at = @At("HEAD"), cancellable = true) - private void be_place(WorldGenLevel structureWorldAccess, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, SpikeConfiguration endSpikeFeatureConfig, CallbackInfoReturnable info) { - if (!GeneratorOptions.hasPillars()) { - info.setReturnValue(false); - } - } - - @Inject(method = "placeSpike", at = @At("HEAD"), cancellable = true) - private void be_placeSpike(ServerLevelAccessor world, Random random, SpikeConfiguration config, SpikeFeature.EndSpike spike, CallbackInfo info) { - int x = spike.getCenterX(); - int z = spike.getCenterZ(); - int radius = spike.getRadius(); - int minY = 0; - - long lx = (long) x; - long lz = (long) z; - if (lx * lx + lz * lz < 10000) { - String pillarID = String.format("%d_%d", x, z); - CompoundTag pillar = WorldDataAPI.getCompoundTag(BetterEnd.MOD_ID, "pillars"); - boolean haveValue = pillar.contains(pillarID); - minY = haveValue ? pillar.getInt(pillarID) : world.getChunk(x >> 4, z >> 4).getHeight(Types.WORLD_SURFACE, x & 15, z); - if (!haveValue) { - pillar.putInt(pillarID, minY); - WorldDataAPI.saveFile(BetterEnd.MOD_ID); - } - } - else { - minY = world.getChunk(x >> 4, z >> 4).getHeight(Types.WORLD_SURFACE, x & 15, z); - } - - GeneratorOptions.setDirectSpikeHeight(); - int maxY = minY + spike.getHeight() - 64; - - if (GeneratorOptions.replacePillars() && be_radiusInRange(radius)) { - radius--; - StructureTemplate base = StructureHelper.readStructure(BetterEnd.makeID("pillars/pillar_base_" + radius)); - StructureTemplate top = StructureHelper.readStructure(BetterEnd.makeID("pillars/pillar_top_" + radius + (spike.isGuarded() ? "_cage" : ""))); - BlockPos side = base.getSize(); - BlockPos pos1 = new BlockPos(x - (side.getX() >> 1), minY - 3, z - (side.getZ() >> 1)); - minY = pos1.getY() + side.getY(); - side = top.getSize(); - BlockPos pos2 = new BlockPos(x - (side.getX() >> 1), maxY, z - (side.getZ() >> 1)); - maxY = pos2.getY(); - - StructurePlaceSettings data = new StructurePlaceSettings(); - base.placeInWorldChunk(world, pos1, data, random); - top.placeInWorldChunk(world, pos2, data, random); - - int r2 = radius * radius + 1; - MutableBlockPos mut = new MutableBlockPos(); - for (int px = -radius; px <= radius; px++) { - mut.setX(x + px); - int x2 = px * px; - for (int pz = -radius; pz <= radius; pz++) { - mut.setZ(z + pz); - int z2 = pz * pz; - if (x2 + z2 <= r2) { - for (int py = minY; py < maxY; py++) { - mut.setY(py); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - if ((px == radius || px == -radius || pz == radius || pz == -radius) && random.nextInt(24) == 0) { - BlocksHelper.setWithoutUpdate(world, mut, Blocks.CRYING_OBSIDIAN); - } - else { - BlocksHelper.setWithoutUpdate(world, mut, Blocks.OBSIDIAN); - } - } - } - } - } - } - } - else { - minY -= 15; - int r2 = radius * radius + 1; - MutableBlockPos mut = new MutableBlockPos(); - for (int px = -radius; px <= radius; px++) { - mut.setX(x + px); - int x2 = px * px; - for (int pz = -radius; pz <= radius; pz++) { - mut.setZ(z + pz); - int z2 = pz * pz; - if (x2 + z2 <= r2) { - for (int py = minY; py < maxY; py++) { - mut.setY(py); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, Blocks.OBSIDIAN); - } - } - } - } - } - mut.setX(x); - mut.setZ(z); - mut.setY(maxY); - BlocksHelper.setWithoutUpdate(world, mut, Blocks.BEDROCK); - - EndCrystal crystal = EntityType.END_CRYSTAL.create(world.getLevel()); - crystal.setBeamTarget(config.getCrystalBeamTarget()); - crystal.setInvulnerable(config.isCrystalInvulnerable()); - crystal.moveTo(x + 0.5D, maxY + 1, z + 0.5D, random.nextFloat() * 360.0F, 0.0F); - world.addFreshEntity(crystal); - - if (spike.isGuarded()) { - for (int px = -2; px <= 2; ++px) { - boolean bl = Mth.abs(px) == 2; - for (int pz = -2; pz <= 2; ++pz) { - boolean bl2 = Mth.abs(pz) == 2; - for (int py = 0; py <= 3; ++py) { - boolean bl3 = py == 3; - if (bl || bl2 || bl3) { - boolean bl4 = px == -2 || px == 2 || bl3; - boolean bl5 = pz == -2 || pz == 2 || bl3; - BlockState blockState = (BlockState) ((BlockState) ((BlockState) ((BlockState) Blocks.IRON_BARS.defaultBlockState().setValue(IronBarsBlock.NORTH, bl4 && pz != -2)).setValue(IronBarsBlock.SOUTH, bl4 && pz != 2)).setValue(IronBarsBlock.WEST, bl5 && px != -2)).setValue(IronBarsBlock.EAST, bl5 && px != 2); - BlocksHelper.setWithoutUpdate(world, mut.set(spike.getCenterX() + px, maxY + py, spike.getCenterZ() + pz), blockState); - } - } - } - } - } - } - - info.cancel(); - } - - private boolean be_radiusInRange(int radius) { - return radius > 1 && radius < 6; - } -} diff --git a/src/main/java/ru/betterend/mixin/common/WeightedBiomePickerMixin.java b/src/main/java/ru/betterend/mixin/common/WeightedBiomePickerMixin.java deleted file mode 100644 index da2c05e6..00000000 --- a/src/main/java/ru/betterend/mixin/common/WeightedBiomePickerMixin.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.betterend.mixin.common; - -import java.util.List; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.google.common.collect.Lists; - -import net.fabricmc.fabric.impl.biome.InternalBiomeData; -import net.fabricmc.fabric.impl.biome.WeightedBiomePicker; -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.Biomes; -import ru.betterend.interfaces.IBiomeList; - -@Mixin(value = WeightedBiomePicker.class, remap = false) -public class WeightedBiomePickerMixin implements IBiomeList { - private final List> biomes = Lists.newArrayList(); - - @Inject(method = "addBiome", at = @At("TAIL")) - private void be_addBiome(final ResourceKey biome, final double weight, CallbackInfo info) { - if (be_isCorrectPicker(WeightedBiomePicker.class.cast(this))) { - biomes.add(biome); - } - } - - @Override - public List> getBiomes() { - return biomes; - } - - private boolean be_isCorrectPicker(WeightedBiomePicker picker) { - return picker == InternalBiomeData.getEndBiomesMap().get(Biomes.SMALL_END_ISLANDS) || picker == InternalBiomeData.getEndBarrensMap().get(Biomes.END_BARRENS); - } -} diff --git a/src/main/java/ru/betterend/noise/OpenSimplexNoise.java b/src/main/java/ru/betterend/noise/OpenSimplexNoise.java deleted file mode 100644 index 3389bfbc..00000000 --- a/src/main/java/ru/betterend/noise/OpenSimplexNoise.java +++ /dev/null @@ -1,2185 +0,0 @@ -package ru.betterend.noise; - -/* - * OpenSimplex Noise in Java. - * by Kurt Spencer - * - * v1.1 (October 5, 2014) - * - Added 2D and 4D implementations. - * - Proper gradient sets for all dimensions, from a - * dimensionally-generalizable scheme with an actual - * rhyme and reason behind it. - * - Removed default permutation array in favor of - * default seed. - * - Changed seed-based constructor to be independent - * of any particular randomization library, so results - * will be the same when ported to other languages. - */ - -public class OpenSimplexNoise { - private static final double STRETCH_CONSTANT_2D = -0.211324865405187; // (1/Math.sqrt(2+1)-1)/2; - private static final double SQUISH_CONSTANT_2D = 0.366025403784439; // (Math.sqrt(2+1)-1)/2; - private static final double STRETCH_CONSTANT_3D = -1.0 / 6; // (1/Math.sqrt(3+1)-1)/3; - private static final double SQUISH_CONSTANT_3D = 1.0 / 3; // (Math.sqrt(3+1)-1)/3; - private static final double STRETCH_CONSTANT_4D = -0.138196601125011; // (1/Math.sqrt(4+1)-1)/4; - private static final double SQUISH_CONSTANT_4D = 0.309016994374947; // (Math.sqrt(4+1)-1)/4; - - private static final double NORM_CONSTANT_2D = 47; - private static final double NORM_CONSTANT_3D = 103; - private static final double NORM_CONSTANT_4D = 30; - - private static final long DEFAULT_SEED = 0; - - private short[] perm; - private short[] permGradIndex3D; - - public OpenSimplexNoise() { - this(DEFAULT_SEED); - } - - public OpenSimplexNoise(short[] perm) { - this.perm = perm; - permGradIndex3D = new short[256]; - - for (int i = 0; i < 256; i++) { - // Since 3D has 24 gradients, simple bitmask won't work, so - // precompute modulo array. - permGradIndex3D[i] = (short) ((perm[i] % (gradients3D.length / 3)) * 3); - } - } - - // Initializes the class using a permutation array generated from a 64-bit - // seed. - // Generates a proper permutation (i.e. doesn't merely perform N successive - // pair swaps on a base array) - // Uses a simple 64-bit LCG. - public OpenSimplexNoise(long seed) { - perm = new short[256]; - permGradIndex3D = new short[256]; - short[] source = new short[256]; - for (short i = 0; i < 256; i++) - source[i] = i; - seed = seed * 6364136223846793005l + 1442695040888963407l; - seed = seed * 6364136223846793005l + 1442695040888963407l; - seed = seed * 6364136223846793005l + 1442695040888963407l; - for (int i = 255; i >= 0; i--) { - seed = seed * 6364136223846793005l + 1442695040888963407l; - int r = (int) ((seed + 31) % (i + 1)); - if (r < 0) - r += (i + 1); - perm[i] = source[r]; - permGradIndex3D[i] = (short) ((perm[i] % (gradients3D.length / 3)) * 3); - source[r] = source[i]; - } - } - - // 2D OpenSimplex Noise. - public double eval(double x, double y) { - - // Place input coordinates onto grid. - double stretchOffset = (x + y) * STRETCH_CONSTANT_2D; - double xs = x + stretchOffset; - double ys = y + stretchOffset; - - // Floor to get grid coordinates of rhombus (stretched square) - // super-cell origin. - int xsb = fastFloor(xs); - int ysb = fastFloor(ys); - - // Skew out to get actual coordinates of rhombus origin. We'll need - // these later. - double squishOffset = (xsb + ysb) * SQUISH_CONSTANT_2D; - double xb = xsb + squishOffset; - double yb = ysb + squishOffset; - - // Compute grid coordinates relative to rhombus origin. - double xins = xs - xsb; - double yins = ys - ysb; - - // Sum those together to get a value that determines which region we're - // in. - double inSum = xins + yins; - - // Positions relative to origin point. - double dx0 = x - xb; - double dy0 = y - yb; - - // We'll be defining these inside the next block and using them - // afterwards. - double dx_ext, dy_ext; - int xsv_ext, ysv_ext; - - double value = 0; - - // Contribution (1,0) - double dx1 = dx0 - 1 - SQUISH_CONSTANT_2D; - double dy1 = dy0 - 0 - SQUISH_CONSTANT_2D; - double attn1 = 2 - dx1 * dx1 - dy1 * dy1; - if (attn1 > 0) { - attn1 *= attn1; - value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, dx1, dy1); - } - - // Contribution (0,1) - double dx2 = dx0 - 0 - SQUISH_CONSTANT_2D; - double dy2 = dy0 - 1 - SQUISH_CONSTANT_2D; - double attn2 = 2 - dx2 * dx2 - dy2 * dy2; - if (attn2 > 0) { - attn2 *= attn2; - value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, dx2, dy2); - } - - if (inSum <= 1) { // We're inside the triangle (2-Simplex) at (0,0) - double zins = 1 - inSum; - if (zins > xins || zins > yins) { // (0,0) is one of the closest two - // triangular vertices - if (xins > yins) { - xsv_ext = xsb + 1; - ysv_ext = ysb - 1; - dx_ext = dx0 - 1; - dy_ext = dy0 + 1; - } else { - xsv_ext = xsb - 1; - ysv_ext = ysb + 1; - dx_ext = dx0 + 1; - dy_ext = dy0 - 1; - } - } else { // (1,0) and (0,1) are the closest two vertices. - xsv_ext = xsb + 1; - ysv_ext = ysb + 1; - dx_ext = dx0 - 1 - 2 * SQUISH_CONSTANT_2D; - dy_ext = dy0 - 1 - 2 * SQUISH_CONSTANT_2D; - } - } else { // We're inside the triangle (2-Simplex) at (1,1) - double zins = 2 - inSum; - if (zins < xins || zins < yins) { // (0,0) is one of the closest two - // triangular vertices - if (xins > yins) { - xsv_ext = xsb + 2; - ysv_ext = ysb + 0; - dx_ext = dx0 - 2 - 2 * SQUISH_CONSTANT_2D; - dy_ext = dy0 + 0 - 2 * SQUISH_CONSTANT_2D; - } else { - xsv_ext = xsb + 0; - ysv_ext = ysb + 2; - dx_ext = dx0 + 0 - 2 * SQUISH_CONSTANT_2D; - dy_ext = dy0 - 2 - 2 * SQUISH_CONSTANT_2D; - } - } else { // (1,0) and (0,1) are the closest two vertices. - dx_ext = dx0; - dy_ext = dy0; - xsv_ext = xsb; - ysv_ext = ysb; - } - xsb += 1; - ysb += 1; - dx0 = dx0 - 1 - 2 * SQUISH_CONSTANT_2D; - dy0 = dy0 - 1 - 2 * SQUISH_CONSTANT_2D; - } - - // Contribution (0,0) or (1,1) - double attn0 = 2 - dx0 * dx0 - dy0 * dy0; - if (attn0 > 0) { - attn0 *= attn0; - value += attn0 * attn0 * extrapolate(xsb, ysb, dx0, dy0); - } - - // Extra Vertex - double attn_ext = 2 - dx_ext * dx_ext - dy_ext * dy_ext; - if (attn_ext > 0) { - attn_ext *= attn_ext; - value += attn_ext * attn_ext * extrapolate(xsv_ext, ysv_ext, dx_ext, dy_ext); - } - - return value / NORM_CONSTANT_2D; - } - - // 3D OpenSimplex Noise. - public double eval(double x, double y, double z) { - - // Place input coordinates on simplectic honeycomb. - double stretchOffset = (x + y + z) * STRETCH_CONSTANT_3D; - double xs = x + stretchOffset; - double ys = y + stretchOffset; - double zs = z + stretchOffset; - - // Floor to get simplectic honeycomb coordinates of rhombohedron - // (stretched cube) super-cell origin. - int xsb = fastFloor(xs); - int ysb = fastFloor(ys); - int zsb = fastFloor(zs); - - // Skew out to get actual coordinates of rhombohedron origin. We'll need - // these later. - double squishOffset = (xsb + ysb + zsb) * SQUISH_CONSTANT_3D; - double xb = xsb + squishOffset; - double yb = ysb + squishOffset; - double zb = zsb + squishOffset; - - // Compute simplectic honeycomb coordinates relative to rhombohedral - // origin. - double xins = xs - xsb; - double yins = ys - ysb; - double zins = zs - zsb; - - // Sum those together to get a value that determines which region we're - // in. - double inSum = xins + yins + zins; - - // Positions relative to origin point. - double dx0 = x - xb; - double dy0 = y - yb; - double dz0 = z - zb; - - // We'll be defining these inside the next block and using them - // afterwards. - double dx_ext0, dy_ext0, dz_ext0; - double dx_ext1, dy_ext1, dz_ext1; - int xsv_ext0, ysv_ext0, zsv_ext0; - int xsv_ext1, ysv_ext1, zsv_ext1; - - double value = 0; - if (inSum <= 1) { // We're inside the tetrahedron (3-Simplex) at (0,0,0) - - // Determine which two of (0,0,1), (0,1,0), (1,0,0) are closest. - byte aPoint = 0x01; - double aScore = xins; - byte bPoint = 0x02; - double bScore = yins; - if (aScore >= bScore && zins > bScore) { - bScore = zins; - bPoint = 0x04; - } else if (aScore < bScore && zins > aScore) { - aScore = zins; - aPoint = 0x04; - } - - // Now we determine the two lattice points not part of the - // tetrahedron that may contribute. - // This depends on the closest two tetrahedral vertices, including - // (0,0,0) - double wins = 1 - inSum; - if (wins > aScore || wins > bScore) { // (0,0,0) is one of the - // closest two tetrahedral - // vertices. - byte c = (bScore > aScore ? bPoint : aPoint); // Our other - // closest - // vertex is the - // closest out - // of a and b. - - if ((c & 0x01) == 0) { - xsv_ext0 = xsb - 1; - xsv_ext1 = xsb; - dx_ext0 = dx0 + 1; - dx_ext1 = dx0; - } else { - xsv_ext0 = xsv_ext1 = xsb + 1; - dx_ext0 = dx_ext1 = dx0 - 1; - } - - if ((c & 0x02) == 0) { - ysv_ext0 = ysv_ext1 = ysb; - dy_ext0 = dy_ext1 = dy0; - if ((c & 0x01) == 0) { - ysv_ext1 -= 1; - dy_ext1 += 1; - } else { - ysv_ext0 -= 1; - dy_ext0 += 1; - } - } else { - ysv_ext0 = ysv_ext1 = ysb + 1; - dy_ext0 = dy_ext1 = dy0 - 1; - } - - if ((c & 0x04) == 0) { - zsv_ext0 = zsb; - zsv_ext1 = zsb - 1; - dz_ext0 = dz0; - dz_ext1 = dz0 + 1; - } else { - zsv_ext0 = zsv_ext1 = zsb + 1; - dz_ext0 = dz_ext1 = dz0 - 1; - } - } else { // (0,0,0) is not one of the closest two tetrahedral - // vertices. - byte c = (byte) (aPoint | bPoint); // Our two extra vertices are - // determined by the closest - // two. - - if ((c & 0x01) == 0) { - xsv_ext0 = xsb; - xsv_ext1 = xsb - 1; - dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_3D; - dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D; - } else { - xsv_ext0 = xsv_ext1 = xsb + 1; - dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; - dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; - } - - if ((c & 0x02) == 0) { - ysv_ext0 = ysb; - ysv_ext1 = ysb - 1; - dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_3D; - dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D; - } else { - ysv_ext0 = ysv_ext1 = ysb + 1; - dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; - } - - if ((c & 0x04) == 0) { - zsv_ext0 = zsb; - zsv_ext1 = zsb - 1; - dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D; - } else { - zsv_ext0 = zsv_ext1 = zsb + 1; - dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; - } - } - - // Contribution (0,0,0) - double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0; - if (attn0 > 0) { - attn0 *= attn0; - value += attn0 * attn0 * extrapolate(xsb + 0, ysb + 0, zsb + 0, dx0, dy0, dz0); - } - - // Contribution (1,0,0) - double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D; - double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D; - double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D; - double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; - if (attn1 > 0) { - attn1 *= attn1; - value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1); - } - - // Contribution (0,1,0) - double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D; - double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D; - double dz2 = dz1; - double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; - if (attn2 > 0) { - attn2 *= attn2; - value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2); - } - - // Contribution (0,0,1) - double dx3 = dx2; - double dy3 = dy1; - double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D; - double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; - if (attn3 > 0) { - attn3 *= attn3; - value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3); - } - } else if (inSum >= 2) { // We're inside the tetrahedron (3-Simplex) at - // (1,1,1) - - // Determine which two tetrahedral vertices are the closest, out of - // (1,1,0), (1,0,1), (0,1,1) but not (1,1,1). - byte aPoint = 0x06; - double aScore = xins; - byte bPoint = 0x05; - double bScore = yins; - if (aScore <= bScore && zins < bScore) { - bScore = zins; - bPoint = 0x03; - } else if (aScore > bScore && zins < aScore) { - aScore = zins; - aPoint = 0x03; - } - - // Now we determine the two lattice points not part of the - // tetrahedron that may contribute. - // This depends on the closest two tetrahedral vertices, including - // (1,1,1) - double wins = 3 - inSum; - if (wins < aScore || wins < bScore) { // (1,1,1) is one of the - // closest two tetrahedral - // vertices. - byte c = (bScore < aScore ? bPoint : aPoint); // Our other - // closest - // vertex is the - // closest out - // of a and b. - - if ((c & 0x01) != 0) { - xsv_ext0 = xsb + 2; - xsv_ext1 = xsb + 1; - dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_3D; - dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; - } else { - xsv_ext0 = xsv_ext1 = xsb; - dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_3D; - } - - if ((c & 0x02) != 0) { - ysv_ext0 = ysv_ext1 = ysb + 1; - dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; - if ((c & 0x01) != 0) { - ysv_ext1 += 1; - dy_ext1 -= 1; - } else { - ysv_ext0 += 1; - dy_ext0 -= 1; - } - } else { - ysv_ext0 = ysv_ext1 = ysb; - dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_3D; - } - - if ((c & 0x04) != 0) { - zsv_ext0 = zsb + 1; - zsv_ext1 = zsb + 2; - dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 - 3 * SQUISH_CONSTANT_3D; - } else { - zsv_ext0 = zsv_ext1 = zsb; - dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_3D; - } - } else { // (1,1,1) is not one of the closest two tetrahedral - // vertices. - byte c = (byte) (aPoint & bPoint); // Our two extra vertices are - // determined by the closest - // two. - - if ((c & 0x01) != 0) { - xsv_ext0 = xsb + 1; - xsv_ext1 = xsb + 2; - dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; - dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D; - } else { - xsv_ext0 = xsv_ext1 = xsb; - dx_ext0 = dx0 - SQUISH_CONSTANT_3D; - dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; - } - - if ((c & 0x02) != 0) { - ysv_ext0 = ysb + 1; - ysv_ext1 = ysb + 2; - dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D; - } else { - ysv_ext0 = ysv_ext1 = ysb; - dy_ext0 = dy0 - SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; - } - - if ((c & 0x04) != 0) { - zsv_ext0 = zsb + 1; - zsv_ext1 = zsb + 2; - dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D; - } else { - zsv_ext0 = zsv_ext1 = zsb; - dz_ext0 = dz0 - SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; - } - } - - // Contribution (1,1,0) - double dx3 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; - double dy3 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; - double dz3 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D; - double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; - if (attn3 > 0) { - attn3 *= attn3; - value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx3, dy3, dz3); - } - - // Contribution (1,0,1) - double dx2 = dx3; - double dy2 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D; - double dz2 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; - double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; - if (attn2 > 0) { - attn2 *= attn2; - value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx2, dy2, dz2); - } - - // Contribution (0,1,1) - double dx1 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D; - double dy1 = dy3; - double dz1 = dz2; - double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; - if (attn1 > 0) { - attn1 *= attn1; - value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx1, dy1, dz1); - } - - // Contribution (1,1,1) - dx0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; - dy0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; - dz0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; - double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0; - if (attn0 > 0) { - attn0 *= attn0; - value += attn0 * attn0 * extrapolate(xsb + 1, ysb + 1, zsb + 1, dx0, dy0, dz0); - } - } else { // We're inside the octahedron (Rectified 3-Simplex) in - // between. - double aScore; - byte aPoint; - boolean aIsFurtherSide; - double bScore; - byte bPoint; - boolean bIsFurtherSide; - - // Decide between point (0,0,1) and (1,1,0) as closest - double p1 = xins + yins; - if (p1 > 1) { - aScore = p1 - 1; - aPoint = 0x03; - aIsFurtherSide = true; - } else { - aScore = 1 - p1; - aPoint = 0x04; - aIsFurtherSide = false; - } - - // Decide between point (0,1,0) and (1,0,1) as closest - double p2 = xins + zins; - if (p2 > 1) { - bScore = p2 - 1; - bPoint = 0x05; - bIsFurtherSide = true; - } else { - bScore = 1 - p2; - bPoint = 0x02; - bIsFurtherSide = false; - } - - // The closest out of the two (1,0,0) and (0,1,1) will replace the - // furthest out of the two decided above, if closer. - double p3 = yins + zins; - if (p3 > 1) { - double score = p3 - 1; - if (aScore <= bScore && aScore < score) { - aScore = score; - aPoint = 0x06; - aIsFurtherSide = true; - } else if (aScore > bScore && bScore < score) { - bScore = score; - bPoint = 0x06; - bIsFurtherSide = true; - } - } else { - double score = 1 - p3; - if (aScore <= bScore && aScore < score) { - aScore = score; - aPoint = 0x01; - aIsFurtherSide = false; - } else if (aScore > bScore && bScore < score) { - bScore = score; - bPoint = 0x01; - bIsFurtherSide = false; - } - } - - // Where each of the two closest points are determines how the extra - // two vertices are calculated. - if (aIsFurtherSide == bIsFurtherSide) { - if (aIsFurtherSide) { // Both closest points on (1,1,1) side - - // One of the two extra points is (1,1,1) - dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; - dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; - dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; - xsv_ext0 = xsb + 1; - ysv_ext0 = ysb + 1; - zsv_ext0 = zsb + 1; - - // Other extra point is based on the shared axis. - byte c = (byte) (aPoint & bPoint); - if ((c & 0x01) != 0) { - dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; - xsv_ext1 = xsb + 2; - ysv_ext1 = ysb; - zsv_ext1 = zsb; - } else if ((c & 0x02) != 0) { - dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; - xsv_ext1 = xsb; - ysv_ext1 = ysb + 2; - zsv_ext1 = zsb; - } else { - dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D; - xsv_ext1 = xsb; - ysv_ext1 = ysb; - zsv_ext1 = zsb + 2; - } - } else {// Both closest points on (0,0,0) side - - // One of the two extra points is (0,0,0) - dx_ext0 = dx0; - dy_ext0 = dy0; - dz_ext0 = dz0; - xsv_ext0 = xsb; - ysv_ext0 = ysb; - zsv_ext0 = zsb; - - // Other extra point is based on the omitted axis. - byte c = (byte) (aPoint | bPoint); - if ((c & 0x01) == 0) { - dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; - xsv_ext1 = xsb - 1; - ysv_ext1 = ysb + 1; - zsv_ext1 = zsb + 1; - } else if ((c & 0x02) == 0) { - dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; - dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; - xsv_ext1 = xsb + 1; - ysv_ext1 = ysb - 1; - zsv_ext1 = zsb + 1; - } else { - dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; - dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D; - xsv_ext1 = xsb + 1; - ysv_ext1 = ysb + 1; - zsv_ext1 = zsb - 1; - } - } - } else { // One point on (0,0,0) side, one point on (1,1,1) side - byte c1, c2; - if (aIsFurtherSide) { - c1 = aPoint; - c2 = bPoint; - } else { - c1 = bPoint; - c2 = aPoint; - } - - // One contribution is a permutation of (1,1,-1) - if ((c1 & 0x01) == 0) { - dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_3D; - dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; - dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; - xsv_ext0 = xsb - 1; - ysv_ext0 = ysb + 1; - zsv_ext0 = zsb + 1; - } else if ((c1 & 0x02) == 0) { - dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; - dy_ext0 = dy0 + 1 - SQUISH_CONSTANT_3D; - dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; - xsv_ext0 = xsb + 1; - ysv_ext0 = ysb - 1; - zsv_ext0 = zsb + 1; - } else { - dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; - dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; - dz_ext0 = dz0 + 1 - SQUISH_CONSTANT_3D; - xsv_ext0 = xsb + 1; - ysv_ext0 = ysb + 1; - zsv_ext0 = zsb - 1; - } - - // One contribution is a permutation of (0,0,2) - dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; - xsv_ext1 = xsb; - ysv_ext1 = ysb; - zsv_ext1 = zsb; - if ((c2 & 0x01) != 0) { - dx_ext1 -= 2; - xsv_ext1 += 2; - } else if ((c2 & 0x02) != 0) { - dy_ext1 -= 2; - ysv_ext1 += 2; - } else { - dz_ext1 -= 2; - zsv_ext1 += 2; - } - } - - // Contribution (1,0,0) - double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D; - double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D; - double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D; - double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; - if (attn1 > 0) { - attn1 *= attn1; - value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1); - } - - // Contribution (0,1,0) - double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D; - double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D; - double dz2 = dz1; - double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; - if (attn2 > 0) { - attn2 *= attn2; - value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2); - } - - // Contribution (0,0,1) - double dx3 = dx2; - double dy3 = dy1; - double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D; - double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; - if (attn3 > 0) { - attn3 *= attn3; - value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3); - } - - // Contribution (1,1,0) - double dx4 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; - double dy4 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; - double dz4 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D; - double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4; - if (attn4 > 0) { - attn4 *= attn4; - value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx4, dy4, dz4); - } - - // Contribution (1,0,1) - double dx5 = dx4; - double dy5 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D; - double dz5 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; - double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5; - if (attn5 > 0) { - attn5 *= attn5; - value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx5, dy5, dz5); - } - - // Contribution (0,1,1) - double dx6 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D; - double dy6 = dy4; - double dz6 = dz5; - double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6; - if (attn6 > 0) { - attn6 *= attn6; - value += attn6 * attn6 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx6, dy6, dz6); - } - } - - // First extra vertex - double attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0; - if (attn_ext0 > 0) { - attn_ext0 *= attn_ext0; - value += attn_ext0 * attn_ext0 * extrapolate(xsv_ext0, ysv_ext0, zsv_ext0, dx_ext0, dy_ext0, dz_ext0); - } - - // Second extra vertex - double attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1; - if (attn_ext1 > 0) { - attn_ext1 *= attn_ext1; - value += attn_ext1 * attn_ext1 * extrapolate(xsv_ext1, ysv_ext1, zsv_ext1, dx_ext1, dy_ext1, dz_ext1); - } - - return value / NORM_CONSTANT_3D; - } - - // 4D OpenSimplex Noise. - public double eval(double x, double y, double z, double w) { - - // Place input coordinates on simplectic honeycomb. - double stretchOffset = (x + y + z + w) * STRETCH_CONSTANT_4D; - double xs = x + stretchOffset; - double ys = y + stretchOffset; - double zs = z + stretchOffset; - double ws = w + stretchOffset; - - // Floor to get simplectic honeycomb coordinates of rhombo-hypercube - // super-cell origin. - int xsb = fastFloor(xs); - int ysb = fastFloor(ys); - int zsb = fastFloor(zs); - int wsb = fastFloor(ws); - - // Skew out to get actual coordinates of stretched rhombo-hypercube - // origin. We'll need these later. - double squishOffset = (xsb + ysb + zsb + wsb) * SQUISH_CONSTANT_4D; - double xb = xsb + squishOffset; - double yb = ysb + squishOffset; - double zb = zsb + squishOffset; - double wb = wsb + squishOffset; - - // Compute simplectic honeycomb coordinates relative to rhombo-hypercube - // origin. - double xins = xs - xsb; - double yins = ys - ysb; - double zins = zs - zsb; - double wins = ws - wsb; - - // Sum those together to get a value that determines which region we're - // in. - double inSum = xins + yins + zins + wins; - - // Positions relative to origin point. - double dx0 = x - xb; - double dy0 = y - yb; - double dz0 = z - zb; - double dw0 = w - wb; - - // We'll be defining these inside the next block and using them - // afterwards. - double dx_ext0, dy_ext0, dz_ext0, dw_ext0; - double dx_ext1, dy_ext1, dz_ext1, dw_ext1; - double dx_ext2, dy_ext2, dz_ext2, dw_ext2; - int xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0; - int xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1; - int xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2; - - double value = 0; - if (inSum <= 1) { // We're inside the pentachoron (4-Simplex) at - // (0,0,0,0) - - // Determine which two of (0,0,0,1), (0,0,1,0), (0,1,0,0), (1,0,0,0) - // are closest. - byte aPoint = 0x01; - double aScore = xins; - byte bPoint = 0x02; - double bScore = yins; - if (aScore >= bScore && zins > bScore) { - bScore = zins; - bPoint = 0x04; - } else if (aScore < bScore && zins > aScore) { - aScore = zins; - aPoint = 0x04; - } - if (aScore >= bScore && wins > bScore) { - bScore = wins; - bPoint = 0x08; - } else if (aScore < bScore && wins > aScore) { - aScore = wins; - aPoint = 0x08; - } - - // Now we determine the three lattice points not part of the - // pentachoron that may contribute. - // This depends on the closest two pentachoron vertices, including - // (0,0,0,0) - double uins = 1 - inSum; - if (uins > aScore || uins > bScore) { // (0,0,0,0) is one of the - // closest two pentachoron - // vertices. - byte c = (bScore > aScore ? bPoint : aPoint); // Our other - // closest - // vertex is the - // closest out - // of a and b. - if ((c & 0x01) == 0) { - xsv_ext0 = xsb - 1; - xsv_ext1 = xsv_ext2 = xsb; - dx_ext0 = dx0 + 1; - dx_ext1 = dx_ext2 = dx0; - } else { - xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1; - dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 1; - } - - if ((c & 0x02) == 0) { - ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; - dy_ext0 = dy_ext1 = dy_ext2 = dy0; - if ((c & 0x01) == 0x01) { - ysv_ext0 -= 1; - dy_ext0 += 1; - } else { - ysv_ext1 -= 1; - dy_ext1 += 1; - } - } else { - ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; - dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1; - } - - if ((c & 0x04) == 0) { - zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; - dz_ext0 = dz_ext1 = dz_ext2 = dz0; - if ((c & 0x03) != 0) { - if ((c & 0x03) == 0x03) { - zsv_ext0 -= 1; - dz_ext0 += 1; - } else { - zsv_ext1 -= 1; - dz_ext1 += 1; - } - } else { - zsv_ext2 -= 1; - dz_ext2 += 1; - } - } else { - zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; - dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1; - } - - if ((c & 0x08) == 0) { - wsv_ext0 = wsv_ext1 = wsb; - wsv_ext2 = wsb - 1; - dw_ext0 = dw_ext1 = dw0; - dw_ext2 = dw0 + 1; - } else { - wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1; - dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 1; - } - } else { // (0,0,0,0) is not one of the closest two pentachoron - // vertices. - byte c = (byte) (aPoint | bPoint); // Our three extra vertices - // are determined by the - // closest two. - - if ((c & 0x01) == 0) { - xsv_ext0 = xsv_ext2 = xsb; - xsv_ext1 = xsb - 1; - dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D; - dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_4D; - dx_ext2 = dx0 - SQUISH_CONSTANT_4D; - } else { - xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1; - dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; - dx_ext1 = dx_ext2 = dx0 - 1 - SQUISH_CONSTANT_4D; - } - - if ((c & 0x02) == 0) { - ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; - dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D; - dy_ext1 = dy_ext2 = dy0 - SQUISH_CONSTANT_4D; - if ((c & 0x01) == 0x01) { - ysv_ext1 -= 1; - dy_ext1 += 1; - } else { - ysv_ext2 -= 1; - dy_ext2 += 1; - } - } else { - ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; - dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; - dy_ext1 = dy_ext2 = dy0 - 1 - SQUISH_CONSTANT_4D; - } - - if ((c & 0x04) == 0) { - zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; - dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D; - dz_ext1 = dz_ext2 = dz0 - SQUISH_CONSTANT_4D; - if ((c & 0x03) == 0x03) { - zsv_ext1 -= 1; - dz_ext1 += 1; - } else { - zsv_ext2 -= 1; - dz_ext2 += 1; - } - } else { - zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; - dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; - dz_ext1 = dz_ext2 = dz0 - 1 - SQUISH_CONSTANT_4D; - } - - if ((c & 0x08) == 0) { - wsv_ext0 = wsv_ext1 = wsb; - wsv_ext2 = wsb - 1; - dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D; - dw_ext1 = dw0 - SQUISH_CONSTANT_4D; - dw_ext2 = dw0 + 1 - SQUISH_CONSTANT_4D; - } else { - wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1; - dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; - dw_ext1 = dw_ext2 = dw0 - 1 - SQUISH_CONSTANT_4D; - } - } - - // Contribution (0,0,0,0) - double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0; - if (attn0 > 0) { - attn0 *= attn0; - value += attn0 * attn0 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 0, dx0, dy0, dz0, dw0); - } - - // Contribution (1,0,0,0) - double dx1 = dx0 - 1 - SQUISH_CONSTANT_4D; - double dy1 = dy0 - 0 - SQUISH_CONSTANT_4D; - double dz1 = dz0 - 0 - SQUISH_CONSTANT_4D; - double dw1 = dw0 - 0 - SQUISH_CONSTANT_4D; - double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; - if (attn1 > 0) { - attn1 *= attn1; - value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1); - } - - // Contribution (0,1,0,0) - double dx2 = dx0 - 0 - SQUISH_CONSTANT_4D; - double dy2 = dy0 - 1 - SQUISH_CONSTANT_4D; - double dz2 = dz1; - double dw2 = dw1; - double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; - if (attn2 > 0) { - attn2 *= attn2; - value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2); - } - - // Contribution (0,0,1,0) - double dx3 = dx2; - double dy3 = dy1; - double dz3 = dz0 - 1 - SQUISH_CONSTANT_4D; - double dw3 = dw1; - double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; - if (attn3 > 0) { - attn3 *= attn3; - value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3); - } - - // Contribution (0,0,0,1) - double dx4 = dx2; - double dy4 = dy1; - double dz4 = dz1; - double dw4 = dw0 - 1 - SQUISH_CONSTANT_4D; - double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; - if (attn4 > 0) { - attn4 *= attn4; - value += attn4 * attn4 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4); - } - } else if (inSum >= 3) { // We're inside the pentachoron (4-Simplex) at - // (1,1,1,1) - // Determine which two of (1,1,1,0), - // (1,1,0,1), (1,0,1,1), (0,1,1,1) - // are closest. - byte aPoint = 0x0E; - double aScore = xins; - byte bPoint = 0x0D; - double bScore = yins; - if (aScore <= bScore && zins < bScore) { - bScore = zins; - bPoint = 0x0B; - } else if (aScore > bScore && zins < aScore) { - aScore = zins; - aPoint = 0x0B; - } - if (aScore <= bScore && wins < bScore) { - bScore = wins; - bPoint = 0x07; - } else if (aScore > bScore && wins < aScore) { - aScore = wins; - aPoint = 0x07; - } - - // Now we determine the three lattice points not part of the - // pentachoron that may contribute. - // This depends on the closest two pentachoron vertices, including - // (0,0,0,0) - double uins = 4 - inSum; - if (uins < aScore || uins < bScore) { // (1,1,1,1) is one of the - // closest two pentachoron - // vertices. - byte c = (bScore < aScore ? bPoint : aPoint); // Our other - // closest - // vertex is the - // closest out - // of a and b. - - if ((c & 0x01) != 0) { - xsv_ext0 = xsb + 2; - xsv_ext1 = xsv_ext2 = xsb + 1; - dx_ext0 = dx0 - 2 - 4 * SQUISH_CONSTANT_4D; - dx_ext1 = dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D; - } else { - xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb; - dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 4 * SQUISH_CONSTANT_4D; - } - - if ((c & 0x02) != 0) { - ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; - dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D; - if ((c & 0x01) != 0) { - ysv_ext1 += 1; - dy_ext1 -= 1; - } else { - ysv_ext0 += 1; - dy_ext0 -= 1; - } - } else { - ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; - dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 4 * SQUISH_CONSTANT_4D; - } - - if ((c & 0x04) != 0) { - zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; - dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D; - if ((c & 0x03) != 0x03) { - if ((c & 0x03) == 0) { - zsv_ext0 += 1; - dz_ext0 -= 1; - } else { - zsv_ext1 += 1; - dz_ext1 -= 1; - } - } else { - zsv_ext2 += 1; - dz_ext2 -= 1; - } - } else { - zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; - dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 4 * SQUISH_CONSTANT_4D; - } - - if ((c & 0x08) != 0) { - wsv_ext0 = wsv_ext1 = wsb + 1; - wsv_ext2 = wsb + 2; - dw_ext0 = dw_ext1 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D; - dw_ext2 = dw0 - 2 - 4 * SQUISH_CONSTANT_4D; - } else { - wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb; - dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 4 * SQUISH_CONSTANT_4D; - } - } else { // (1,1,1,1) is not one of the closest two pentachoron - // vertices. - byte c = (byte) (aPoint & bPoint); // Our three extra vertices - // are determined by the - // closest two. - - if ((c & 0x01) != 0) { - xsv_ext0 = xsv_ext2 = xsb + 1; - xsv_ext1 = xsb + 2; - dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; - dx_ext1 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D; - dx_ext2 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; - } else { - xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb; - dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D; - dx_ext1 = dx_ext2 = dx0 - 3 * SQUISH_CONSTANT_4D; - } - - if ((c & 0x02) != 0) { - ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; - dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; - dy_ext1 = dy_ext2 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; - if ((c & 0x01) != 0) { - ysv_ext2 += 1; - dy_ext2 -= 1; - } else { - ysv_ext1 += 1; - dy_ext1 -= 1; - } - } else { - ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; - dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D; - dy_ext1 = dy_ext2 = dy0 - 3 * SQUISH_CONSTANT_4D; - } - - if ((c & 0x04) != 0) { - zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; - dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; - dz_ext1 = dz_ext2 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; - if ((c & 0x03) != 0) { - zsv_ext2 += 1; - dz_ext2 -= 1; - } else { - zsv_ext1 += 1; - dz_ext1 -= 1; - } - } else { - zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; - dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D; - dz_ext1 = dz_ext2 = dz0 - 3 * SQUISH_CONSTANT_4D; - } - - if ((c & 0x08) != 0) { - wsv_ext0 = wsv_ext1 = wsb + 1; - wsv_ext2 = wsb + 2; - dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; - dw_ext1 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; - dw_ext2 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D; - } else { - wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb; - dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D; - dw_ext1 = dw_ext2 = dw0 - 3 * SQUISH_CONSTANT_4D; - } - } - - // Contribution (1,1,1,0) - double dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; - double dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; - double dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; - double dw4 = dw0 - 3 * SQUISH_CONSTANT_4D; - double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; - if (attn4 > 0) { - attn4 *= attn4; - value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4); - } - - // Contribution (1,1,0,1) - double dx3 = dx4; - double dy3 = dy4; - double dz3 = dz0 - 3 * SQUISH_CONSTANT_4D; - double dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; - double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; - if (attn3 > 0) { - attn3 *= attn3; - value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3); - } - - // Contribution (1,0,1,1) - double dx2 = dx4; - double dy2 = dy0 - 3 * SQUISH_CONSTANT_4D; - double dz2 = dz4; - double dw2 = dw3; - double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; - if (attn2 > 0) { - attn2 *= attn2; - value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2); - } - - // Contribution (0,1,1,1) - double dx1 = dx0 - 3 * SQUISH_CONSTANT_4D; - double dz1 = dz4; - double dy1 = dy4; - double dw1 = dw3; - double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; - if (attn1 > 0) { - attn1 *= attn1; - value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1); - } - - // Contribution (1,1,1,1) - dx0 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D; - dy0 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D; - dz0 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D; - dw0 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D; - double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0; - if (attn0 > 0) { - attn0 *= attn0; - value += attn0 * attn0 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 1, dx0, dy0, dz0, dw0); - } - } else if (inSum <= 2) { // We're inside the first dispentachoron - // (Rectified 4-Simplex) - double aScore; - byte aPoint; - boolean aIsBiggerSide = true; - double bScore; - byte bPoint; - boolean bIsBiggerSide = true; - - // Decide between (1,1,0,0) and (0,0,1,1) - if (xins + yins > zins + wins) { - aScore = xins + yins; - aPoint = 0x03; - } else { - aScore = zins + wins; - aPoint = 0x0C; - } - - // Decide between (1,0,1,0) and (0,1,0,1) - if (xins + zins > yins + wins) { - bScore = xins + zins; - bPoint = 0x05; - } else { - bScore = yins + wins; - bPoint = 0x0A; - } - - // Closer between (1,0,0,1) and (0,1,1,0) will replace the further - // of a and b, if closer. - if (xins + wins > yins + zins) { - double score = xins + wins; - if (aScore >= bScore && score > bScore) { - bScore = score; - bPoint = 0x09; - } else if (aScore < bScore && score > aScore) { - aScore = score; - aPoint = 0x09; - } - } else { - double score = yins + zins; - if (aScore >= bScore && score > bScore) { - bScore = score; - bPoint = 0x06; - } else if (aScore < bScore && score > aScore) { - aScore = score; - aPoint = 0x06; - } - } - - // Decide if (1,0,0,0) is closer. - double p1 = 2 - inSum + xins; - if (aScore >= bScore && p1 > bScore) { - bScore = p1; - bPoint = 0x01; - bIsBiggerSide = false; - } else if (aScore < bScore && p1 > aScore) { - aScore = p1; - aPoint = 0x01; - aIsBiggerSide = false; - } - - // Decide if (0,1,0,0) is closer. - double p2 = 2 - inSum + yins; - if (aScore >= bScore && p2 > bScore) { - bScore = p2; - bPoint = 0x02; - bIsBiggerSide = false; - } else if (aScore < bScore && p2 > aScore) { - aScore = p2; - aPoint = 0x02; - aIsBiggerSide = false; - } - - // Decide if (0,0,1,0) is closer. - double p3 = 2 - inSum + zins; - if (aScore >= bScore && p3 > bScore) { - bScore = p3; - bPoint = 0x04; - bIsBiggerSide = false; - } else if (aScore < bScore && p3 > aScore) { - aScore = p3; - aPoint = 0x04; - aIsBiggerSide = false; - } - - // Decide if (0,0,0,1) is closer. - double p4 = 2 - inSum + wins; - if (aScore >= bScore && p4 > bScore) { - bScore = p4; - bPoint = 0x08; - bIsBiggerSide = false; - } else if (aScore < bScore && p4 > aScore) { - aScore = p4; - aPoint = 0x08; - aIsBiggerSide = false; - } - - // Where each of the two closest points are determines how the extra - // three vertices are calculated. - if (aIsBiggerSide == bIsBiggerSide) { - if (aIsBiggerSide) { // Both closest points on the bigger side - byte c1 = (byte) (aPoint | bPoint); - byte c2 = (byte) (aPoint & bPoint); - if ((c1 & 0x01) == 0) { - xsv_ext0 = xsb; - xsv_ext1 = xsb - 1; - dx_ext0 = dx0 - 3 * SQUISH_CONSTANT_4D; - dx_ext1 = dx0 + 1 - 2 * SQUISH_CONSTANT_4D; - } else { - xsv_ext0 = xsv_ext1 = xsb + 1; - dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; - dx_ext1 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; - } - - if ((c1 & 0x02) == 0) { - ysv_ext0 = ysb; - ysv_ext1 = ysb - 1; - dy_ext0 = dy0 - 3 * SQUISH_CONSTANT_4D; - dy_ext1 = dy0 + 1 - 2 * SQUISH_CONSTANT_4D; - } else { - ysv_ext0 = ysv_ext1 = ysb + 1; - dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; - dy_ext1 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; - } - - if ((c1 & 0x04) == 0) { - zsv_ext0 = zsb; - zsv_ext1 = zsb - 1; - dz_ext0 = dz0 - 3 * SQUISH_CONSTANT_4D; - dz_ext1 = dz0 + 1 - 2 * SQUISH_CONSTANT_4D; - } else { - zsv_ext0 = zsv_ext1 = zsb + 1; - dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; - dz_ext1 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; - } - - if ((c1 & 0x08) == 0) { - wsv_ext0 = wsb; - wsv_ext1 = wsb - 1; - dw_ext0 = dw0 - 3 * SQUISH_CONSTANT_4D; - dw_ext1 = dw0 + 1 - 2 * SQUISH_CONSTANT_4D; - } else { - wsv_ext0 = wsv_ext1 = wsb + 1; - dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; - dw_ext1 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; - } - - // One combination is a permutation of (0,0,0,2) based on c2 - xsv_ext2 = xsb; - ysv_ext2 = ysb; - zsv_ext2 = zsb; - wsv_ext2 = wsb; - dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D; - dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D; - dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D; - dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D; - if ((c2 & 0x01) != 0) { - xsv_ext2 += 2; - dx_ext2 -= 2; - } else if ((c2 & 0x02) != 0) { - ysv_ext2 += 2; - dy_ext2 -= 2; - } else if ((c2 & 0x04) != 0) { - zsv_ext2 += 2; - dz_ext2 -= 2; - } else { - wsv_ext2 += 2; - dw_ext2 -= 2; - } - - } else { // Both closest points on the smaller side - // One of the two extra points is (0,0,0,0) - xsv_ext2 = xsb; - ysv_ext2 = ysb; - zsv_ext2 = zsb; - wsv_ext2 = wsb; - dx_ext2 = dx0; - dy_ext2 = dy0; - dz_ext2 = dz0; - dw_ext2 = dw0; - - // Other two points are based on the omitted axes. - byte c = (byte) (aPoint | bPoint); - - if ((c & 0x01) == 0) { - xsv_ext0 = xsb - 1; - xsv_ext1 = xsb; - dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D; - dx_ext1 = dx0 - SQUISH_CONSTANT_4D; - } else { - xsv_ext0 = xsv_ext1 = xsb + 1; - dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D; - } - - if ((c & 0x02) == 0) { - ysv_ext0 = ysv_ext1 = ysb; - dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D; - if ((c & 0x01) == 0x01) { - ysv_ext0 -= 1; - dy_ext0 += 1; - } else { - ysv_ext1 -= 1; - dy_ext1 += 1; - } - } else { - ysv_ext0 = ysv_ext1 = ysb + 1; - dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D; - } - - if ((c & 0x04) == 0) { - zsv_ext0 = zsv_ext1 = zsb; - dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D; - if ((c & 0x03) == 0x03) { - zsv_ext0 -= 1; - dz_ext0 += 1; - } else { - zsv_ext1 -= 1; - dz_ext1 += 1; - } - } else { - zsv_ext0 = zsv_ext1 = zsb + 1; - dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D; - } - - if ((c & 0x08) == 0) { - wsv_ext0 = wsb; - wsv_ext1 = wsb - 1; - dw_ext0 = dw0 - SQUISH_CONSTANT_4D; - dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D; - } else { - wsv_ext0 = wsv_ext1 = wsb + 1; - dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D; - } - - } - } else { // One point on each "side" - byte c1, c2; - if (aIsBiggerSide) { - c1 = aPoint; - c2 = bPoint; - } else { - c1 = bPoint; - c2 = aPoint; - } - - // Two contributions are the bigger-sided point with each 0 - // replaced with -1. - if ((c1 & 0x01) == 0) { - xsv_ext0 = xsb - 1; - xsv_ext1 = xsb; - dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D; - dx_ext1 = dx0 - SQUISH_CONSTANT_4D; - } else { - xsv_ext0 = xsv_ext1 = xsb + 1; - dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D; - } - - if ((c1 & 0x02) == 0) { - ysv_ext0 = ysv_ext1 = ysb; - dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D; - if ((c1 & 0x01) == 0x01) { - ysv_ext0 -= 1; - dy_ext0 += 1; - } else { - ysv_ext1 -= 1; - dy_ext1 += 1; - } - } else { - ysv_ext0 = ysv_ext1 = ysb + 1; - dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D; - } - - if ((c1 & 0x04) == 0) { - zsv_ext0 = zsv_ext1 = zsb; - dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D; - if ((c1 & 0x03) == 0x03) { - zsv_ext0 -= 1; - dz_ext0 += 1; - } else { - zsv_ext1 -= 1; - dz_ext1 += 1; - } - } else { - zsv_ext0 = zsv_ext1 = zsb + 1; - dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D; - } - - if ((c1 & 0x08) == 0) { - wsv_ext0 = wsb; - wsv_ext1 = wsb - 1; - dw_ext0 = dw0 - SQUISH_CONSTANT_4D; - dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D; - } else { - wsv_ext0 = wsv_ext1 = wsb + 1; - dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D; - } - - // One contribution is a permutation of (0,0,0,2) based on the - // smaller-sided point - xsv_ext2 = xsb; - ysv_ext2 = ysb; - zsv_ext2 = zsb; - wsv_ext2 = wsb; - dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D; - dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D; - dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D; - dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D; - if ((c2 & 0x01) != 0) { - xsv_ext2 += 2; - dx_ext2 -= 2; - } else if ((c2 & 0x02) != 0) { - ysv_ext2 += 2; - dy_ext2 -= 2; - } else if ((c2 & 0x04) != 0) { - zsv_ext2 += 2; - dz_ext2 -= 2; - } else { - wsv_ext2 += 2; - dw_ext2 -= 2; - } - } - - // Contribution (1,0,0,0) - double dx1 = dx0 - 1 - SQUISH_CONSTANT_4D; - double dy1 = dy0 - 0 - SQUISH_CONSTANT_4D; - double dz1 = dz0 - 0 - SQUISH_CONSTANT_4D; - double dw1 = dw0 - 0 - SQUISH_CONSTANT_4D; - double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; - if (attn1 > 0) { - attn1 *= attn1; - value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1); - } - - // Contribution (0,1,0,0) - double dx2 = dx0 - 0 - SQUISH_CONSTANT_4D; - double dy2 = dy0 - 1 - SQUISH_CONSTANT_4D; - double dz2 = dz1; - double dw2 = dw1; - double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; - if (attn2 > 0) { - attn2 *= attn2; - value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2); - } - - // Contribution (0,0,1,0) - double dx3 = dx2; - double dy3 = dy1; - double dz3 = dz0 - 1 - SQUISH_CONSTANT_4D; - double dw3 = dw1; - double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; - if (attn3 > 0) { - attn3 *= attn3; - value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3); - } - - // Contribution (0,0,0,1) - double dx4 = dx2; - double dy4 = dy1; - double dz4 = dz1; - double dw4 = dw0 - 1 - SQUISH_CONSTANT_4D; - double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; - if (attn4 > 0) { - attn4 *= attn4; - value += attn4 * attn4 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4); - } - - // Contribution (1,1,0,0) - double dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; - double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5; - if (attn5 > 0) { - attn5 *= attn5; - value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5); - } - - // Contribution (1,0,1,0) - double dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; - double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6; - if (attn6 > 0) { - attn6 *= attn6; - value += attn6 * attn6 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6); - } - - // Contribution (1,0,0,1) - double dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; - double attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7; - if (attn7 > 0) { - attn7 *= attn7; - value += attn7 * attn7 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7); - } - - // Contribution (0,1,1,0) - double dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; - double attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8; - if (attn8 > 0) { - attn8 *= attn8; - value += attn8 * attn8 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8); - } - - // Contribution (0,1,0,1) - double dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; - double attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9; - if (attn9 > 0) { - attn9 *= attn9; - value += attn9 * attn9 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9); - } - - // Contribution (0,0,1,1) - double dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; - double attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10; - if (attn10 > 0) { - attn10 *= attn10; - value += attn10 * attn10 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10); - } - } else { // We're inside the second dispentachoron (Rectified 4-Simplex) - double aScore; - byte aPoint; - boolean aIsBiggerSide = true; - double bScore; - byte bPoint; - boolean bIsBiggerSide = true; - - // Decide between (0,0,1,1) and (1,1,0,0) - if (xins + yins < zins + wins) { - aScore = xins + yins; - aPoint = 0x0C; - } else { - aScore = zins + wins; - aPoint = 0x03; - } - - // Decide between (0,1,0,1) and (1,0,1,0) - if (xins + zins < yins + wins) { - bScore = xins + zins; - bPoint = 0x0A; - } else { - bScore = yins + wins; - bPoint = 0x05; - } - - // Closer between (0,1,1,0) and (1,0,0,1) will replace the further - // of a and b, if closer. - if (xins + wins < yins + zins) { - double score = xins + wins; - if (aScore <= bScore && score < bScore) { - bScore = score; - bPoint = 0x06; - } else if (aScore > bScore && score < aScore) { - aScore = score; - aPoint = 0x06; - } - } else { - double score = yins + zins; - if (aScore <= bScore && score < bScore) { - bScore = score; - bPoint = 0x09; - } else if (aScore > bScore && score < aScore) { - aScore = score; - aPoint = 0x09; - } - } - - // Decide if (0,1,1,1) is closer. - double p1 = 3 - inSum + xins; - if (aScore <= bScore && p1 < bScore) { - bScore = p1; - bPoint = 0x0E; - bIsBiggerSide = false; - } else if (aScore > bScore && p1 < aScore) { - aScore = p1; - aPoint = 0x0E; - aIsBiggerSide = false; - } - - // Decide if (1,0,1,1) is closer. - double p2 = 3 - inSum + yins; - if (aScore <= bScore && p2 < bScore) { - bScore = p2; - bPoint = 0x0D; - bIsBiggerSide = false; - } else if (aScore > bScore && p2 < aScore) { - aScore = p2; - aPoint = 0x0D; - aIsBiggerSide = false; - } - - // Decide if (1,1,0,1) is closer. - double p3 = 3 - inSum + zins; - if (aScore <= bScore && p3 < bScore) { - bScore = p3; - bPoint = 0x0B; - bIsBiggerSide = false; - } else if (aScore > bScore && p3 < aScore) { - aScore = p3; - aPoint = 0x0B; - aIsBiggerSide = false; - } - - // Decide if (1,1,1,0) is closer. - double p4 = 3 - inSum + wins; - if (aScore <= bScore && p4 < bScore) { - bScore = p4; - bPoint = 0x07; - bIsBiggerSide = false; - } else if (aScore > bScore && p4 < aScore) { - aScore = p4; - aPoint = 0x07; - aIsBiggerSide = false; - } - - // Where each of the two closest points are determines how the extra - // three vertices are calculated. - if (aIsBiggerSide == bIsBiggerSide) { - if (aIsBiggerSide) { // Both closest points on the bigger side - byte c1 = (byte) (aPoint & bPoint); - byte c2 = (byte) (aPoint | bPoint); - - // Two contributions are permutations of (0,0,0,1) and - // (0,0,0,2) based on c1 - xsv_ext0 = xsv_ext1 = xsb; - ysv_ext0 = ysv_ext1 = ysb; - zsv_ext0 = zsv_ext1 = zsb; - wsv_ext0 = wsv_ext1 = wsb; - dx_ext0 = dx0 - SQUISH_CONSTANT_4D; - dy_ext0 = dy0 - SQUISH_CONSTANT_4D; - dz_ext0 = dz0 - SQUISH_CONSTANT_4D; - dw_ext0 = dw0 - SQUISH_CONSTANT_4D; - dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_4D; - dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_4D; - dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_4D; - dw_ext1 = dw0 - 2 * SQUISH_CONSTANT_4D; - if ((c1 & 0x01) != 0) { - xsv_ext0 += 1; - dx_ext0 -= 1; - xsv_ext1 += 2; - dx_ext1 -= 2; - } else if ((c1 & 0x02) != 0) { - ysv_ext0 += 1; - dy_ext0 -= 1; - ysv_ext1 += 2; - dy_ext1 -= 2; - } else if ((c1 & 0x04) != 0) { - zsv_ext0 += 1; - dz_ext0 -= 1; - zsv_ext1 += 2; - dz_ext1 -= 2; - } else { - wsv_ext0 += 1; - dw_ext0 -= 1; - wsv_ext1 += 2; - dw_ext1 -= 2; - } - - // One contribution is a permutation of (1,1,1,-1) based on - // c2 - xsv_ext2 = xsb + 1; - ysv_ext2 = ysb + 1; - zsv_ext2 = zsb + 1; - wsv_ext2 = wsb + 1; - dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; - dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; - dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; - dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; - if ((c2 & 0x01) == 0) { - xsv_ext2 -= 2; - dx_ext2 += 2; - } else if ((c2 & 0x02) == 0) { - ysv_ext2 -= 2; - dy_ext2 += 2; - } else if ((c2 & 0x04) == 0) { - zsv_ext2 -= 2; - dz_ext2 += 2; - } else { - wsv_ext2 -= 2; - dw_ext2 += 2; - } - } else { // Both closest points on the smaller side - // One of the two extra points is (1,1,1,1) - xsv_ext2 = xsb + 1; - ysv_ext2 = ysb + 1; - zsv_ext2 = zsb + 1; - wsv_ext2 = wsb + 1; - dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D; - dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D; - dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D; - dw_ext2 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D; - - // Other two points are based on the shared axes. - byte c = (byte) (aPoint & bPoint); - - if ((c & 0x01) != 0) { - xsv_ext0 = xsb + 2; - xsv_ext1 = xsb + 1; - dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D; - dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; - } else { - xsv_ext0 = xsv_ext1 = xsb; - dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D; - } - - if ((c & 0x02) != 0) { - ysv_ext0 = ysv_ext1 = ysb + 1; - dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; - if ((c & 0x01) == 0) { - ysv_ext0 += 1; - dy_ext0 -= 1; - } else { - ysv_ext1 += 1; - dy_ext1 -= 1; - } - } else { - ysv_ext0 = ysv_ext1 = ysb; - dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D; - } - - if ((c & 0x04) != 0) { - zsv_ext0 = zsv_ext1 = zsb + 1; - dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; - if ((c & 0x03) == 0) { - zsv_ext0 += 1; - dz_ext0 -= 1; - } else { - zsv_ext1 += 1; - dz_ext1 -= 1; - } - } else { - zsv_ext0 = zsv_ext1 = zsb; - dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D; - } - - if ((c & 0x08) != 0) { - wsv_ext0 = wsb + 1; - wsv_ext1 = wsb + 2; - dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; - dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D; - } else { - wsv_ext0 = wsv_ext1 = wsb; - dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D; - } - } - } else { // One point on each "side" - byte c1, c2; - if (aIsBiggerSide) { - c1 = aPoint; - c2 = bPoint; - } else { - c1 = bPoint; - c2 = aPoint; - } - - // Two contributions are the bigger-sided point with each 1 - // replaced with 2. - if ((c1 & 0x01) != 0) { - xsv_ext0 = xsb + 2; - xsv_ext1 = xsb + 1; - dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D; - dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; - } else { - xsv_ext0 = xsv_ext1 = xsb; - dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D; - } - - if ((c1 & 0x02) != 0) { - ysv_ext0 = ysv_ext1 = ysb + 1; - dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; - if ((c1 & 0x01) == 0) { - ysv_ext0 += 1; - dy_ext0 -= 1; - } else { - ysv_ext1 += 1; - dy_ext1 -= 1; - } - } else { - ysv_ext0 = ysv_ext1 = ysb; - dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D; - } - - if ((c1 & 0x04) != 0) { - zsv_ext0 = zsv_ext1 = zsb + 1; - dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; - if ((c1 & 0x03) == 0) { - zsv_ext0 += 1; - dz_ext0 -= 1; - } else { - zsv_ext1 += 1; - dz_ext1 -= 1; - } - } else { - zsv_ext0 = zsv_ext1 = zsb; - dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D; - } - - if ((c1 & 0x08) != 0) { - wsv_ext0 = wsb + 1; - wsv_ext1 = wsb + 2; - dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; - dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D; - } else { - wsv_ext0 = wsv_ext1 = wsb; - dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D; - } - - // One contribution is a permutation of (1,1,1,-1) based on the - // smaller-sided point - xsv_ext2 = xsb + 1; - ysv_ext2 = ysb + 1; - zsv_ext2 = zsb + 1; - wsv_ext2 = wsb + 1; - dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; - dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; - dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; - dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; - if ((c2 & 0x01) == 0) { - xsv_ext2 -= 2; - dx_ext2 += 2; - } else if ((c2 & 0x02) == 0) { - ysv_ext2 -= 2; - dy_ext2 += 2; - } else if ((c2 & 0x04) == 0) { - zsv_ext2 -= 2; - dz_ext2 += 2; - } else { - wsv_ext2 -= 2; - dw_ext2 += 2; - } - } - - // Contribution (1,1,1,0) - double dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; - double dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; - double dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; - double dw4 = dw0 - 3 * SQUISH_CONSTANT_4D; - double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; - if (attn4 > 0) { - attn4 *= attn4; - value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4); - } - - // Contribution (1,1,0,1) - double dx3 = dx4; - double dy3 = dy4; - double dz3 = dz0 - 3 * SQUISH_CONSTANT_4D; - double dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; - double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; - if (attn3 > 0) { - attn3 *= attn3; - value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3); - } - - // Contribution (1,0,1,1) - double dx2 = dx4; - double dy2 = dy0 - 3 * SQUISH_CONSTANT_4D; - double dz2 = dz4; - double dw2 = dw3; - double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; - if (attn2 > 0) { - attn2 *= attn2; - value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2); - } - - // Contribution (0,1,1,1) - double dx1 = dx0 - 3 * SQUISH_CONSTANT_4D; - double dz1 = dz4; - double dy1 = dy4; - double dw1 = dw3; - double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; - if (attn1 > 0) { - attn1 *= attn1; - value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1); - } - - // Contribution (1,1,0,0) - double dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; - double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5; - if (attn5 > 0) { - attn5 *= attn5; - value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5); - } - - // Contribution (1,0,1,0) - double dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; - double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6; - if (attn6 > 0) { - attn6 *= attn6; - value += attn6 * attn6 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6); - } - - // Contribution (1,0,0,1) - double dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; - double attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7; - if (attn7 > 0) { - attn7 *= attn7; - value += attn7 * attn7 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7); - } - - // Contribution (0,1,1,0) - double dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; - double attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8; - if (attn8 > 0) { - attn8 *= attn8; - value += attn8 * attn8 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8); - } - - // Contribution (0,1,0,1) - double dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; - double attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9; - if (attn9 > 0) { - attn9 *= attn9; - value += attn9 * attn9 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9); - } - - // Contribution (0,0,1,1) - double dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; - double dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; - double dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; - double attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10; - if (attn10 > 0) { - attn10 *= attn10; - value += attn10 * attn10 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10); - } - } - - // First extra vertex - double attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0 - dw_ext0 * dw_ext0; - if (attn_ext0 > 0) { - attn_ext0 *= attn_ext0; - value += attn_ext0 * attn_ext0 - * extrapolate(xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0, dx_ext0, dy_ext0, dz_ext0, dw_ext0); - } - - // Second extra vertex - double attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1 - dw_ext1 * dw_ext1; - if (attn_ext1 > 0) { - attn_ext1 *= attn_ext1; - value += attn_ext1 * attn_ext1 - * extrapolate(xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1, dx_ext1, dy_ext1, dz_ext1, dw_ext1); - } - - // Third extra vertex - double attn_ext2 = 2 - dx_ext2 * dx_ext2 - dy_ext2 * dy_ext2 - dz_ext2 * dz_ext2 - dw_ext2 * dw_ext2; - if (attn_ext2 > 0) { - attn_ext2 *= attn_ext2; - value += attn_ext2 * attn_ext2 - * extrapolate(xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2, dx_ext2, dy_ext2, dz_ext2, dw_ext2); - } - - return value / NORM_CONSTANT_4D; - } - - private double extrapolate(int xsb, int ysb, double dx, double dy) { - int index = perm[(perm[xsb & 0xFF] + ysb) & 0xFF] & 0x0E; - return gradients2D[index] * dx + gradients2D[index + 1] * dy; - } - - private double extrapolate(int xsb, int ysb, int zsb, double dx, double dy, double dz) { - int index = permGradIndex3D[(perm[(perm[xsb & 0xFF] + ysb) & 0xFF] + zsb) & 0xFF]; - return gradients3D[index] * dx + gradients3D[index + 1] * dy + gradients3D[index + 2] * dz; - } - - private double extrapolate(int xsb, int ysb, int zsb, int wsb, double dx, double dy, double dz, double dw) { - int index = perm[(perm[(perm[(perm[xsb & 0xFF] + ysb) & 0xFF] + zsb) & 0xFF] + wsb) & 0xFF] & 0xFC; - return gradients4D[index] * dx + gradients4D[index + 1] * dy + gradients4D[index + 2] * dz - + gradients4D[index + 3] * dw; - } - - private static int fastFloor(double x) { - int xi = (int) x; - return x < xi ? xi - 1 : xi; - } - - // Gradients for 2D. They approximate the directions to the - // vertices of an octagon from the center. - private static byte[] gradients2D = new byte[] { 5, 2, 2, 5, -5, 2, -2, 5, 5, -2, 2, -5, -5, -2, -2, -5, }; - - // Gradients for 3D. They approximate the directions to the - // vertices of a rhombicuboctahedron from the center, skewed so - // that the triangular and square facets can be inscribed inside - // circles of the same radius. - private static byte[] gradients3D = new byte[] { -11, 4, 4, -4, 11, 4, -4, 4, 11, 11, 4, 4, 4, 11, 4, 4, 4, 11, -11, - -4, 4, -4, -11, 4, -4, -4, 11, 11, -4, 4, 4, -11, 4, 4, -4, 11, -11, 4, -4, -4, 11, -4, -4, 4, -11, 11, 4, - -4, 4, 11, -4, 4, 4, -11, -11, -4, -4, -4, -11, -4, -4, -4, -11, 11, -4, -4, 4, -11, -4, 4, -4, -11, }; - - // Gradients for 4D. They approximate the directions to the - // vertices of a disprismatotesseractihexadecachoron from the center, - // skewed so that the tetrahedral and cubic facets can be inscribed inside - // spheres of the same radius. - private static byte[] gradients4D = new byte[] { 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, -3, 1, 1, 1, -1, 3, - 1, 1, -1, 1, 3, 1, -1, 1, 1, 3, 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, 1, 1, -1, 1, 3, -3, -1, 1, 1, -1, -3, 1, - 1, -1, -1, 3, 1, -1, -1, 1, 3, 3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, -3, 1, -1, 1, -1, 3, -1, - 1, -1, 1, -3, 1, -1, 1, -1, 3, 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, -3, -1, -1, 1, -1, - -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, 3, 1, 1, -1, 1, 3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3, -3, 1, 1, -1, - -1, 3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3, 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, -3, -1, 1, - -1, -1, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, 3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, -3, - 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, -1, 1, -1, - -1, -3, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, }; -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/particle/FireflyParticle.java b/src/main/java/ru/betterend/particle/FireflyParticle.java deleted file mode 100644 index 64624178..00000000 --- a/src/main/java/ru/betterend/particle/FireflyParticle.java +++ /dev/null @@ -1,81 +0,0 @@ -package ru.betterend.particle; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.particle.Particle; -import net.minecraft.client.particle.ParticleProvider; -import net.minecraft.client.particle.SimpleAnimatedParticle; -import net.minecraft.client.particle.SpriteSet; -import net.minecraft.core.particles.SimpleParticleType; -import net.minecraft.util.Mth; -import ru.bclib.util.MHelper; - -@Environment(EnvType.CLIENT) -public class FireflyParticle extends SimpleAnimatedParticle { - private double preVX; - private double preVY; - private double preVZ; - private double nextVX; - private double nextVY; - private double nextVZ; - - protected FireflyParticle(ClientLevel world, double x, double y, double z, SpriteSet sprites, double r, double g, double b) { - super(world, x, y, z, sprites, 0); - setSprite(sprites.get(random)); - this.lifetime = MHelper.randRange(150, 300, random); - this.quadSize = MHelper.randRange(0.05F, 0.15F, random); - this.setFadeColor(15916745); - this.setSpriteFromAge(sprites); - this.setAlpha(0); - - preVX = random.nextGaussian() * 0.02; - preVY = random.nextGaussian() * 0.02; - preVZ = random.nextGaussian() * 0.02; - - nextVX = random.nextGaussian() * 0.02; - nextVY = random.nextGaussian() * 0.02; - nextVZ = random.nextGaussian() * 0.02; - } - - @Override - public void tick() { - int ticks = this.age & 31; - if (ticks == 0) { - preVX = nextVX; - preVY = nextVY; - preVZ = nextVZ; - nextVX = random.nextGaussian() * 0.02; - nextVY = random.nextGaussian() * 0.02; - nextVZ = random.nextGaussian() * 0.02; - } - double delta = (double) ticks / 31.0; - - this.xd = Mth.lerp(delta, preVX, nextVX); - this.yd = Mth.lerp(delta, preVY, nextVY); - this.zd = Mth.lerp(delta, preVZ, nextVZ); - - if (this.age <= 60) { - this.setAlpha(this.age / 60F); - } - else if (this.age > lifetime - 60) { - this.setAlpha((lifetime - this.age) / 60F); - } - - super.tick(); - } - - @Environment(EnvType.CLIENT) - public static class FireflyParticleFactory implements ParticleProvider { - private final SpriteSet sprites; - - public FireflyParticleFactory(SpriteSet sprites) { - this.sprites = sprites; - } - - @Override - public Particle createParticle(SimpleParticleType type, ClientLevel world, double x, double y, double z, double vX, double vY, double vZ) { - return new FireflyParticle(world, x, y, z, sprites, 1, 1, 1); - } - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/particle/InfusionParticle.java b/src/main/java/ru/betterend/particle/InfusionParticle.java deleted file mode 100644 index 8bdac965..00000000 --- a/src/main/java/ru/betterend/particle/InfusionParticle.java +++ /dev/null @@ -1,62 +0,0 @@ -package ru.betterend.particle; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.particle.Particle; -import net.minecraft.client.particle.ParticleProvider; -import net.minecraft.client.particle.ParticleRenderType; -import net.minecraft.client.particle.SpriteSet; -import net.minecraft.client.particle.TextureSheetParticle; - -public class InfusionParticle extends TextureSheetParticle { - - private final SpriteSet spriteProvider; - - public InfusionParticle(ClientLevel clientWorld, double x, double y, double z, double velocityX, double velocityY, double velocityZ, float[] palette, SpriteSet spriteProvider) { - super(clientWorld, x, y, z, 0.0, 0.0, 0.0); - this.setSpriteFromAge(spriteProvider); - this.spriteProvider = spriteProvider; - this.setColor(palette[0], palette[1], palette[2]); - this.setAlpha(palette[3]); - this.xd = velocityX * 0.1D; - this.yd = velocityY * 0.1D; - this.zd = velocityZ * 0.1D; - this.lifetime = (int) (3.0F / (this.random.nextFloat() * 0.9F + 0.1F)); - this.quadSize *= 0.9F; - } - - @Override - public ParticleRenderType getRenderType() { - return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; - } - - @Override - public void tick() { - this.xo = this.x; - this.yo = this.y; - this.zo = this.z; - if (this.age++ >= this.lifetime) { - this.remove(); - } else { - this.setSpriteFromAge(spriteProvider); - double velocityX = 2.0D * this.xd * this.random.nextDouble(); - double velocityY = 3.0D * this.yd * this.random.nextDouble(); - double velocityZ = 2.0D * this.zd * this.random.nextDouble(); - this.move(velocityX, velocityY, velocityZ); - } - } - - @Environment(EnvType.CLIENT) - public static class InfusionFactory implements ParticleProvider { - private final SpriteSet spriteProvider; - - public InfusionFactory(SpriteSet spriteProvider) { - this.spriteProvider = spriteProvider; - } - - public Particle createParticle(InfusionParticleType particleType, ClientLevel clientWorld, double d, double e, double f, double g, double h, double i) { - return new InfusionParticle(clientWorld, d, e, f, g, h, i, particleType.getPalette(), this.spriteProvider); - } - } -} diff --git a/src/main/java/ru/betterend/particle/InfusionParticleType.java b/src/main/java/ru/betterend/particle/InfusionParticleType.java deleted file mode 100644 index 672f3ab9..00000000 --- a/src/main/java/ru/betterend/particle/InfusionParticleType.java +++ /dev/null @@ -1,76 +0,0 @@ -package ru.betterend.particle; - -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.serialization.Codec; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.commands.arguments.item.ItemInput; -import net.minecraft.commands.arguments.item.ItemParser; -import net.minecraft.core.Registry; -import net.minecraft.core.particles.ParticleOptions; -import net.minecraft.core.particles.ParticleType; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.world.item.ItemStack; -import ru.bclib.util.ColorUtil; -import ru.betterend.registry.EndParticles; - -public class InfusionParticleType extends ParticleType implements ParticleOptions { - public static final Codec CODEC = ItemStack.CODEC.xmap(itemStack -> { - return new InfusionParticleType(EndParticles.INFUSION, itemStack); - }, infusionParticleType -> { - return infusionParticleType.itemStack; - }); - public static final ParticleOptions.Deserializer PARAMETERS_FACTORY = new ParticleOptions.Deserializer() { - public InfusionParticleType fromCommand(ParticleType particleType, StringReader stringReader) throws CommandSyntaxException { - stringReader.expect(' '); - ItemParser itemStringReader = new ItemParser(stringReader, false).parse(); - ItemStack itemStack = new ItemInput(itemStringReader.getItem(), itemStringReader.getNbt()).createItemStack(1, false); - return new InfusionParticleType(particleType, itemStack); - } - - public InfusionParticleType fromNetwork(ParticleType particleType, FriendlyByteBuf packetByteBuf) { - return new InfusionParticleType(particleType, packetByteBuf.readItem()); - } - }; - - private ParticleType type; - private ItemStack itemStack; - - public InfusionParticleType(ParticleType particleType, ItemStack stack) { - super(true, PARAMETERS_FACTORY); - this.type = particleType; - this.itemStack = stack; - } - - public InfusionParticleType(ItemStack stack) { - this(EndParticles.INFUSION, stack); - } - - @Environment(EnvType.CLIENT) - public float[] getPalette() { - int color = ColorUtil.extractColor(itemStack.getItem()); - return ColorUtil.toFloatArray(color); - } - - @Override - public ParticleType getType() { - return this.type; - } - - @Override - public void writeToNetwork(FriendlyByteBuf buffer) { - buffer.writeItem(itemStack); - } - - @Override - public String writeToString() { - return Registry.PARTICLE_TYPE.getKey(this).toString(); - } - - @Override - public Codec codec() { - return CODEC; - } -} diff --git a/src/main/java/ru/betterend/particle/ParticleBlackSpore.java b/src/main/java/ru/betterend/particle/ParticleBlackSpore.java deleted file mode 100644 index 9278a0c7..00000000 --- a/src/main/java/ru/betterend/particle/ParticleBlackSpore.java +++ /dev/null @@ -1,92 +0,0 @@ -package ru.betterend.particle; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.particle.Particle; -import net.minecraft.client.particle.ParticleProvider; -import net.minecraft.client.particle.ParticleRenderType; -import net.minecraft.client.particle.SimpleAnimatedParticle; -import net.minecraft.client.particle.SpriteSet; -import net.minecraft.core.particles.SimpleParticleType; -import net.minecraft.util.Mth; -import ru.bclib.util.MHelper; - -@Environment(EnvType.CLIENT) -public class ParticleBlackSpore extends SimpleAnimatedParticle { - private double preVX; - private double preVY; - private double preVZ; - private double nextVX; - private double nextVY; - private double nextVZ; - - protected ParticleBlackSpore(ClientLevel world, double x, double y, double z, double r, double g, double b, SpriteSet sprites) { - super(world, x, y, z, sprites, 0); - setSprite(sprites.get(random)); - - this.lifetime = MHelper.randRange(30, 60, random); - this.quadSize = MHelper.randRange(0.05F, 0.15F, random); - this.setColor(1, 1, 1); - this.setAlpha(0); - - preVX = random.nextGaussian() * 0.015; - preVY = 0; - preVZ = random.nextGaussian() * 0.015; - - nextVX = random.nextGaussian() * 0.015; - nextVY = random.nextFloat() * 0.02 + 0.01; - nextVZ = random.nextGaussian() * 0.015; - } - - @Override - public void tick() { - int ticks = this.age & 15; - if (ticks == 0) { - preVX = nextVX; - preVY = nextVY; - preVZ = nextVZ; - nextVX = random.nextGaussian() * 0.015; - nextVY = random.nextFloat() * 0.02 + 0.01; - nextVZ = random.nextGaussian() * 0.015; - } - double delta = (double) ticks / 15.0; - - if (this.age <= 15) { - this.setAlpha(this.age / 15F); - } - else if (this.age >= this.lifetime - 15) { - this.setAlpha((this.lifetime - this.age) / 15F); - } - - if (this.age >= this.lifetime) { - this.remove(); - } - - this.xd = Mth.lerp(delta, preVX, nextVX); - this.yd = Mth.lerp(delta, preVY, nextVY); - this.zd = Mth.lerp(delta, preVZ, nextVZ); - - super.tick(); - } - - @Override - public ParticleRenderType getRenderType() { - return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; - } - - @Environment(EnvType.CLIENT) - public static class FactoryBlackSpore implements ParticleProvider { - - private final SpriteSet sprites; - - public FactoryBlackSpore(SpriteSet sprites) { - this.sprites = sprites; - } - - @Override - public Particle createParticle(SimpleParticleType type, ClientLevel world, double x, double y, double z, double vX, double vY, double vZ) { - return new ParticleBlackSpore(world, x, y, z, 1, 1, 1, sprites); - } - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/particle/ParticleGeyser.java b/src/main/java/ru/betterend/particle/ParticleGeyser.java deleted file mode 100644 index 4c7cb531..00000000 --- a/src/main/java/ru/betterend/particle/ParticleGeyser.java +++ /dev/null @@ -1,79 +0,0 @@ -package ru.betterend.particle; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.particle.Particle; -import net.minecraft.client.particle.ParticleProvider; -import net.minecraft.client.particle.ParticleRenderType; -import net.minecraft.client.particle.SpriteSet; -import net.minecraft.client.particle.TextureSheetParticle; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.particles.SimpleParticleType; -import ru.bclib.util.MHelper; - -@Environment(EnvType.CLIENT) -public class ParticleGeyser extends TextureSheetParticle { - private MutableBlockPos mut = new MutableBlockPos(); - private boolean changeDir = false; - private boolean check = true; - - protected ParticleGeyser(ClientLevel world, double x, double y, double z, double vx, double vy, double vz, SpriteSet sprites) { - super(world, x, y, z, vx, vy, vz); - pickSprite(sprites); - this.lifetime = MHelper.randRange(400, 800, random); - this.quadSize = MHelper.randRange(0.5F, 1.0F, random); - this.xd = vx; - this.zd = vz; - this.yo = y - 0.125; - } - - @Override - public void tick() { - - if (this.yo == this.y || this.age > this.lifetime) { - this.remove(); - } - else { - if (this.age >= this.lifetime - 200) { - this.setAlpha((this.lifetime - this.age) / 200F); - } - - this.quadSize += 0.005F; - this.yd = 0.125; - - if (changeDir) { - changeDir = false; - check = false; - this.xd += MHelper.randRange(-0.2, 0.2, random); - this.zd += MHelper.randRange(-0.2, 0.2, random); - } - else if (check) { - changeDir = level.getBlockState(mut.set(x, y, z)).getFluidState().isEmpty(); - this.xd = 0; - this.zd = 0; - } - } - super.tick(); - } - - @Override - public ParticleRenderType getRenderType() { - return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; - } - - @Environment(EnvType.CLIENT) - public static class FactoryGeyser implements ParticleProvider { - - private final SpriteSet sprites; - - public FactoryGeyser(SpriteSet sprites) { - this.sprites = sprites; - } - - @Override - public Particle createParticle(SimpleParticleType type, ClientLevel world, double x, double y, double z, double vX, double vY, double vZ) { - return new ParticleGeyser(world, x, y, z, 0, 0.125, 0, sprites); - } - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/particle/ParticleGlowingSphere.java b/src/main/java/ru/betterend/particle/ParticleGlowingSphere.java deleted file mode 100644 index 8edea37a..00000000 --- a/src/main/java/ru/betterend/particle/ParticleGlowingSphere.java +++ /dev/null @@ -1,76 +0,0 @@ -package ru.betterend.particle; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.particle.Particle; -import net.minecraft.client.particle.ParticleProvider; -import net.minecraft.client.particle.SimpleAnimatedParticle; -import net.minecraft.client.particle.SpriteSet; -import net.minecraft.core.particles.SimpleParticleType; -import net.minecraft.util.Mth; -import ru.bclib.util.MHelper; - -@Environment(EnvType.CLIENT) -public class ParticleGlowingSphere extends SimpleAnimatedParticle { - private int ticks; - private double preVX; - private double preVY; - private double preVZ; - private double nextVX; - private double nextVY; - private double nextVZ; - - protected ParticleGlowingSphere(ClientLevel world, double x, double y, double z, SpriteSet sprites, double r, double g, double b) { - super(world, x, y, z, sprites, 0); - setSprite(sprites.get(random)); - this.lifetime = MHelper.randRange(150, 300, random); - this.quadSize = MHelper.randRange(0.05F, 0.15F, random); - this.setFadeColor(15916745); - this.setSpriteFromAge(sprites); - - preVX = random.nextGaussian() * 0.02; - preVY = random.nextGaussian() * 0.02; - preVZ = random.nextGaussian() * 0.02; - - nextVX = random.nextGaussian() * 0.02; - nextVY = random.nextGaussian() * 0.02; - nextVZ = random.nextGaussian() * 0.02; - } - - @Override - public void tick() { - ticks ++; - if (ticks > 30) { - preVX = nextVX; - preVY = nextVY; - preVZ = nextVZ; - nextVX = random.nextGaussian() * 0.02; - nextVY = random.nextGaussian() * 0.02; - nextVZ = random.nextGaussian() * 0.02; - ticks = 0; - } - double delta = (double) ticks / 30.0; - - this.xd = Mth.lerp(delta, preVX, nextVX); - this.yd = Mth.lerp(delta, preVY, nextVY); - this.zd = Mth.lerp(delta, preVZ, nextVZ); - - super.tick(); - } - - @Environment(EnvType.CLIENT) - public static class FactoryGlowingSphere implements ParticleProvider { - - private final SpriteSet sprites; - - public FactoryGlowingSphere(SpriteSet sprites) { - this.sprites = sprites; - } - - @Override - public Particle createParticle(SimpleParticleType type, ClientLevel world, double x, double y, double z, double vX, double vY, double vZ) { - return new ParticleGlowingSphere(world, x, y, z, sprites, 1, 1, 1); - } - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/particle/ParticleJungleSpore.java b/src/main/java/ru/betterend/particle/ParticleJungleSpore.java deleted file mode 100644 index 25e3e916..00000000 --- a/src/main/java/ru/betterend/particle/ParticleJungleSpore.java +++ /dev/null @@ -1,70 +0,0 @@ -package ru.betterend.particle; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.particle.Particle; -import net.minecraft.client.particle.ParticleProvider; -import net.minecraft.client.particle.SimpleAnimatedParticle; -import net.minecraft.client.particle.SpriteSet; -import net.minecraft.core.particles.SimpleParticleType; -import ru.bclib.util.MHelper; - -@Environment(EnvType.CLIENT) -public class ParticleJungleSpore extends SimpleAnimatedParticle { - - protected ParticleJungleSpore(ClientLevel world, double x, double y, double z, SpriteSet sprites, double r, double g, double b) { - super(world, x, y, z, sprites, 0); - setSprite(sprites.get(random)); - this.lifetime = MHelper.randRange(150, 300, random); - this.quadSize = MHelper.randRange(0.05F, 0.15F, random); - this.setFadeColor(15916745); - this.setSpriteFromAge(sprites); - this.setAlpha(0); - } - - @Override - public void tick() { - super.tick(); - - int ticks = this.age % 30; - if (ticks == 0) { - this.xd = random.nextGaussian() * 0.02; - this.yd = random.nextFloat() * 0.02 + 0.02; - this.zd = random.nextGaussian() * 0.02; - ticks = 0; - } - - if (this.age <= 30) { - float delta = ticks / 30F; - this.setAlpha(delta); - } - else if (this.age >= this.lifetime) { - this.setAlpha(0); - } - else if (this.age >= this.lifetime - 30) { - this.setAlpha((this.lifetime - this.age) / 30F); - } - else { - this.setAlpha(1); - } - - this.yd -= 0.001F; - this.xd *= 0.99F; - this.zd *= 0.99F; - } - - @Environment(EnvType.CLIENT) - public static class FactoryJungleSpore implements ParticleProvider { - private final SpriteSet sprites; - - public FactoryJungleSpore(SpriteSet sprites) { - this.sprites = sprites; - } - - @Override - public Particle createParticle(SimpleParticleType type, ClientLevel world, double x, double y, double z, double vX, double vY, double vZ) { - return new ParticleJungleSpore(world, x, y, z, sprites, 1, 1, 1); - } - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/particle/ParticleSnowflake.java b/src/main/java/ru/betterend/particle/ParticleSnowflake.java deleted file mode 100644 index e5f2d921..00000000 --- a/src/main/java/ru/betterend/particle/ParticleSnowflake.java +++ /dev/null @@ -1,96 +0,0 @@ -package ru.betterend.particle; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.particle.Particle; -import net.minecraft.client.particle.ParticleProvider; -import net.minecraft.client.particle.ParticleRenderType; -import net.minecraft.client.particle.SpriteSet; -import net.minecraft.client.particle.TextureSheetParticle; -import net.minecraft.core.particles.SimpleParticleType; -import net.minecraft.util.Mth; -import ru.bclib.util.MHelper; - -@Environment(EnvType.CLIENT) -public class ParticleSnowflake extends TextureSheetParticle { - private int ticks; - private double preVX; - private double preVY; - private double preVZ; - private double nextVX; - private double nextVY; - private double nextVZ; - - protected ParticleSnowflake(ClientLevel world, double x, double y, double z, double r, double g, double b, SpriteSet sprites) { - super(world, x, y, z, r, g, b); - pickSprite(sprites); - - this.lifetime = MHelper.randRange(150, 300, random); - this.quadSize = MHelper.randRange(0.05F, 0.2F, random); - this.setAlpha(0F); - - preVX = random.nextGaussian() * 0.015; - preVY = random.nextGaussian() * 0.015; - preVZ = random.nextGaussian() * 0.015; - - nextVX = random.nextGaussian() * 0.015; - nextVY = random.nextGaussian() * 0.015; - nextVZ = random.nextGaussian() * 0.015; - } - - @Override - public void tick() { - ticks ++; - if (ticks > 200) { - preVX = nextVX; - preVY = nextVY; - preVZ = nextVZ; - nextVX = random.nextGaussian() * 0.015; - nextVY = random.nextGaussian() * 0.015; - nextVZ = random.nextGaussian() * 0.015; - if (random.nextInt(4) == 0) { - nextVY = Math.abs(nextVY); - } - ticks = 0; - } - double delta = (double) ticks / 200.0; - - if (this.age <= 40) { - this.setAlpha(this.age / 40F); - } - else if (this.age >= this.lifetime - 40) { - this.setAlpha((this.lifetime - this.age) / 40F); - } - - if (this.age >= this.lifetime) { - this.remove(); - } - - this.xd = Mth.lerp(delta, preVX, nextVX); - this.yd = Mth.lerp(delta, preVY, nextVY); - this.zd = Mth.lerp(delta, preVZ, nextVZ); - - super.tick(); - } - - @Override - public ParticleRenderType getRenderType() { - return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; - } - - @Environment(EnvType.CLIENT) - public static class FactorySnowflake implements ParticleProvider { - - private final SpriteSet sprites; - - public FactorySnowflake(SpriteSet sprites) { - this.sprites = sprites; - } - - @Override - public Particle createParticle(SimpleParticleType type, ClientLevel world, double x, double y, double z, double vX, double vY, double vZ) { - return new ParticleSnowflake(world, x, y, z, 1, 1, 1, sprites); - } - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/particle/ParticleSulphur.java b/src/main/java/ru/betterend/particle/ParticleSulphur.java deleted file mode 100644 index 049dbe97..00000000 --- a/src/main/java/ru/betterend/particle/ParticleSulphur.java +++ /dev/null @@ -1,97 +0,0 @@ -package ru.betterend.particle; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.particle.Particle; -import net.minecraft.client.particle.ParticleProvider; -import net.minecraft.client.particle.ParticleRenderType; -import net.minecraft.client.particle.SpriteSet; -import net.minecraft.client.particle.TextureSheetParticle; -import net.minecraft.core.particles.SimpleParticleType; -import net.minecraft.util.Mth; -import ru.bclib.util.MHelper; - -@Environment(EnvType.CLIENT) -public class ParticleSulphur extends TextureSheetParticle { - private int ticks; - private double preVX; - private double preVY; - private double preVZ; - private double nextVX; - private double nextVY; - private double nextVZ; - - protected ParticleSulphur(ClientLevel world, double x, double y, double z, double r, double g, double b, SpriteSet sprites) { - super(world, x, y, z, r, g, b); - pickSprite(sprites); - - this.lifetime = MHelper.randRange(150, 300, random); - this.quadSize = MHelper.randRange(0.05F, 0.15F, random); - this.setColor(1, 1, 1); - this.setAlpha(0); - - preVX = random.nextGaussian() * 0.015; - preVY = random.nextGaussian() * 0.015; - preVZ = random.nextGaussian() * 0.015; - - nextVX = random.nextGaussian() * 0.015; - nextVY = random.nextGaussian() * 0.015; - nextVZ = random.nextGaussian() * 0.015; - } - - @Override - public void tick() { - ticks ++; - if (ticks > 200) { - preVX = nextVX; - preVY = nextVY; - preVZ = nextVZ; - nextVX = random.nextGaussian() * 0.015; - nextVY = random.nextGaussian() * 0.015; - nextVZ = random.nextGaussian() * 0.015; - if (random.nextInt(4) == 0) { - nextVY = Math.abs(nextVY); - } - ticks = 0; - } - double delta = (double) ticks / 200.0; - - if (this.age <= 40) { - this.setAlpha(this.age / 40F); - } - else if (this.age >= this.lifetime - 40) { - this.setAlpha((this.lifetime - this.age) / 40F); - } - - if (this.age >= this.lifetime) { - this.remove(); - } - - this.xd = Mth.lerp(delta, preVX, nextVX); - this.yd = Mth.lerp(delta, preVY, nextVY); - this.zd = Mth.lerp(delta, preVZ, nextVZ); - - super.tick(); - } - - @Override - public ParticleRenderType getRenderType() { - return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; - } - - @Environment(EnvType.CLIENT) - public static class FactorySulphur implements ParticleProvider { - - private final SpriteSet sprites; - - public FactorySulphur(SpriteSet sprites) { - this.sprites = sprites; - } - - @Override - public Particle createParticle(SimpleParticleType type, ClientLevel world, double x, double y, double z, double vX, double vY, double vZ) { - return new ParticleSulphur(world, x, y, z, 1, 1, 1, sprites); - } - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/particle/ParticleTenaneaPetal.java b/src/main/java/ru/betterend/particle/ParticleTenaneaPetal.java deleted file mode 100644 index 7bcb882d..00000000 --- a/src/main/java/ru/betterend/particle/ParticleTenaneaPetal.java +++ /dev/null @@ -1,111 +0,0 @@ -package ru.betterend.particle; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.color.block.BlockColor; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.particle.Particle; -import net.minecraft.client.particle.ParticleProvider; -import net.minecraft.client.particle.ParticleRenderType; -import net.minecraft.client.particle.SpriteSet; -import net.minecraft.client.particle.TextureSheetParticle; -import net.minecraft.core.BlockPos; -import net.minecraft.core.particles.SimpleParticleType; -import net.minecraft.util.Mth; -import ru.bclib.interfaces.IColorProvider; -import ru.bclib.util.MHelper; -import ru.betterend.registry.EndBlocks; - -@Environment(EnvType.CLIENT) -public class ParticleTenaneaPetal extends TextureSheetParticle { - private static BlockColor provider; - - private double preVX; - private double preVY; - private double preVZ; - private double nextVX; - private double nextVY; - private double nextVZ; - - protected ParticleTenaneaPetal(ClientLevel world, double x, double y, double z, double r, double g, double b, SpriteSet sprites) { - super(world, x, y, z, r, g, b); - pickSprite(sprites); - - if (provider == null) { - IColorProvider block = (IColorProvider) EndBlocks.TENANEA_FLOWERS; - provider = block.getProvider(); - } - int color = provider.getColor(null, null, new BlockPos(x, y, z), 0); - this.rCol = ((color >> 16) & 255) / 255F; - this.gCol = ((color >> 8) & 255) / 255F; - this.bCol = ((color) & 255) / 255F; - - this.lifetime = MHelper.randRange(120, 200, random); - this.quadSize = MHelper.randRange(0.05F, 0.15F, random); - this.setAlpha(0); - - preVX = 0; - preVY = 0; - preVZ = 0; - - nextVX = random.nextGaussian() * 0.02; - nextVY = -random.nextDouble() * 0.02 - 0.02; - nextVZ = random.nextGaussian() * 0.02; - } - - @Override - public int getLightColor(float tint) { - return 15728880; - } - - @Override - public void tick() { - int ticks = this.age & 63; - if (ticks == 0) { - preVX = nextVX; - preVY = nextVY; - preVZ = nextVZ; - nextVX = random.nextGaussian() * 0.02; - nextVY = -random.nextDouble() * 0.02 - 0.02; - nextVZ = random.nextGaussian() * 0.02; - } - double delta = (double) ticks / 63.0; - - if (this.age <= 40) { - this.setAlpha(this.age / 40F); - } - else if (this.age >= this.lifetime - 40) { - this.setAlpha((this.lifetime - this.age) / 40F); - } - - if (this.age >= this.lifetime) { - this.remove(); - } - - this.xd = Mth.lerp(delta, preVX, nextVX); - this.yd = Mth.lerp(delta, preVY, nextVY); - this.zd = Mth.lerp(delta, preVZ, nextVZ); - - super.tick(); - } - - @Override - public ParticleRenderType getRenderType() { - return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; - } - - @Environment(EnvType.CLIENT) - public static class FactoryTenaneaPetal implements ParticleProvider { - - private final SpriteSet sprites; - - public FactoryTenaneaPetal(SpriteSet sprites) { - this.sprites = sprites; - } - - @Override - public Particle createParticle(SimpleParticleType type, ClientLevel world, double x, double y, double z, double vX, double vY, double vZ) { - return new ParticleTenaneaPetal(world, x, y, z, 1, 1, 1, sprites); - } - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/particle/PaticlePortalSphere.java b/src/main/java/ru/betterend/particle/PaticlePortalSphere.java deleted file mode 100644 index 1d0afdd7..00000000 --- a/src/main/java/ru/betterend/particle/PaticlePortalSphere.java +++ /dev/null @@ -1,76 +0,0 @@ -package ru.betterend.particle; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.particle.Particle; -import net.minecraft.client.particle.ParticleProvider; -import net.minecraft.client.particle.SimpleAnimatedParticle; -import net.minecraft.client.particle.SpriteSet; -import net.minecraft.core.particles.SimpleParticleType; -import net.minecraft.util.Mth; -import ru.bclib.util.MHelper; - -public class PaticlePortalSphere extends SimpleAnimatedParticle { - private int ticks; - private double preVX; - private double preVY; - private double preVZ; - private double nextVX; - private double nextVY; - private double nextVZ; - - public PaticlePortalSphere(ClientLevel world, double x, double y, double z, SpriteSet spriteProvider) { - super(world, x, y, z, spriteProvider, 0); - setSprite(spriteProvider.get(random)); - this.lifetime = MHelper.randRange(20, 80, random); - this.quadSize = MHelper.randRange(0.05F, 0.15F, random); - this.setColor(0xFEBBD5); - this.setFadeColor(0xBBFEE4); - this.setSpriteFromAge(spriteProvider); - - preVX = random.nextGaussian() * 0.02; - preVY = random.nextGaussian() * 0.02; - preVZ = random.nextGaussian() * 0.02; - - nextVX = random.nextGaussian() * 0.02; - nextVY = random.nextGaussian() * 0.02; - nextVZ = random.nextGaussian() * 0.02; - } - - @Override - public void tick() { - ticks++; - if (ticks > 30) { - preVX = nextVX; - preVY = nextVY; - preVZ = nextVZ; - nextVX = random.nextGaussian() * 0.02; - nextVY = random.nextGaussian() * 0.02; - nextVZ = random.nextGaussian() * 0.02; - ticks = 0; - } - double delta = (double) ticks / 30.0; - - this.xd = Mth.lerp(delta, preVX, nextVX); - this.yd = Mth.lerp(delta, preVY, nextVY); - this.zd = Mth.lerp(delta, preVZ, nextVZ); - - super.tick(); - } - - @Environment(EnvType.CLIENT) - public static class FactoryPortalSphere implements ParticleProvider { - - private final SpriteSet sprites; - - public FactoryPortalSphere(SpriteSet sprites) { - this.sprites = sprites; - } - - @Override - public Particle createParticle(SimpleParticleType type, ClientLevel world, double x, double y, double z, double vX, double vY, double vZ) { - return new PaticlePortalSphere(world, x, y, z, sprites); - } - } -} diff --git a/src/main/java/ru/betterend/particle/SmaragdantParticle.java b/src/main/java/ru/betterend/particle/SmaragdantParticle.java deleted file mode 100644 index 38a3ad71..00000000 --- a/src/main/java/ru/betterend/particle/SmaragdantParticle.java +++ /dev/null @@ -1,92 +0,0 @@ -package ru.betterend.particle; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.particle.Particle; -import net.minecraft.client.particle.ParticleProvider; -import net.minecraft.client.particle.ParticleRenderType; -import net.minecraft.client.particle.SimpleAnimatedParticle; -import net.minecraft.client.particle.SpriteSet; -import net.minecraft.core.particles.SimpleParticleType; -import net.minecraft.util.Mth; -import ru.bclib.util.MHelper; - -@Environment(EnvType.CLIENT) -public class SmaragdantParticle extends SimpleAnimatedParticle { - private double preVX; - private double preVY; - private double preVZ; - private double nextVX; - private double nextVY; - private double nextVZ; - - protected SmaragdantParticle(ClientLevel world, double x, double y, double z, double r, double g, double b, SpriteSet sprites) { - super(world, x, y, z, sprites, 0); - setSprite(sprites.get(random)); - - this.lifetime = MHelper.randRange(60, 120, random); - this.quadSize = MHelper.randRange(0.05F, 0.15F, random); - this.setColor(1, 1, 1); - this.setAlpha(0); - - preVX = random.nextGaussian() * 0.01; - preVY = random.nextGaussian() * 0.01; - preVZ = random.nextGaussian() * 0.01; - - nextVX = random.nextGaussian() * 0.01; - nextVY = random.nextGaussian() * 0.01; - nextVZ = random.nextGaussian() * 0.01; - } - - @Override - public void tick() { - int ticks = this.age & 31; - if (ticks == 0) { - preVX = nextVX; - preVY = nextVY; - preVZ = nextVZ; - nextVX = random.nextGaussian() * 0.015; - nextVY = random.nextFloat() * 0.02 + 0.01; - nextVZ = random.nextGaussian() * 0.015; - } - double delta = (double) ticks / 31.0; - - if (this.age <= 31) { - this.setAlpha(this.age / 31F); - } - else if (this.age >= this.lifetime - 31) { - this.setAlpha((this.lifetime - this.age) / 31F); - } - - if (this.age >= this.lifetime) { - this.remove(); - } - - this.xd = Mth.lerp(delta, preVX, nextVX); - this.yd = Mth.lerp(delta, preVY, nextVY); - this.zd = Mth.lerp(delta, preVZ, nextVZ); - - super.tick(); - } - - @Override - public ParticleRenderType getRenderType() { - return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; - } - - @Environment(EnvType.CLIENT) - public static class SmaragdantParticleFactory implements ParticleProvider { - - private final SpriteSet sprites; - - public SmaragdantParticleFactory(SpriteSet sprites) { - this.sprites = sprites; - } - - @Override - public Particle createParticle(SimpleParticleType type, ClientLevel world, double x, double y, double z, double vX, double vY, double vZ) { - return new SmaragdantParticle(world, x, y, z, 1, 1, 1, sprites); - } - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/recipe/AlloyingRecipes.java b/src/main/java/ru/betterend/recipe/AlloyingRecipes.java deleted file mode 100644 index 9d6dfc88..00000000 --- a/src/main/java/ru/betterend/recipe/AlloyingRecipes.java +++ /dev/null @@ -1,46 +0,0 @@ -package ru.betterend.recipe; - -import net.minecraft.world.item.Items; -import net.minecraft.world.level.block.Blocks; -import ru.betterend.recipe.builders.AlloyingRecipe; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class AlloyingRecipes { - public static void register() { - AlloyingRecipe.Builder.create("additional_iron") - .setInput(Blocks.IRON_ORE, Blocks.IRON_ORE) - .setOutput(Items.IRON_INGOT, 3) - .setExpiriense(2.1F) - .build(); - AlloyingRecipe.Builder.create("additional_gold") - .setInput(Blocks.GOLD_ORE, Blocks.GOLD_ORE) - .setOutput(Items.GOLD_INGOT, 3) - .setExpiriense(3F) - .build(); - AlloyingRecipe.Builder.create("additional_netherite") - .setInput(Blocks.ANCIENT_DEBRIS, Blocks.ANCIENT_DEBRIS) - .setOutput(Items.NETHERITE_SCRAP, 3) - .setExpiriense(6F) - .setSmeltTime(1000) - .build(); - AlloyingRecipe.Builder.create("terminite_ingot") - .setInput(Items.IRON_INGOT, EndItems.ENDER_DUST) - .setOutput(EndBlocks.TERMINITE.ingot, 1) - .setExpiriense(2.5F) - .setSmeltTime(450) - .build(); - AlloyingRecipe.Builder.create("aeternium_ingot") - .setInput(EndBlocks.TERMINITE.ingot, Items.NETHERITE_INGOT) - .setOutput(EndItems.AETERNIUM_INGOT, 1) - .setExpiriense(4.5F) - .setSmeltTime(850) - .build(); - AlloyingRecipe.Builder.create("terminite_ingot_thallasium") - .setInput(EndBlocks.THALLASIUM.ingot, EndItems.ENDER_DUST) - .setOutput(EndBlocks.TERMINITE.ingot, 1) - .setExpiriense(2.5F) - .setSmeltTime(450) - .build(); - } -} diff --git a/src/main/java/ru/betterend/recipe/AnvilRecipes.java b/src/main/java/ru/betterend/recipe/AnvilRecipes.java deleted file mode 100644 index c6c09ead..00000000 --- a/src/main/java/ru/betterend/recipe/AnvilRecipes.java +++ /dev/null @@ -1,74 +0,0 @@ -package ru.betterend.recipe; - -import net.minecraft.world.item.Items; -import ru.betterend.item.material.EndToolMaterial; -import ru.betterend.recipe.builders.AnvilRecipe; -import ru.betterend.registry.EndItems; - -public class AnvilRecipes { - public static void register() { - AnvilRecipe.Builder.create("ender_pearl_to_dust") - .setInput(Items.ENDER_PEARL) - .setOutput(EndItems.ENDER_DUST) - .setToolLevel(4) - .setDamage(5) - .build(); - AnvilRecipe.Builder.create("ender_shard_to_dust") - .setInput(EndItems.ENDER_SHARD) - .setOutput(EndItems.ENDER_DUST) - .setToolLevel(0) - .setDamage(3) - .build(); - - int anvilLevel = EndToolMaterial.AETERNIUM.getLevel(); - AnvilRecipe.Builder.create("aeternium_axe_head") - .setInput(EndItems.AETERNIUM_INGOT) - .setOutput(EndItems.AETERNIUM_AXE_HEAD) - .setAnvilLevel(anvilLevel) - .setToolLevel(4) - .setDamage(6) - .build(); - AnvilRecipe.Builder.create("aeternium_pickaxe_head") - .setInput(EndItems.AETERNIUM_INGOT) - .setOutput(EndItems.AETERNIUM_PICKAXE_HEAD) - .setAnvilLevel(anvilLevel) - .setToolLevel(4) - .setDamage(6) - .build(); - AnvilRecipe.Builder.create("aeternium_shovel_head") - .setInput(EndItems.AETERNIUM_INGOT) - .setOutput(EndItems.AETERNIUM_SHOVEL_HEAD) - .setAnvilLevel(anvilLevel) - .setToolLevel(4) - .setDamage(6) - .build(); - AnvilRecipe.Builder.create("aeternium_hoe_head") - .setInput(EndItems.AETERNIUM_INGOT) - .setOutput(EndItems.AETERNIUM_HOE_HEAD) - .setAnvilLevel(anvilLevel) - .setToolLevel(4) - .setDamage(6) - .build(); - AnvilRecipe.Builder.create("aeternium_hammer_head") - .setInput(EndItems.AETERNIUM_INGOT) - .setOutput(EndItems.AETERNIUM_HAMMER_HEAD) - .setAnvilLevel(anvilLevel) - .setToolLevel(4) - .setDamage(6) - .build(); - AnvilRecipe.Builder.create("aeternium_sword_blade") - .setInput(EndItems.AETERNIUM_INGOT) - .setOutput(EndItems.AETERNIUM_SWORD_BLADE) - .setAnvilLevel(anvilLevel) - .setToolLevel(4) - .setDamage(6) - .build(); - AnvilRecipe.Builder.create("aeternium_forged_plate") - .setInput(EndItems.AETERNIUM_INGOT) - .setOutput(EndItems.AETERNIUM_FORGED_PLATE) - .setAnvilLevel(anvilLevel) - .setToolLevel(4) - .setDamage(6) - .build(); - } -} diff --git a/src/main/java/ru/betterend/recipe/CraftingRecipes.java b/src/main/java/ru/betterend/recipe/CraftingRecipes.java deleted file mode 100644 index 121b2aeb..00000000 --- a/src/main/java/ru/betterend/recipe/CraftingRecipes.java +++ /dev/null @@ -1,255 +0,0 @@ -package ru.betterend.recipe; - -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.alchemy.PotionUtils; -import net.minecraft.world.item.alchemy.Potions; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import ru.bclib.api.TagAPI; -import ru.bclib.recipes.GridRecipe; -import ru.betterend.BetterEnd; -import ru.betterend.config.Configs; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class CraftingRecipes { - - public static void register() { - GridRecipe.make(BetterEnd.MOD_ID, "ender_perl_to_block", EndBlocks.ENDER_BLOCK) - .checkConfig(Configs.RECIPE_CONFIG) - .setShape("OO", "OO") - .addMaterial('O', Items.ENDER_PEARL) - .build(); - GridRecipe.make(BetterEnd.MOD_ID, "ender_block_to_perl", Items.ENDER_PEARL) - .checkConfig(Configs.RECIPE_CONFIG) - .addMaterial('#', EndBlocks.ENDER_BLOCK) - .setOutputCount(4) - .setList("#") - .build(); - - GridRecipe.make(BetterEnd.MOD_ID, "end_stone_smelter", EndBlocks.END_STONE_SMELTER) - .checkConfig(Configs.RECIPE_CONFIG) - .setShape("T#T", "V V", "T#T") - .addMaterial('#', Blocks.END_STONE_BRICKS) - .addMaterial('T', EndBlocks.THALLASIUM.ingot) - .addMaterial('V', TagAPI.FURNACES) - .build(); - - registerPedestal("andesite_pedestal", EndBlocks.ANDESITE_PEDESTAL, Blocks.POLISHED_ANDESITE_SLAB, Blocks.POLISHED_ANDESITE); - registerPedestal("diorite_pedestal", EndBlocks.DIORITE_PEDESTAL, Blocks.POLISHED_DIORITE_SLAB, Blocks.POLISHED_DIORITE); - registerPedestal("granite_pedestal", EndBlocks.GRANITE_PEDESTAL, Blocks.POLISHED_GRANITE_SLAB, Blocks.POLISHED_GRANITE); - registerPedestal("quartz_pedestal", EndBlocks.QUARTZ_PEDESTAL, Blocks.QUARTZ_SLAB, Blocks.QUARTZ_PILLAR); - registerPedestal("purpur_pedestal", EndBlocks.PURPUR_PEDESTAL, Blocks.PURPUR_SLAB, Blocks.PURPUR_PILLAR); - - GridRecipe.make(BetterEnd.MOD_ID, "infusion_pedestal", EndBlocks.INFUSION_PEDESTAL) - .checkConfig(Configs.RECIPE_CONFIG) - .setShape(" Y ", "O#O", " # ") - .addMaterial('O', Items.ENDER_PEARL) - .addMaterial('Y', Items.ENDER_EYE) - .addMaterial('#', Blocks.OBSIDIAN) - .build(); - - String material = "aeternium"; - GridRecipe.make(BetterEnd.MOD_ID, material + "_block", EndBlocks.AETERNIUM_BLOCK) - .checkConfig(Configs.RECIPE_CONFIG) - .setShape("III", "III", "III") - .addMaterial('I', EndItems.AETERNIUM_INGOT) - .build(); - GridRecipe.make(BetterEnd.MOD_ID, material + "_block_to_ingot", EndItems.AETERNIUM_INGOT) - .checkConfig(Configs.RECIPE_CONFIG) - .addMaterial('#', EndBlocks.AETERNIUM_BLOCK) - .setOutputCount(9) - .setList("#") - .build(); - - GridRecipe.make(BetterEnd.MOD_ID, "blue_vine_seed_dye", Items.BLUE_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.BLUE_VINE_SEED).build(); - GridRecipe.make(BetterEnd.MOD_ID, "creeping_moss_dye", Items.CYAN_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.CREEPING_MOSS).build(); - GridRecipe.make(BetterEnd.MOD_ID, "umbrella_moss_dye", Items.YELLOW_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.UMBRELLA_MOSS).build(); - GridRecipe.make(BetterEnd.MOD_ID, "umbrella_moss_tall_dye", Items.YELLOW_DYE).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(2).setList("#").addMaterial('#', EndBlocks.UMBRELLA_MOSS_TALL).build(); - GridRecipe.make(BetterEnd.MOD_ID, "shadow_plant_dye", Items.BLACK_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.SHADOW_PLANT).build(); - - GridRecipe.make(BetterEnd.MOD_ID, "paper", Items.PAPER).checkConfig(Configs.RECIPE_CONFIG).setShape("###").addMaterial('#', EndItems.END_LILY_LEAF_DRIED).setOutputCount(3).build(); - - GridRecipe.make(BetterEnd.MOD_ID, "aurora_block", EndBlocks.AURORA_CRYSTAL).checkConfig(Configs.RECIPE_CONFIG).setShape("##", "##").addMaterial('#', EndItems.CRYSTAL_SHARDS).build(); - GridRecipe.make(BetterEnd.MOD_ID, "lotus_block", EndBlocks.END_LOTUS.log).checkConfig(Configs.RECIPE_CONFIG).setShape("##", "##").addMaterial('#', EndBlocks.END_LOTUS_STEM).build(); - GridRecipe.make(BetterEnd.MOD_ID, "needlegrass_stick", Items.STICK).setList("#").checkConfig(Configs.RECIPE_CONFIG).setOutputCount(2).addMaterial('#', EndBlocks.NEEDLEGRASS).build(); - GridRecipe.make(BetterEnd.MOD_ID, "shadow_berry_seeds", EndBlocks.SHADOW_BERRY).checkConfig(Configs.RECIPE_CONFIG).setList("#").setOutputCount(4).addMaterial('#', EndItems.SHADOW_BERRY_RAW).build(); - GridRecipe.make(BetterEnd.MOD_ID, "purple_polypore_dye", Items.PURPLE_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.PURPLE_POLYPORE).build(); - - registerLantern("end_stone_lantern", EndBlocks.END_STONE_LANTERN, Blocks.END_STONE_BRICK_SLAB); - registerLantern("andesite_lantern", EndBlocks.ANDESITE_LANTERN, Blocks.ANDESITE_SLAB); - registerLantern("diorite_lantern", EndBlocks.DIORITE_LANTERN, Blocks.DIORITE_SLAB); - registerLantern("granite_lantern", EndBlocks.GRANITE_LANTERN, Blocks.GRANITE_SLAB); - registerLantern("quartz_lantern", EndBlocks.QUARTZ_LANTERN, Blocks.QUARTZ_SLAB); - registerLantern("purpur_lantern", EndBlocks.PURPUR_LANTERN, Blocks.PURPUR_SLAB); - registerLantern("blackstone_lantern", EndBlocks.BLACKSTONE_LANTERN, Blocks.BLACKSTONE_SLAB); - - GridRecipe.make(BetterEnd.MOD_ID, "amber_gem", EndItems.AMBER_GEM).checkConfig(Configs.RECIPE_CONFIG).setShape("##", "##").addMaterial('#', EndItems.RAW_AMBER).build(); - GridRecipe.make(BetterEnd.MOD_ID, "amber_block", EndBlocks.AMBER_BLOCK).checkConfig(Configs.RECIPE_CONFIG).setShape("##", "##").addMaterial('#', EndItems.AMBER_GEM).build(); - GridRecipe.make(BetterEnd.MOD_ID, "amber_gem_block", EndItems.AMBER_GEM).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(4).setList("#").addMaterial('#', EndBlocks.AMBER_BLOCK).build(); - GridRecipe.make(BetterEnd.MOD_ID, "iron_bulb_lantern", EndBlocks.IRON_BULB_LANTERN).checkConfig(Configs.RECIPE_CONFIG).setShape("C", "I", "#").addMaterial('C', Items.CHAIN).addMaterial('I', Items.IRON_INGOT) - .addMaterial('#', EndItems.GLOWING_BULB).build(); - GridRecipe.make(BetterEnd.MOD_ID, "twisted_moss_dye", Items.PINK_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.TWISTED_MOSS).build(); - GridRecipe.make(BetterEnd.MOD_ID, "byshy_grass_dye", Items.MAGENTA_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.BUSHY_GRASS).build(); - GridRecipe.make(BetterEnd.MOD_ID, "tail_moss_dye", Items.GRAY_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.TAIL_MOSS).build(); - GridRecipe.make(BetterEnd.MOD_ID, "petal_block", EndBlocks.HYDRALUX_PETAL_BLOCK).checkConfig(Configs.RECIPE_CONFIG).setShape("##", "##").addMaterial('#', EndItems.HYDRALUX_PETAL).build(); - GridRecipe.make(BetterEnd.MOD_ID, "petal_white_dye", Items.WHITE_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndItems.HYDRALUX_PETAL).build(); - - GridRecipe.make(BetterEnd.MOD_ID, "sweet_berry_jelly", EndItems.SWEET_BERRY_JELLY) - .checkConfig(Configs.RECIPE_CONFIG) - .setList("JWSB") - .addMaterial('J', EndItems.GELATINE) - .addMaterial('W', PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)) - .addMaterial('S', Items.SUGAR).addMaterial('B', Items.SWEET_BERRIES) - .build(); - - GridRecipe.make(BetterEnd.MOD_ID, "shadow_berry_jelly", EndItems.SHADOW_BERRY_JELLY) - .checkConfig(Configs.RECIPE_CONFIG) - .setList("JWSB") - .addMaterial('J', EndItems.GELATINE) - .addMaterial('W', PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)) - .addMaterial('S', Items.SUGAR) - .addMaterial('B', EndItems.SHADOW_BERRY_COOKED) - .build(); - - GridRecipe.make(BetterEnd.MOD_ID, "shadow_berry_jelly", EndItems.BLOSSOM_BERRY_JELLY) - .checkConfig(Configs.RECIPE_CONFIG) - .setList("JWSB") - .addMaterial('J', EndItems.GELATINE) - .addMaterial('W', PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)) - .addMaterial('S', Items.SUGAR) - .addMaterial('B', EndItems.BLOSSOM_BERRY) - .build(); - - GridRecipe.make(BetterEnd.MOD_ID, "sulphur_gunpowder", Items.GUNPOWDER).checkConfig(Configs.RECIPE_CONFIG).setList("SCB").addMaterial('S', EndItems.CRYSTALLINE_SULPHUR).addMaterial('C', Items.COAL, Items.CHARCOAL) - .addMaterial('B', Items.BONE_MEAL).build(); - - GridRecipe.make(BetterEnd.MOD_ID, "dense_emerald_ice", EndBlocks.DENSE_EMERALD_ICE).checkConfig(Configs.RECIPE_CONFIG).setShape("##", "##").addMaterial('#', EndBlocks.EMERALD_ICE).build(); - GridRecipe.make(BetterEnd.MOD_ID, "ancient_emerald_ice", EndBlocks.ANCIENT_EMERALD_ICE).checkConfig(Configs.RECIPE_CONFIG).setShape("###", "###", "###").addMaterial('#', EndBlocks.DENSE_EMERALD_ICE).build(); - - GridRecipe.make(BetterEnd.MOD_ID, "charnia_cyan_dye", Items.CYAN_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.CHARNIA_CYAN).build(); - GridRecipe.make(BetterEnd.MOD_ID, "charnia_green_dye", Items.GREEN_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.CHARNIA_GREEN).build(); - GridRecipe.make(BetterEnd.MOD_ID, "charnia_light_blue_dye", Items.LIGHT_BLUE_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.CHARNIA_LIGHT_BLUE).build(); - GridRecipe.make(BetterEnd.MOD_ID, "charnia_orange_dye", Items.ORANGE_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.CHARNIA_ORANGE).build(); - GridRecipe.make(BetterEnd.MOD_ID, "charnia_purple_dye", Items.PURPLE_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.CHARNIA_PURPLE).build(); - GridRecipe.make(BetterEnd.MOD_ID, "charnia_red_dye", Items.RED_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.CHARNIA_RED).build(); - - GridRecipe.make(BetterEnd.MOD_ID, "respawn_obelisk", EndBlocks.RESPAWN_OBELISK) - .checkConfig(Configs.RECIPE_CONFIG) - .setShape("CSC", "CSC", "AAA") - .addMaterial('C', EndBlocks.AURORA_CRYSTAL) - .addMaterial('S', EndItems.ETERNAL_CRYSTAL) - .addMaterial('A', EndBlocks.AMBER_BLOCK) - .build(); - - GridRecipe.make(BetterEnd.MOD_ID, "twisted_umbrella_moss_dye", Items.PURPLE_DYE).checkConfig(Configs.RECIPE_CONFIG).setList("#").addMaterial('#', EndBlocks.TWISTED_UMBRELLA_MOSS).build(); - GridRecipe.make(BetterEnd.MOD_ID, "twisted_umbrella_moss_dye_tall", Items.PURPLE_DYE).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(2).setList("#").addMaterial('#', EndBlocks.TWISTED_UMBRELLA_MOSS_TALL).build(); - - GridRecipe.make(BetterEnd.MOD_ID, "leather_to_stripes", EndItems.LEATHER_STRIPE) - .checkConfig(Configs.RECIPE_CONFIG) - .setList("L") - .addMaterial('L', Items.LEATHER) - .setOutputCount(3) - .build(); - GridRecipe.make(BetterEnd.MOD_ID, "stripes_to_leather", Items.LEATHER) - .checkConfig(Configs.RECIPE_CONFIG) - .setList("SSS") - .addMaterial('S', EndItems.LEATHER_STRIPE) - .build(); - GridRecipe.make(BetterEnd.MOD_ID, "leather_wrapped_stick", EndItems.LEATHER_WRAPPED_STICK) - .checkConfig(Configs.RECIPE_CONFIG) - .setList("SL") - .addMaterial('S', Items.STICK) - .addMaterial('L', EndItems.LEATHER_STRIPE) - .build(); - - GridRecipe.make(BetterEnd.MOD_ID, "fiber_string", Items.STRING).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(6).setShape("#", "#", "#").addMaterial('#', EndItems.SILK_FIBER).build(); - - GridRecipe.make(BetterEnd.MOD_ID, "ender_eye_amber", Items.ENDER_EYE) - .checkConfig(Configs.RECIPE_CONFIG) - .setShape("SAS", "APA", "SAS") - .addMaterial('S', EndItems.CRYSTAL_SHARDS) - .addMaterial('A', EndItems.AMBER_GEM) - .addMaterial('P', Items.ENDER_PEARL) - .build(); - - GridRecipe.make(BetterEnd.MOD_ID, "iron_chandelier", EndBlocks.IRON_CHANDELIER).checkConfig(Configs.RECIPE_CONFIG).setShape("I#I", " # ").addMaterial('#', Items.IRON_INGOT).addMaterial('I', EndItems.LUMECORN_ROD) - .setGroup("end_metal_chandelier").build(); - GridRecipe.make(BetterEnd.MOD_ID, "gold_chandelier", EndBlocks.GOLD_CHANDELIER).checkConfig(Configs.RECIPE_CONFIG).setShape("I#I", " # ").addMaterial('#', Items.GOLD_INGOT).addMaterial('I', EndItems.LUMECORN_ROD) - .setGroup("end_metal_chandelier").build(); - - GridRecipe.make(BetterEnd.MOD_ID, "missing_tile", EndBlocks.MISSING_TILE) - .checkConfig(Configs.RECIPE_CONFIG) - .setOutputCount(4) - .setShape("#P", "P#") - .addMaterial('#', EndBlocks.VIOLECITE.stone, EndBlocks.VIOLECITE.bricks, EndBlocks.VIOLECITE.tiles) - .addMaterial('P', Blocks.PURPUR_BLOCK) - .build(); - - registerHammer("iron", Items.IRON_INGOT, EndItems.IRON_HAMMER); - registerHammer("golden", Items.GOLD_INGOT, EndItems.GOLDEN_HAMMER); - registerHammer("diamond", Items.DIAMOND, EndItems.DIAMOND_HAMMER); - - GridRecipe.make(BetterEnd.MOD_ID, "charcoal_block", EndBlocks.CHARCOAL_BLOCK).checkConfig(Configs.RECIPE_CONFIG).setShape("###", "###", "###").addMaterial('#', Items.CHARCOAL).build(); - GridRecipe.make(BetterEnd.MOD_ID, "charcoal_from_block", Items.CHARCOAL).checkConfig(Configs.RECIPE_CONFIG).setOutputCount(9).setList("#").addMaterial('#', EndBlocks.CHARCOAL_BLOCK).build(); - GridRecipe.make(BetterEnd.MOD_ID, "end_stone_furnace", EndBlocks.END_STONE_FURNACE).checkConfig(Configs.RECIPE_CONFIG).setShape("###", "# #", "###").addMaterial('#', Blocks.END_STONE).build(); - GridRecipe.make(BetterEnd.MOD_ID, "filalux_lantern", EndBlocks.FILALUX_LANTERN).checkConfig(Configs.RECIPE_CONFIG).setShape("###", "###", "###").addMaterial('#', EndBlocks.FILALUX).build(); - - GridRecipe.make(BetterEnd.MOD_ID, "silk_moth_hive", EndBlocks.SILK_MOTH_HIVE) - .checkConfig(Configs.RECIPE_CONFIG).setShape("#L#", "LML", "#L#") - .addMaterial('#', EndBlocks.TENANEA.planks) - .addMaterial('L', EndBlocks.TENANEA_LEAVES) - .addMaterial('M', EndItems.SILK_MOTH_MATRIX) - .build(); - - GridRecipe.make(BetterEnd.MOD_ID, "cave_pumpkin_pie", EndItems.CAVE_PUMPKIN_PIE) - .checkConfig(Configs.RECIPE_CONFIG) - .setShape("SBS", "BPB", "SBS") - .addMaterial('P', EndBlocks.CAVE_PUMPKIN) - .addMaterial('B', EndItems.BLOSSOM_BERRY, EndItems.SHADOW_BERRY_RAW).addMaterial('S', Items.SUGAR).build(); - - GridRecipe.make(BetterEnd.MOD_ID, "cave_pumpkin_seeds", EndBlocks.CAVE_PUMPKIN_SEED) - .checkConfig(Configs.RECIPE_CONFIG) - .setOutputCount(4) - .setList("#") - .addMaterial('#', EndBlocks.CAVE_PUMPKIN) - .build(); - - GridRecipe.make(BetterEnd.MOD_ID, "neon_cactus_block", EndBlocks.NEON_CACTUS_BLOCK).checkConfig(Configs.RECIPE_CONFIG).setShape("##", "##").addMaterial('#', EndBlocks.NEON_CACTUS).build(); - GridRecipe.make(BetterEnd.MOD_ID, "neon_cactus_block_slab", EndBlocks.NEON_CACTUS_BLOCK_SLAB).checkConfig(Configs.RECIPE_CONFIG).setShape("###").setOutputCount(6).addMaterial('#', EndBlocks.NEON_CACTUS_BLOCK).build(); - GridRecipe.make(BetterEnd.MOD_ID, "neon_cactus_block_stairs", EndBlocks.NEON_CACTUS_BLOCK_STAIRS).checkConfig(Configs.RECIPE_CONFIG).setShape("# ", "## ", "###").setOutputCount(4).addMaterial('#', EndBlocks.NEON_CACTUS_BLOCK).build(); - - GridRecipe.make(BetterEnd.MOD_ID, "sugar_from_root", Items.SUGAR).checkConfig(Configs.RECIPE_CONFIG).setList("###").addMaterial('#', EndItems.AMBER_ROOT_RAW).build(); - } - - private static void registerLantern(String name, Block lantern, Block slab) { - GridRecipe.make(BetterEnd.MOD_ID, name, lantern) - .checkConfig(Configs.RECIPE_CONFIG) - .setShape("S", "#", "S") - .addMaterial('#', EndItems.CRYSTAL_SHARDS) - .addMaterial('S', slab) - .setGroup("end_stone_lanterns") - .build(); - } - - public static void registerPedestal(String name, Block pedestal, Block slab, Block pillar) { - GridRecipe.make(BetterEnd.MOD_ID, name, pedestal) - .checkConfig(Configs.RECIPE_CONFIG) - .setShape("S", "#", "S") - .addMaterial('S', slab) - .addMaterial('#', pillar) - .setOutputCount(2) - .build(); - } - - private static void registerHammer(String name, Item material, Item result) { - GridRecipe.make(BetterEnd.MOD_ID, name + "_hammer", result) - .checkConfig(Configs.RECIPE_CONFIG) - .setShape("I I", "I#I", " # ") - .addMaterial('I', material) - .addMaterial('#', Items.STICK) - .build(); - } -} diff --git a/src/main/java/ru/betterend/recipe/FurnaceRecipes.java b/src/main/java/ru/betterend/recipe/FurnaceRecipes.java deleted file mode 100644 index 635826d6..00000000 --- a/src/main/java/ru/betterend/recipe/FurnaceRecipes.java +++ /dev/null @@ -1,22 +0,0 @@ -package ru.betterend.recipe; - -import net.minecraft.world.item.Items; -import net.minecraft.world.level.block.Blocks; -import ru.bclib.recipes.FurnaceRecipe; -import ru.betterend.BetterEnd; -import ru.betterend.config.Configs; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class FurnaceRecipes { - public static void register() { - FurnaceRecipe.make(BetterEnd.MOD_ID, "end_lily_leaf_dried", EndItems.END_LILY_LEAF, EndItems.END_LILY_LEAF_DRIED).checkConfig(Configs.RECIPE_CONFIG).build(); - FurnaceRecipe.make(BetterEnd.MOD_ID, "end_glass", EndBlocks.ENDSTONE_DUST, Blocks.GLASS).checkConfig(Configs.RECIPE_CONFIG).build(); - FurnaceRecipe.make(BetterEnd.MOD_ID, "end_berry", EndItems.SHADOW_BERRY_RAW, EndItems.SHADOW_BERRY_COOKED).checkConfig(Configs.RECIPE_CONFIG).buildFoodlike(); - FurnaceRecipe.make(BetterEnd.MOD_ID, "end_fish", EndItems.END_FISH_RAW, EndItems.END_FISH_COOKED).checkConfig(Configs.RECIPE_CONFIG).buildFoodlike(); - FurnaceRecipe.make(BetterEnd.MOD_ID, "slime_ball", EndBlocks.JELLYSHROOM_CAP_PURPLE, Items.SLIME_BALL).checkConfig(Configs.RECIPE_CONFIG).build(); - FurnaceRecipe.make(BetterEnd.MOD_ID, "menger_sponge", EndBlocks.MENGER_SPONGE_WET, EndBlocks.MENGER_SPONGE).checkConfig(Configs.RECIPE_CONFIG).build(); - FurnaceRecipe.make(BetterEnd.MOD_ID, "chorus_mushroom", EndItems.CHORUS_MUSHROOM_RAW, EndItems.CHORUS_MUSHROOM_COOKED).checkConfig(Configs.RECIPE_CONFIG).buildFoodlike(); - FurnaceRecipe.make(BetterEnd.MOD_ID, "bolux_mushroom", EndBlocks.BOLUX_MUSHROOM, EndItems.BOLUX_MUSHROOM_COOKED).checkConfig(Configs.RECIPE_CONFIG).buildFoodlike(); - } -} diff --git a/src/main/java/ru/betterend/recipe/InfusionRecipes.java b/src/main/java/ru/betterend/recipe/InfusionRecipes.java deleted file mode 100644 index b4de0b54..00000000 --- a/src/main/java/ru/betterend/recipe/InfusionRecipes.java +++ /dev/null @@ -1,614 +0,0 @@ -package ru.betterend.recipe; - -import net.minecraft.world.item.EnchantedBookItem; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.enchantment.Enchantment; -import net.minecraft.world.item.enchantment.EnchantmentInstance; -import net.minecraft.world.item.enchantment.Enchantments; -import net.minecraft.world.level.block.Blocks; -import ru.betterend.recipe.builders.InfusionRecipe; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class InfusionRecipes { - public static void register() { - InfusionRecipe.Builder.create("runed_flavolite") - .setInput(EndBlocks.FLAVOLITE.polished) - .setOutput(EndBlocks.FLAVOLITE_RUNED) - .addCatalyst(0, EndItems.CRYSTAL_SHARDS) - .addCatalyst(2, EndItems.CRYSTAL_SHARDS) - .addCatalyst(4, EndItems.CRYSTAL_SHARDS) - .addCatalyst(6, EndItems.CRYSTAL_SHARDS) - .setTime(100) - .build(); - - InfusionRecipe.Builder.create("eternal_crystal") - .setInput(Items.END_CRYSTAL) - .setOutput(EndItems.ETERNAL_CRYSTAL) - .addCatalyst(0, EndItems.CRYSTAL_SHARDS) - .addCatalyst(2, EndItems.CRYSTAL_SHARDS) - .addCatalyst(4, EndItems.CRYSTAL_SHARDS) - .addCatalyst(6, EndItems.CRYSTAL_SHARDS) - .addCatalyst(1, EndItems.ENDER_SHARD) - .addCatalyst(3, EndItems.ENDER_SHARD) - .addCatalyst(5, EndItems.ENDER_SHARD) - .addCatalyst(7, EndItems.ENDER_SHARD) - .setTime(250) - .build(); - - InfusionRecipe.Builder.create("crystalite_helmet") - .setInput(EndBlocks.TERMINITE.helmet) - .setOutput(EndItems.CRYSTALITE_HELMET) - .addCatalyst(0, EndItems.AMBER_GEM) - .addCatalyst(2, EndItems.CRYSTAL_SHARDS) - .addCatalyst(6, EndItems.CRYSTAL_SHARDS) - .setTime(150) - .build(); - InfusionRecipe.Builder.create("crystalite_chestplate") - .setInput(EndBlocks.TERMINITE.chestplate) - .setOutput(EndItems.CRYSTALITE_CHESTPLATE) - .addCatalyst(0, EndItems.AMBER_GEM) - .addCatalyst(1, EndItems.CRYSTAL_SHARDS) - .addCatalyst(3, EndItems.CRYSTAL_SHARDS) - .addCatalyst(5, EndItems.CRYSTAL_SHARDS) - .addCatalyst(7, EndItems.CRYSTAL_SHARDS) - .setTime(300) - .build(); - InfusionRecipe.Builder.create("crystalite_leggings") - .setInput(EndBlocks.TERMINITE.leggings) - .setOutput(EndItems.CRYSTALITE_LEGGINGS) - .addCatalyst(0, EndItems.AMBER_GEM) - .addCatalyst(2, EndItems.CRYSTAL_SHARDS) - .addCatalyst(4, EndItems.CRYSTAL_SHARDS) - .addCatalyst(6, EndItems.CRYSTAL_SHARDS) - .setTime(225) - .build(); - InfusionRecipe.Builder.create("crystalite_boots") - .setInput(EndBlocks.TERMINITE.boots) - .setOutput(EndItems.CRYSTALITE_BOOTS) - .addCatalyst(0, EndItems.AMBER_GEM) - .addCatalyst(2, EndItems.CRYSTAL_SHARDS) - .addCatalyst(6, EndItems.CRYSTAL_SHARDS) - .setTime(150) - .build(); - - InfusionRecipe.Builder.create("crystalite_elytra") - .setInput(Items.ELYTRA) - .setOutput(EndItems.CRYSTALITE_ELYTRA) - .addCatalyst(0, EndItems.AMBER_GEM) - .addCatalyst(1, EndItems.CRYSTAL_SHARDS) - .addCatalyst(2, EndItems.ENCHANTED_MEMBRANE) - .addCatalyst(3, EndItems.CRYSTAL_SHARDS) - .addCatalyst(4, EndItems.ENCHANTED_MEMBRANE) - .addCatalyst(5, EndItems.CRYSTAL_SHARDS) - .addCatalyst(6, EndItems.ENCHANTED_MEMBRANE) - .addCatalyst(7, EndItems.CRYSTAL_SHARDS) - .setTime(500) - .build(); - - InfusionRecipe.Builder.create("enchanted_petal") - .setInput(EndItems.HYDRALUX_PETAL) - .setOutput(EndItems.ENCHANTED_PETAL) - .addCatalyst(0, EndItems.CRYSTAL_SHARDS) - .addCatalyst(2, EndItems.CRYSTAL_SHARDS) - .addCatalyst(4, EndItems.CRYSTAL_SHARDS) - .addCatalyst(6, EndItems.CRYSTAL_SHARDS) - .setTime(75) - .build(); - InfusionRecipe.Builder.create("enchanted_membrane") - .setInput(Items.PHANTOM_MEMBRANE) - .setOutput(EndItems.ENCHANTED_MEMBRANE) - .addCatalyst(0, EndItems.CRYSTAL_SHARDS) - .addCatalyst(2, EndItems.CRYSTAL_SHARDS) - .addCatalyst(4, EndItems.CRYSTAL_SHARDS) - .addCatalyst(6, EndItems.CRYSTAL_SHARDS) - .setTime(75) - .build(); - - InfusionRecipe.Builder.create("protection_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.ALL_DAMAGE_PROTECTION, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(4, Items.TURTLE_HELMET) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("fire_protection_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.FIRE_PROTECTION, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.BLAZE_ROD) - .addCatalyst(4, Items.BLAZE_ROD) - .addCatalyst(6, Items.BLAZE_ROD) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("feather_falling_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.FALL_PROTECTION, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.FEATHER) - .addCatalyst(4, Items.FEATHER) - .addCatalyst(6, Items.FEATHER) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("blast_protection_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.BLAST_PROTECTION, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Blocks.OBSIDIAN) - .addCatalyst(4, Blocks.OBSIDIAN) - .addCatalyst(6, Blocks.OBSIDIAN) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("projectile_protection_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.PROJECTILE_PROTECTION, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.SCUTE) - .addCatalyst(4, Items.SHIELD) - .addCatalyst(6, Items.SCUTE) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("respiration_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.RESPIRATION, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.NAUTILUS_SHELL) - .addCatalyst(4, Items.NAUTILUS_SHELL) - .addCatalyst(6, Items.NAUTILUS_SHELL) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("aqua_affinity_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.AQUA_AFFINITY, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.PRISMARINE_CRYSTALS) - .addCatalyst(4, Items.PRISMARINE_CRYSTALS) - .addCatalyst(6, Items.PRISMARINE_CRYSTALS) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("thorns_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.THORNS, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Blocks.CACTUS) - .addCatalyst(4, Blocks.CACTUS) - .addCatalyst(6, Blocks.CACTUS) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("depth_strider_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.DEPTH_STRIDER, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Blocks.LILY_PAD) - .addCatalyst(4, EndBlocks.END_LILY_SEED) - .addCatalyst(6, Blocks.LILY_PAD) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("frost_walker_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.FROST_WALKER, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(4, EndBlocks.ANCIENT_EMERALD_ICE) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("soul_speed_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.SOUL_SPEED, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Blocks.SOUL_SAND, Blocks.SOUL_SOIL) - .addCatalyst(4, Blocks.SOUL_SAND, Blocks.SOUL_SOIL) - .addCatalyst(6, Blocks.SOUL_SAND, Blocks.SOUL_SOIL) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("sharpness_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.SHARPNESS, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(4, Items.NETHERITE_SCRAP) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("smite_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.SMITE, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Blocks.SUNFLOWER) - .addCatalyst(4, Items.GOLD_INGOT) - .addCatalyst(6, Blocks.SUNFLOWER) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("bane_of_arthropods_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.BANE_OF_ARTHROPODS, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.FERMENTED_SPIDER_EYE) - .addCatalyst(4, Items.IRON_INGOT) - .addCatalyst(6, Items.FERMENTED_SPIDER_EYE) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("knockback_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.KNOCKBACK, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.REDSTONE) - .addCatalyst(4, Blocks.PISTON) - .addCatalyst(6, Items.REDSTONE) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("fire_aspect_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.FIRE_ASPECT, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.BLAZE_POWDER) - .addCatalyst(4, Items.MAGMA_CREAM) - .addCatalyst(6, Items.BLAZE_POWDER) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("looting_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.MOB_LOOTING, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.EMERALD) - .addCatalyst(4, Items.GOLD_INGOT) - .addCatalyst(6, Items.EMERALD) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("sweeping_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.SWEEPING_EDGE, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.GOLDEN_SWORD) - .addCatalyst(4, Items.IRON_SWORD) - .addCatalyst(6, Items.GOLDEN_SWORD) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("efficiency_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.BLOCK_EFFICIENCY, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, EndItems.AMBER_GEM) - .addCatalyst(4, EndItems.AMBER_GEM) - .addCatalyst(6, EndItems.AMBER_GEM) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("silk_touch_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.SILK_TOUCH, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Blocks.COBWEB) - .addCatalyst(4, EndItems.ETERNAL_CRYSTAL) - .addCatalyst(6, Blocks.COBWEB) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(375) - .build(); - InfusionRecipe.Builder.create("unbreaking_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.UNBREAKING, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.DIAMOND) - .addCatalyst(4, Items.DIAMOND) - .addCatalyst(6, Items.DIAMOND) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("fortune_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.BLOCK_FORTUNE, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.EMERALD) - .addCatalyst(4, Items.RABBIT_FOOT) - .addCatalyst(6, Items.EMERALD) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("power_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.POWER_ARROWS, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, EndItems.AMBER_GEM) - .addCatalyst(4, Items.DIAMOND_SWORD) - .addCatalyst(6, EndItems.AMBER_GEM) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("punch_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.PUNCH_ARROWS, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.POPPED_CHORUS_FRUIT) - .addCatalyst(4, Items.SPECTRAL_ARROW) - .addCatalyst(6, Items.POPPED_CHORUS_FRUIT) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("flame_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.FLAMING_ARROWS, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.BLAZE_POWDER) - .addCatalyst(4, Items.SPECTRAL_ARROW) - .addCatalyst(6, Items.BLAZE_POWDER) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("infinity_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.INFINITY_ARROWS, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.SPECTRAL_ARROW) - .addCatalyst(4, EndItems.ETERNAL_CRYSTAL) - .addCatalyst(6, Items.SPECTRAL_ARROW) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(375) - .build(); - InfusionRecipe.Builder.create("luck_of_sea_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.FISHING_LUCK, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.EMERALD) - .addCatalyst(4, Items.FISHING_ROD) - .addCatalyst(6, Items.EMERALD) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("lure_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.FISHING_SPEED, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.GOLD_NUGGET) - .addCatalyst(4, Items.FISHING_ROD) - .addCatalyst(6, Items.GOLD_NUGGET) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("loyalty_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.LOYALTY, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.ENDER_EYE) - .addCatalyst(4, Items.HEART_OF_THE_SEA) - .addCatalyst(6, Items.ENDER_EYE) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(375) - .build(); - InfusionRecipe.Builder.create("impaling_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.IMPALING, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.PRISMARINE_SHARD) - .addCatalyst(4, Items.IRON_SWORD) - .addCatalyst(6, Items.PRISMARINE_SHARD) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("riptide_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.RIPTIDE, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.LEAD) - .addCatalyst(4, Items.HEART_OF_THE_SEA) - .addCatalyst(6, Items.LEAD) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(375) - .build(); - InfusionRecipe.Builder.create("channeling_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.CHANNELING, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.CHAIN) - .addCatalyst(4, Items.HEART_OF_THE_SEA) - .addCatalyst(6, Items.CHAIN) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(375) - .build(); - InfusionRecipe.Builder.create("multishot_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.MULTISHOT, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.ARROW) - .addCatalyst(4, Items.SPECTRAL_ARROW) - .addCatalyst(6, Items.ARROW) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("quick_charge_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.QUICK_CHARGE, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.QUARTZ) - .addCatalyst(4, Items.GLOWSTONE_DUST) - .addCatalyst(6, Items.QUARTZ) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("piercing_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.PIERCING, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.GLOWSTONE_DUST) - .addCatalyst(4, Items.SPECTRAL_ARROW) - .addCatalyst(6, Items.GLOWSTONE_DUST) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(300) - .build(); - InfusionRecipe.Builder.create("mending_book") - .setInput(Items.BOOK) - .setOutput(createEnchantedBook(Enchantments.MENDING, 1)) - .addCatalyst(0, EndItems.ENCHANTED_PETAL) - .addCatalyst(2, Items.EXPERIENCE_BOTTLE) - .addCatalyst(4, Blocks.ANVIL) - .addCatalyst(6, Items.EXPERIENCE_BOTTLE) - .addCatalyst(1, Items.LAPIS_LAZULI) - .addCatalyst(3, Items.LAPIS_LAZULI) - .addCatalyst(5, Items.LAPIS_LAZULI) - .addCatalyst(7, Items.LAPIS_LAZULI) - .setGroup("enchantment") - .setTime(375) - .build(); - } - - private static ItemStack createEnchantedBook(Enchantment enchantment, int level) { - ItemStack book = new ItemStack(Items.ENCHANTED_BOOK); - EnchantedBookItem.addEnchantment(book, new EnchantmentInstance(enchantment, level)); - return book; - } -} diff --git a/src/main/java/ru/betterend/recipe/SmithingRecipes.java b/src/main/java/ru/betterend/recipe/SmithingRecipes.java deleted file mode 100644 index 5c8e82b6..00000000 --- a/src/main/java/ru/betterend/recipe/SmithingRecipes.java +++ /dev/null @@ -1,109 +0,0 @@ -package ru.betterend.recipe; - -import net.minecraft.world.item.Items; -import ru.bclib.recipes.SmithingTableRecipe; -import ru.betterend.BetterEnd; -import ru.betterend.config.Configs; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class SmithingRecipes { - - public static void register() { - SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_sword_handle") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndItems.AETERNIUM_SWORD_HANDLE) - .setBase(EndBlocks.TERMINITE.ingot) - .setAddition(EndItems.LEATHER_WRAPPED_STICK) - .build(); - - SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_sword") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndItems.AETERNIUM_SWORD) - .setBase(EndItems.AETERNIUM_SWORD_BLADE) - .setAddition(EndItems.AETERNIUM_SWORD_HANDLE) - .build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_pickaxe") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndItems.AETERNIUM_PICKAXE) - .setBase(EndItems.AETERNIUM_PICKAXE_HEAD) - .setAddition(EndItems.LEATHER_WRAPPED_STICK) - .build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_axe") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndItems.AETERNIUM_AXE) - .setBase(EndItems.AETERNIUM_AXE_HEAD) - .setAddition(EndItems.LEATHER_WRAPPED_STICK) - .build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_shovel") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndItems.AETERNIUM_SHOVEL) - .setBase(EndItems.AETERNIUM_SHOVEL_HEAD) - .setAddition(EndItems.LEATHER_WRAPPED_STICK) - .build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_hoe") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndItems.AETERNIUM_HOE) - .setBase(EndItems.AETERNIUM_HOE_HEAD) - .setAddition(EndItems.LEATHER_WRAPPED_STICK) - .build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_hammer") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndItems.AETERNIUM_HAMMER) - .setBase(EndItems.AETERNIUM_HAMMER_HEAD) - .setAddition(EndItems.LEATHER_WRAPPED_STICK) - .build(); - - SmithingTableRecipe.create(BetterEnd.MOD_ID, "netherite_hammer") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndItems.NETHERITE_HAMMER) - .setBase(EndItems.DIAMOND_HAMMER) - .setAddition(Items.NETHERITE_INGOT) - .build(); - - SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_helmet") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndItems.AETERNIUM_HELMET) - .setBase(EndBlocks.TERMINITE.helmet) - .setAddition(EndItems.AETERNIUM_FORGED_PLATE) - .build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_chestplate") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndItems.AETERNIUM_CHESTPLATE) - .setBase(EndBlocks.TERMINITE.chestplate) - .setAddition(EndItems.AETERNIUM_FORGED_PLATE) - .build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_leggings") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndItems.AETERNIUM_LEGGINGS) - .setBase(EndBlocks.TERMINITE.leggings) - .setAddition(EndItems.AETERNIUM_FORGED_PLATE) - .build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, "aeternium_boots") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndItems.AETERNIUM_BOOTS) - .setBase(EndBlocks.TERMINITE.boots) - .setAddition(EndItems.AETERNIUM_FORGED_PLATE) - .build(); - - SmithingTableRecipe.create(BetterEnd.MOD_ID, "thallasium_anvil_updrade") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndBlocks.TERMINITE.anvilBlock) - .setBase(EndBlocks.THALLASIUM.anvilBlock) - .setAddition(EndBlocks.TERMINITE.block) - .build(); - SmithingTableRecipe.create(BetterEnd.MOD_ID, "terminite_anvil_updrade") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndBlocks.AETERNIUM_ANVIL) - .setBase(EndBlocks.TERMINITE.anvilBlock) - .setAddition(EndItems.AETERNIUM_INGOT) - .build(); - - SmithingTableRecipe.create(BetterEnd.MOD_ID, "armored_elytra") - .checkConfig(Configs.RECIPE_CONFIG) - .setResult(EndItems.ARMORED_ELYTRA) - .setBase(Items.ELYTRA) - .setAddition(EndItems.AETERNIUM_INGOT) - .build(); - } -} diff --git a/src/main/java/ru/betterend/recipe/builders/AlloyingRecipe.java b/src/main/java/ru/betterend/recipe/builders/AlloyingRecipe.java deleted file mode 100644 index 98e79b2c..00000000 --- a/src/main/java/ru/betterend/recipe/builders/AlloyingRecipe.java +++ /dev/null @@ -1,279 +0,0 @@ -package ru.betterend.recipe.builders; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.core.NonNullList; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.Tag; -import net.minecraft.util.GsonHelper; -import net.minecraft.world.Container; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Recipe; -import net.minecraft.world.item.crafting.RecipeSerializer; -import net.minecraft.world.item.crafting.RecipeType; -import net.minecraft.world.level.ItemLike; -import net.minecraft.world.level.Level; -import ru.bclib.recipes.BCLRecipeManager; -import ru.betterend.BetterEnd; -import ru.betterend.config.Configs; -import ru.betterend.interfaces.BetterEndRecipe; -import ru.betterend.registry.EndBlocks; -import ru.betterend.util.ItemUtil; -import ru.betterend.util.RecipeHelper; - -public class AlloyingRecipe implements Recipe, BetterEndRecipe { - - public final static String GROUP = "alloying"; - public final static RecipeType TYPE = BCLRecipeManager.registerType(BetterEnd.MOD_ID, GROUP); - public final static Serializer SERIALIZER = BCLRecipeManager.registerSerializer(BetterEnd.MOD_ID, GROUP, new Serializer()); - public final static ResourceLocation ID = BetterEnd.makeID(GROUP); - - protected final RecipeType type; - protected final ResourceLocation id; - protected final Ingredient primaryInput; - protected final Ingredient secondaryInput; - protected final ItemStack output; - protected final String group; - protected final float experience; - protected final int smeltTime; - - public AlloyingRecipe(ResourceLocation id, String group, Ingredient primaryInput, Ingredient secondaryInput, ItemStack output, float experience, int smeltTime) { - this.group = group; - this.id = id; - this.primaryInput = primaryInput; - this.secondaryInput = secondaryInput; - this.output = output; - this.experience = experience; - this.smeltTime = smeltTime; - this.type = TYPE; - } - - public float getExperience() { - return this.experience; - } - - public int getSmeltTime() { - return this.smeltTime; - } - - @Override - public NonNullList getIngredients() { - NonNullList defaultedList = NonNullList.create(); - defaultedList.add(primaryInput); - defaultedList.add(secondaryInput); - - return defaultedList; - } - - @Override - public boolean matches(Container inv, Level world) { - return this.primaryInput.test(inv.getItem(0)) && this.secondaryInput.test(inv.getItem(1)) || - this.primaryInput.test(inv.getItem(1)) && this.secondaryInput.test(inv.getItem(0)); - } - - @Override - public ItemStack assemble(Container inv) { - return this.output.copy(); - } - - @Override - public boolean canCraftInDimensions(int width, int height) { - return true; - } - - @Override - public ItemStack getResultItem() { - return this.output; - } - - @Override - public ResourceLocation getId() { - return this.id; - } - - @Override - public RecipeSerializer getSerializer() { - return SERIALIZER; - } - - @Override - public RecipeType getType() { - return this.type; - } - - @Override - @Environment(EnvType.CLIENT) - public String getGroup() { - return this.group; - } - - @Environment(EnvType.CLIENT) - public ItemStack getToastSymbol() { - return new ItemStack(EndBlocks.END_STONE_SMELTER); - } - - public static class Builder { - private final static Builder INSTANCE = new Builder(); - private static boolean exist; - - public static Builder create(ResourceLocation id) { - INSTANCE.id = id; - INSTANCE.group = String.format("%s_%s", GROUP, id); - INSTANCE.primaryInput = null; - INSTANCE.secondaryInput = null; - INSTANCE.output = null; - INSTANCE.experience = 0.0F; - INSTANCE.smeltTime = 350; - exist = Configs.RECIPE_CONFIG.getBoolean("alloying", id.getPath(), true); - - return INSTANCE; - } - - public static Builder create(String id) { - return create(BetterEnd.makeID(id)); - } - - private ResourceLocation id; - private Ingredient primaryInput; - private Ingredient secondaryInput; - private ItemStack output; - private String group; - private float experience; - private int smeltTime; - private boolean alright = true; - - private Builder() {} - - public Builder setGroup(String group) { - this.group = group; - return this; - } - - public Builder setPrimaryInput(ItemLike... inputs) { - for (ItemLike item : inputs) { - this.alright &= RecipeHelper.exists(item); - } - this.primaryInput = Ingredient.of(inputs); - return this; - } - - public Builder setSecondaryInput(ItemLike... inputs) { - for (ItemLike item : inputs) { - this.alright &= RecipeHelper.exists(item); - } - this.secondaryInput = Ingredient.of(inputs); - return this; - } - - public Builder setPrimaryInput(Tag input) { - this.primaryInput = Ingredient.of(input); - return this; - } - - public Builder setSecondaryInput(Tag input) { - this.secondaryInput = Ingredient.of(input); - return this; - } - - public Builder setInput(ItemLike primaryInput, ItemLike secondaryInput) { - this.setPrimaryInput(primaryInput); - this.setSecondaryInput(secondaryInput); - return this; - } - - public Builder setInput(Tag primaryInput, Tag secondaryInput) { - this.setPrimaryInput(primaryInput); - this.setSecondaryInput(secondaryInput); - return this; - } - - public Builder setOutput(ItemLike output, int amount) { - this.alright &= RecipeHelper.exists(output); - this.output = new ItemStack(output, amount); - return this; - } - - public Builder setExpiriense(float amount) { - this.experience = amount; - return this; - } - - public Builder setSmeltTime(int time) { - this.smeltTime = time; - return this; - } - - public void build() { - if (exist) { - if (primaryInput == null) { - BetterEnd.LOGGER.warning("Primary input for Alloying recipe can't be 'null', recipe {} will be ignored!", id); - return; - } - if(secondaryInput == null) { - BetterEnd.LOGGER.warning("Secondary input for Alloying can't be 'null', recipe {} will be ignored!", id); - return; - } - if(output == null) { - BetterEnd.LOGGER.warning("Output for Alloying can't be 'null', recipe {} will be ignored!", id); - return; - } - if (BCLRecipeManager.getRecipe(TYPE, id) != null) { - BetterEnd.LOGGER.warning("Can't add Alloying recipe! Id {} already exists!", id); - return; - } - if (!alright) { - BetterEnd.LOGGER.debug("Can't add Alloying recipe {}! Ingeredient or output not exists.", id); - return; - } - BCLRecipeManager.addRecipe(TYPE, new AlloyingRecipe(id, group, primaryInput, secondaryInput, output, experience, smeltTime)); - } - } - } - - public static class Serializer implements RecipeSerializer { - @Override - public AlloyingRecipe fromJson(ResourceLocation id, JsonObject json) { - JsonArray ingredients = GsonHelper.getAsJsonArray(json, "ingredients"); - Ingredient primaryInput = Ingredient.fromJson(ingredients.get(0)); - Ingredient secondaryInput = Ingredient.fromJson(ingredients.get(1)); - String group = GsonHelper.getAsString(json, "group", ""); - JsonObject result = GsonHelper.getAsJsonObject(json, "result"); - ItemStack output = ItemUtil.fromJsonRecipe(result); - if (output == null) { - throw new IllegalStateException("Output item does not exists!"); - } - float experience = GsonHelper.getAsFloat(json, "experience", 0.0F); - int smeltTime = GsonHelper.getAsInt(json, "smelttime", 350); - - return new AlloyingRecipe(id, group, primaryInput, secondaryInput, output, experience, smeltTime); - } - - @Override - public AlloyingRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf packetBuffer) { - String group = packetBuffer.readUtf(32767); - Ingredient primary = Ingredient.fromNetwork(packetBuffer); - Ingredient secondary = Ingredient.fromNetwork(packetBuffer); - ItemStack output = packetBuffer.readItem(); - float experience = packetBuffer.readFloat(); - int smeltTime = packetBuffer.readVarInt(); - - return new AlloyingRecipe(id, group, primary, secondary, output, experience, smeltTime); - } - - @Override - public void toNetwork(FriendlyByteBuf packetBuffer, AlloyingRecipe recipe) { - packetBuffer.writeUtf(recipe.group); - recipe.primaryInput.toNetwork(packetBuffer); - recipe.secondaryInput.toNetwork(packetBuffer); - packetBuffer.writeItem(recipe.output); - packetBuffer.writeFloat(recipe.experience); - packetBuffer.writeVarInt(recipe.smeltTime); - } - } -} diff --git a/src/main/java/ru/betterend/recipe/builders/AnvilRecipe.java b/src/main/java/ru/betterend/recipe/builders/AnvilRecipe.java deleted file mode 100644 index 2a9ed475..00000000 --- a/src/main/java/ru/betterend/recipe/builders/AnvilRecipe.java +++ /dev/null @@ -1,309 +0,0 @@ -package ru.betterend.recipe.builders; - -import java.util.Objects; - -import com.google.gson.JsonObject; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.core.NonNullList; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.Tag; -import net.minecraft.util.GsonHelper; -import net.minecraft.world.Container; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TieredItem; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Recipe; -import net.minecraft.world.item.crafting.RecipeSerializer; -import net.minecraft.world.item.crafting.RecipeType; -import net.minecraft.world.level.ItemLike; -import net.minecraft.world.level.Level; -import ru.bclib.recipes.BCLRecipeManager; -import ru.betterend.BetterEnd; -import ru.betterend.config.Configs; -import ru.betterend.interfaces.BetterEndRecipe; -import ru.betterend.registry.EndTags; -import ru.betterend.util.ItemUtil; -import ru.betterend.util.RecipeHelper; - -public class AnvilRecipe implements Recipe, BetterEndRecipe { - - public final static String GROUP = "smithing"; - public final static RecipeType TYPE = BCLRecipeManager.registerType(BetterEnd.MOD_ID, GROUP); - public final static Serializer SERIALIZER = BCLRecipeManager.registerSerializer(BetterEnd.MOD_ID, GROUP, new Serializer()); - public final static ResourceLocation ID = BetterEnd.makeID(GROUP); - - private final ResourceLocation id; - private final Ingredient input; - private final ItemStack output; - private final int damage; - private final int toolLevel; - private final int anvilLevel; - private final int inputCount; - - public AnvilRecipe(ResourceLocation identifier, Ingredient input, ItemStack output, int inputCount, int toolLevel, int anvilLevel, int damage) { - this.id = identifier; - this.input = input; - this.output = output; - this.toolLevel = toolLevel; - this.anvilLevel = anvilLevel; - this.inputCount = inputCount; - this.damage = damage; - } - - @Override - public RecipeSerializer getSerializer() { - return SERIALIZER; - } - - @Override - public ItemStack getResultItem() { - return this.output; - } - - @Override - public boolean matches(Container craftingInventory, Level world) { - return this.matches(craftingInventory); - } - - @Override - public ItemStack assemble(Container craftingInventory) { - return this.output.copy(); - } - - public ItemStack craft(Container craftingInventory, Player player) { - if (!player.isCreative()) { - if (!checkHammerDurability(craftingInventory, player)) return ItemStack.EMPTY; - ItemStack hammer = craftingInventory.getItem(1); - hammer.hurtAndBreak(this.damage, player, entity -> - entity.broadcastBreakEvent((InteractionHand) null)); - } - return this.assemble(craftingInventory); - } - - public boolean checkHammerDurability(Container craftingInventory, Player player) { - if (player.isCreative()) return true; - ItemStack hammer = craftingInventory.getItem(1); - int damage = hammer.getDamageValue() + this.damage; - return damage < hammer.getMaxDamage(); - } - - public boolean matches(Container craftingInventory) { - ItemStack hammer = craftingInventory.getItem(1); - if (hammer.isEmpty() || !EndTags.HAMMERS.contains(hammer.getItem())) { - return false; - } - ItemStack material = craftingInventory.getItem(0); - int materialCount = material.getCount(); - int level = ((TieredItem) hammer.getItem()).getTier().getLevel(); - return this.input.test(craftingInventory.getItem(0)) && - materialCount >= this.inputCount && - level >= this.toolLevel; - } - - public int getDamage() { - return this.damage; - } - - public int getInputCount() { - return this.inputCount; - } - - public int getAnvilLevel() { - return this.anvilLevel; - } - - @Override - public NonNullList getIngredients() { - NonNullList defaultedList = NonNullList.create(); - defaultedList.add(Ingredient.of(EndTags.HAMMERS.getValues().stream().filter(hammer -> - ((TieredItem) hammer).getTier().getLevel() >= toolLevel).map(ItemStack::new))); - defaultedList.add(input); - - return defaultedList; - } - - @Override - @Environment(EnvType.CLIENT) - public boolean canCraftInDimensions(int width, int height) { - return true; - } - - @Override - public ResourceLocation getId() { - return this.id; - } - - @Override - public RecipeType getType() { - return TYPE; - } - - @Override - public boolean isSpecial() { - return true; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - AnvilRecipe that = (AnvilRecipe) o; - return damage == that.damage && toolLevel == that.toolLevel && id.equals(that.id) && input.equals(that.input) && output.equals(that.output); - } - - @Override - public int hashCode() { - return Objects.hash(id, input, output, damage, toolLevel); - } - - @Override - public String toString() { - return "AnvilRecipe [" + id + "]"; - } - - public static class Builder { - private final static Builder INSTANCE = new Builder(); - - public static Builder create(String id) { - return create(BetterEnd.makeID(id)); - } - - public static Builder create(ResourceLocation id) { - INSTANCE.id = id; - INSTANCE.input = null; - INSTANCE.output = null; - INSTANCE.inputCount = 1; - INSTANCE.toolLevel = 1; - INSTANCE.anvilLevel = 1; - INSTANCE.damage = 1; - INSTANCE.alright = true; - - return INSTANCE; - } - - private ResourceLocation id; - private Ingredient input; - private ItemStack output; - private int inputCount = 1; - private int toolLevel = 1; - private int anvilLevel = 1; - private int damage = 1; - private boolean alright; - - private Builder() {} - - public Builder setInput(ItemLike... inputItems) { - this.alright &= RecipeHelper.exists(inputItems); - this.setInput(Ingredient.of(inputItems)); - return this; - } - - public Builder setInput(Tag inputTag) { - this.setInput(Ingredient.of(inputTag)); - return this; - } - - public Builder setInput(Ingredient ingredient) { - this.input = ingredient; - return this; - } - - public Builder setInputCount(int count) { - this.inputCount = count; - return this; - } - - public Builder setOutput(ItemLike output) { - return this.setOutput(output, 1); - } - - public Builder setOutput(ItemLike output, int amount) { - this.alright &= RecipeHelper.exists(output); - this.output = new ItemStack(output, amount); - return this; - } - - public Builder setToolLevel(int level) { - this.toolLevel = level; - return this; - } - - public Builder setAnvilLevel(int level) { - this.anvilLevel = level; - return this; - } - - public Builder setDamage(int damage) { - this.damage = damage; - return this; - } - - public void build() { - if (Configs.RECIPE_CONFIG.getBoolean("anvil", id.getPath(), true)) { - if (input == null) { - BetterEnd.LOGGER.warning("Input for Anvil recipe can't be 'null', recipe {} will be ignored!", id); - return; - } - if(output == null) { - BetterEnd.LOGGER.warning("Output for Anvil recipe can't be 'null', recipe {} will be ignored!", id); - return; - } - if (BCLRecipeManager.getRecipe(TYPE, id) != null) { - BetterEnd.LOGGER.warning("Can't add Anvil recipe! Id {} already exists!", id); - return; - } - if (!alright) { - BetterEnd.LOGGER.debug("Can't add Anvil recipe {}! Ingeredient or output not exists.", id); - return; - } - BCLRecipeManager.addRecipe(TYPE, new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage)); - } - } - } - - public static class Serializer implements RecipeSerializer { - @Override - public AnvilRecipe fromJson(ResourceLocation id, JsonObject json) { - Ingredient input = Ingredient.fromJson(json.get("input")); - JsonObject result = GsonHelper.getAsJsonObject(json, "result"); - ItemStack output = ItemUtil.fromJsonRecipe(result); - if (output == null) { - throw new IllegalStateException("Output item does not exists!"); - } - int inputCount = GsonHelper.getAsInt(json, "inputCount", 1); - int toolLevel = GsonHelper.getAsInt(json, "toolLevel", 1); - int anvilLevel = GsonHelper.getAsInt(json, "anvilLevel", 1); - int damage = GsonHelper.getAsInt(json, "damage", 1); - - return new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage); - } - - @Override - public AnvilRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf packetBuffer) { - Ingredient input = Ingredient.fromNetwork(packetBuffer); - ItemStack output = packetBuffer.readItem(); - int inputCount = packetBuffer.readVarInt(); - int toolLevel = packetBuffer.readVarInt(); - int anvilLevel = packetBuffer.readVarInt(); - int damage = packetBuffer.readVarInt(); - - return new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage); - } - - @Override - public void toNetwork(FriendlyByteBuf packetBuffer, AnvilRecipe recipe) { - recipe.input.toNetwork(packetBuffer); - packetBuffer.writeItem(recipe.output); - packetBuffer.writeVarInt(recipe.inputCount); - packetBuffer.writeVarInt(recipe.toolLevel); - packetBuffer.writeVarInt(recipe.anvilLevel); - packetBuffer.writeVarInt(recipe.damage); - } - } -} diff --git a/src/main/java/ru/betterend/recipe/builders/InfusionRecipe.java b/src/main/java/ru/betterend/recipe/builders/InfusionRecipe.java deleted file mode 100644 index b05b2f37..00000000 --- a/src/main/java/ru/betterend/recipe/builders/InfusionRecipe.java +++ /dev/null @@ -1,260 +0,0 @@ -package ru.betterend.recipe.builders; - -import java.util.Arrays; - -import com.google.gson.JsonObject; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.core.NonNullList; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.GsonHelper; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Recipe; -import net.minecraft.world.item.crafting.RecipeSerializer; -import net.minecraft.world.item.crafting.RecipeType; -import net.minecraft.world.level.ItemLike; -import net.minecraft.world.level.Level; -import ru.bclib.recipes.BCLRecipeManager; -import ru.betterend.BetterEnd; -import ru.betterend.config.Configs; -import ru.betterend.interfaces.BetterEndRecipe; -import ru.betterend.rituals.InfusionRitual; -import ru.betterend.util.ItemUtil; - -public class InfusionRecipe implements Recipe, BetterEndRecipe { - - public final static String GROUP = "infusion"; - public final static RecipeType TYPE = BCLRecipeManager.registerType(BetterEnd.MOD_ID, GROUP); - public final static Serializer SERIALIZER = BCLRecipeManager.registerSerializer(BetterEnd.MOD_ID, GROUP, new Serializer()); - public final static ResourceLocation ID = BetterEnd.makeID(GROUP); - - private final ResourceLocation id; - private final Ingredient[] catalysts; - private Ingredient input; - private ItemStack output; - private int time = 1; - private String group; - - private InfusionRecipe(ResourceLocation id) { - this(id, null, null); - } - - private InfusionRecipe(ResourceLocation id, Ingredient input, ItemStack output) { - this.id = id; - this.input = input; - this.output = output; - this.catalysts = new Ingredient[8]; - Arrays.fill(catalysts, Ingredient.EMPTY); - } - - public int getInfusionTime() { - return this.time; - } - - @Override - public boolean matches(InfusionRitual inv, Level world) { - boolean valid = this.input.test(inv.getItem(0)); - if (!valid) return false; - for (int i = 0; i < 8; i++) { - valid &= this.catalysts[i].test(inv.getItem(i + 1)); - } - return valid; - } - - @Override - public ItemStack assemble(InfusionRitual ritual) { - return output.copy(); - } - - @Override - public boolean canCraftInDimensions(int width, int height) { - return true; - } - - @Override - public NonNullList getIngredients() { - NonNullList defaultedList = NonNullList.create(); - defaultedList.add(input); - defaultedList.addAll(Arrays.asList(catalysts)); - return defaultedList; - } - - @Override - public ItemStack getResultItem() { - return this.output; - } - - @Override - public ResourceLocation getId() { - return this.id; - } - - @Override - @Environment(EnvType.CLIENT) - public String getGroup() { - return this.group; - } - - @Override - public RecipeSerializer getSerializer() { - return SERIALIZER; - } - - @Override - public RecipeType getType() { - return TYPE; - } - - public static class Builder { - private final static Builder INSTANCE = new Builder(); - private static boolean exist; - - public static Builder create(String id) { - return create(BetterEnd.makeID(id)); - } - - public static Builder create(ResourceLocation id) { - INSTANCE.id = id; - INSTANCE.input = null; - INSTANCE.output = null; - INSTANCE.time = 1; - exist = Configs.RECIPE_CONFIG.getBoolean("infusion", id.getPath(), true); - - Arrays.fill(INSTANCE.catalysts, Ingredient.EMPTY); - - return INSTANCE; - } - - private final Ingredient[] catalysts = new Ingredient[8]; - private ResourceLocation id; - private Ingredient input; - private ItemStack output; - private String group; - private int time = 1; - - private Builder() { - Arrays.fill(catalysts, Ingredient.EMPTY); - } - - public Builder setGroup(String group) { - this.group = group; - return this; - } - - public Builder setInput(ItemLike input) { - this.input = Ingredient.of(input); - return this; - } - - public Builder setOutput(ItemLike output) { - this.output = new ItemStack(output); - this.output.setCount(1); - return this; - } - - public Builder setOutput(ItemStack output) { - this.output = output; - this.output.setCount(1); - return this; - } - - public Builder setTime(int time) { - this.time = time; - return this; - } - - public Builder addCatalyst(int slot, ItemLike... items) { - if (slot > 7) return this; - this.catalysts[slot] = Ingredient.of(items); - return this; - } - - public void build() { - if (exist) { - if (input == null) { - BetterEnd.LOGGER.warning("Input for Infusion recipe can't be 'null', recipe {} will be ignored!", id); - return; - } - if (output == null) { - BetterEnd.LOGGER.warning("Output for Infusion recipe can't be 'null', recipe {} will be ignored!", id); - return; - } - InfusionRecipe recipe = new InfusionRecipe(id, input, output); - recipe.group = group != null ? group : GROUP; - recipe.time = time; - int empty = 0; - for (int i = 0; i < catalysts.length; i++) { - if (catalysts[i].isEmpty()) empty++; - else recipe.catalysts[i] = catalysts[i]; - } - if (empty == catalysts.length) { - BetterEnd.LOGGER.warning("At least one catalyst must be non empty, recipe {} will be ignored!", id); - return; - } - BCLRecipeManager.addRecipe(TYPE, recipe); - } - } - } - - public static class Serializer implements RecipeSerializer { - @Override - public InfusionRecipe fromJson(ResourceLocation id, JsonObject json) { - InfusionRecipe recipe = new InfusionRecipe(id); - recipe.input = Ingredient.fromJson(json.get("input")); - JsonObject result = GsonHelper.getAsJsonObject(json, "result"); - recipe.output = ItemUtil.fromJsonRecipe(result); - if (recipe.output == null) { - throw new IllegalStateException("Output item does not exists!"); - } - recipe.group = GsonHelper.getAsString(json, "group", GROUP); - recipe.time = GsonHelper.getAsInt(json, "time", 1); - - JsonObject catalysts = GsonHelper.getAsJsonObject(json, "catalysts"); - ItemStack catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "north", "")); - recipe.catalysts[0] = (catalyst != null && !catalyst.isEmpty()) ? Ingredient.of(catalyst.getItem()) : Ingredient.EMPTY; - catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "north_east", "")); - recipe.catalysts[1] = (catalyst != null && !catalyst.isEmpty()) ? Ingredient.of(catalyst.getItem()) : Ingredient.EMPTY; - catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "east", "")); - recipe.catalysts[2] = (catalyst != null && !catalyst.isEmpty()) ? Ingredient.of(catalyst.getItem()) : Ingredient.EMPTY; - catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "south_east", "")); - recipe.catalysts[3] = (catalyst != null && !catalyst.isEmpty()) ? Ingredient.of(catalyst.getItem()) : Ingredient.EMPTY; - catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "south", "")); - recipe.catalysts[4] = (catalyst != null && !catalyst.isEmpty()) ? Ingredient.of(catalyst.getItem()) : Ingredient.EMPTY; - catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "south_west", "")); - recipe.catalysts[5] = (catalyst != null && !catalyst.isEmpty()) ? Ingredient.of(catalyst.getItem()) : Ingredient.EMPTY; - catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "west", "")); - recipe.catalysts[6] = (catalyst != null && !catalyst.isEmpty()) ? Ingredient.of(catalyst.getItem()) : Ingredient.EMPTY; - catalyst = ItemUtil.fromStackString(GsonHelper.getAsString(catalysts, "north_west", "")); - recipe.catalysts[7] = (catalyst != null && !catalyst.isEmpty()) ? Ingredient.of(catalyst.getItem()) : Ingredient.EMPTY; - - return recipe; - } - - @Override - public InfusionRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) { - InfusionRecipe recipe = new InfusionRecipe(id); - recipe.input = Ingredient.fromNetwork(buffer); - recipe.output = buffer.readItem(); - recipe.group = buffer.readUtf(); - recipe.time = buffer.readVarInt(); - for (int i = 0; i < 8; i++) { - recipe.catalysts[i] = Ingredient.fromNetwork(buffer); - } - return recipe; - } - - @Override - public void toNetwork(FriendlyByteBuf buffer, InfusionRecipe recipe) { - recipe.input.toNetwork(buffer); - buffer.writeItem(recipe.output); - buffer.writeUtf(recipe.group); - buffer.writeVarInt(recipe.time); - for (int i = 0; i < 8; i++) { - recipe.catalysts[i].toNetwork(buffer); - } - } - } -} diff --git a/src/main/java/ru/betterend/registry/EndAttributes.java b/src/main/java/ru/betterend/registry/EndAttributes.java deleted file mode 100644 index 95d2dda4..00000000 --- a/src/main/java/ru/betterend/registry/EndAttributes.java +++ /dev/null @@ -1,21 +0,0 @@ -package ru.betterend.registry; - -import net.minecraft.core.Registry; -import net.minecraft.world.entity.ai.attributes.Attribute; -import net.minecraft.world.entity.ai.attributes.AttributeSupplier; -import ru.betterend.BetterEnd; -import ru.betterend.item.EndAttribute; - -public class EndAttributes { - public final static Attribute BLINDNESS_RESISTANCE = registerAttribute("generic.blindness_resistance", 0.0, true); - - public static Attribute registerAttribute(String name, double value, boolean syncable) { - return Registry.register(Registry.ATTRIBUTE, BetterEnd.makeID(name), new EndAttribute("attribute.name." + name, value).setSyncable(syncable)); - } - - public static AttributeSupplier.Builder addLivingEntityAttributes(AttributeSupplier.Builder builder) { - return builder.add(EndAttributes.BLINDNESS_RESISTANCE); - } -} - - diff --git a/src/main/java/ru/betterend/registry/EndBiomes.java b/src/main/java/ru/betterend/registry/EndBiomes.java deleted file mode 100644 index b39fd679..00000000 --- a/src/main/java/ru/betterend/registry/EndBiomes.java +++ /dev/null @@ -1,384 +0,0 @@ -package ru.betterend.registry; - -import java.io.InputStream; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import net.fabricmc.fabric.impl.biome.InternalBiomeData; -import net.fabricmc.fabric.impl.biome.WeightedBiomePicker; -import net.minecraft.core.Registry; -import net.minecraft.data.BuiltinRegistries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.Biome.BiomeCategory; -import net.minecraft.world.level.biome.Biomes; -import ru.bclib.BCLib; -import ru.bclib.api.BiomeAPI; -import ru.bclib.api.ModIntegrationAPI; -import ru.bclib.util.JsonFactory; -import ru.bclib.world.biomes.BCLBiome; -import ru.bclib.world.generator.BiomeMap; -import ru.bclib.world.generator.BiomePicker; -import ru.betterend.config.Configs; -import ru.betterend.integration.EndBiomeIntegration; -import ru.betterend.interfaces.IBiomeList; -import ru.betterend.world.biome.EndBiome; -import ru.betterend.world.biome.air.BiomeIceStarfield; -import ru.betterend.world.biome.cave.EmptyAuroraCaveBiome; -import ru.betterend.world.biome.cave.EmptyEndCaveBiome; -import ru.betterend.world.biome.cave.EmptySmaragdantCaveBiome; -import ru.betterend.world.biome.cave.EndCaveBiome; -import ru.betterend.world.biome.cave.JadeCaveBiome; -import ru.betterend.world.biome.cave.LushAuroraCaveBiome; -import ru.betterend.world.biome.cave.LushSmaragdantCaveBiome; -import ru.betterend.world.biome.land.AmberLandBiome; -import ru.betterend.world.biome.land.BlossomingSpiresBiome; -import ru.betterend.world.biome.land.ChorusForestBiome; -import ru.betterend.world.biome.land.CrystalMountainsBiome; -import ru.betterend.world.biome.land.DragonGraveyardsBiome; -import ru.betterend.world.biome.land.DryShrublandBiome; -import ru.betterend.world.biome.land.DustWastelandsBiome; -import ru.betterend.world.biome.land.FoggyMushroomlandBiome; -import ru.betterend.world.biome.land.GlowingGrasslandsBiome; -import ru.betterend.world.biome.land.LanternWoodsBiome; -import ru.betterend.world.biome.land.MegalakeBiome; -import ru.betterend.world.biome.land.MegalakeGroveBiome; -import ru.betterend.world.biome.land.NeonOasisBiome; -import ru.betterend.world.biome.land.PaintedMountainsBiome; -import ru.betterend.world.biome.land.ShadowForestBiome; -import ru.betterend.world.biome.land.SulphurSpringsBiome; -import ru.betterend.world.biome.land.UmbrellaJungleBiome; -import ru.betterend.world.generator.BiomeType; -import ru.betterend.world.generator.GeneratorOptions; - -public class EndBiomes { - private static final Map ID_MAP = Maps.newHashMap(); - public static final Set FABRIC_VOID = Sets.newHashSet(); - private static final Set SUBBIOMES_UNMUTABLES = Sets.newHashSet(); - - public static final BiomePicker LAND_BIOMES = new BiomePicker(); - public static final BiomePicker VOID_BIOMES = new BiomePicker(); - public static final BiomePicker CAVE_BIOMES = new BiomePicker(); - public static final List SUBBIOMES = Lists.newArrayList(); - private static final JsonObject EMPTY_JSON = new JsonObject(); - private static BiomeMap caveBiomeMap; - - // Vanilla Land - public static final EndBiome END = registerBiome(Biomes.THE_END, BiomeType.LAND, 1F); - public static final EndBiome END_MIDLANDS = registerSubBiome(Biomes.END_MIDLANDS, END, 0.5F); - public static final EndBiome END_HIGHLANDS = registerSubBiome(Biomes.END_HIGHLANDS, END, 0.5F); - - // Vanilla Void - public static final EndBiome END_BARRENS = registerBiome(Biomes.END_BARRENS, BiomeType.VOID, 1F); - public static final EndBiome SMALL_END_ISLANDS = registerBiome(Biomes.SMALL_END_ISLANDS, BiomeType.VOID, 1); - - // Better End Land - public static final EndBiome FOGGY_MUSHROOMLAND = registerBiome(new FoggyMushroomlandBiome(), BiomeType.LAND); - public static final EndBiome CHORUS_FOREST = registerBiome(new ChorusForestBiome(), BiomeType.LAND); - public static final EndBiome DUST_WASTELANDS = registerBiome(new DustWastelandsBiome(), BiomeType.LAND); - public static final EndBiome MEGALAKE = registerBiome(new MegalakeBiome(), BiomeType.LAND); - public static final EndBiome MEGALAKE_GROVE = registerSubBiome(new MegalakeGroveBiome(), MEGALAKE); - public static final EndBiome CRYSTAL_MOUNTAINS = registerBiome(new CrystalMountainsBiome(), BiomeType.LAND); - public static final EndBiome PAINTED_MOUNTAINS = registerSubBiome(new PaintedMountainsBiome(), DUST_WASTELANDS); - public static final EndBiome SHADOW_FOREST = registerBiome(new ShadowForestBiome(), BiomeType.LAND); - public static final EndBiome AMBER_LAND = registerBiome(new AmberLandBiome(), BiomeType.LAND); - public static final EndBiome BLOSSOMING_SPIRES = registerBiome(new BlossomingSpiresBiome(), BiomeType.LAND); - public static final EndBiome SULPHUR_SPRINGS = registerBiome(new SulphurSpringsBiome(), BiomeType.LAND); - public static final EndBiome UMBRELLA_JUNGLE = registerBiome(new UmbrellaJungleBiome(), BiomeType.LAND); - public static final EndBiome GLOWING_GRASSLANDS = registerBiome(new GlowingGrasslandsBiome(), BiomeType.LAND); - public static final EndBiome DRAGON_GRAVEYARDS = registerBiome(new DragonGraveyardsBiome(), BiomeType.LAND); - public static final EndBiome DRY_SHRUBLAND = registerBiome(new DryShrublandBiome(), BiomeType.LAND); - public static final EndBiome LANTERN_WOODS = registerBiome(new LanternWoodsBiome(), BiomeType.LAND); - public static final EndBiome NEON_OASIS = registerSubBiome(new NeonOasisBiome(), DUST_WASTELANDS); - - // Better End Void - public static final EndBiome ICE_STARFIELD = registerBiome(new BiomeIceStarfield(), BiomeType.VOID); - - // Better End Caves - public static final EndCaveBiome EMPTY_END_CAVE = registerCaveBiome(new EmptyEndCaveBiome()); - public static final EndCaveBiome EMPTY_SMARAGDANT_CAVE = registerCaveBiome(new EmptySmaragdantCaveBiome()); - public static final EndCaveBiome LUSH_SMARAGDANT_CAVE = registerCaveBiome(new LushSmaragdantCaveBiome()); - public static final EndCaveBiome EMPTY_AURORA_CAVE = registerCaveBiome(new EmptyAuroraCaveBiome()); - public static final EndCaveBiome LUSH_AURORA_CAVE = registerCaveBiome(new LushAuroraCaveBiome()); - public static final EndCaveBiome JADE_CAVE = registerCaveBiome(new JadeCaveBiome()); - - public static void register() { - CAVE_BIOMES.rebuild(); - } - - public static void onWorldLoad(long seed) { - if (caveBiomeMap == null || caveBiomeMap.getSeed() != seed) { - caveBiomeMap = new BiomeMap(seed, GeneratorOptions.getBiomeSizeCaves(), CAVE_BIOMES); - } - } - - public static void mutateRegistry(Registry biomeRegistry) { - LAND_BIOMES.clearMutables(); - VOID_BIOMES.clearMutables(); - CAVE_BIOMES.clearMutables(); - - if (FABRIC_VOID.isEmpty()) { - loadFabricAPIBiomes(); - } - - Map configs = Maps.newHashMap(); - - biomeRegistry.forEach((biome) -> { - if (biome.getBiomeCategory() == BiomeCategory.THEEND) { - ResourceLocation id = biomeRegistry.getKey(biome); - if (!id.getNamespace().equals("ultra_amplified_dimension") && Configs.BIOME_CONFIG.getBoolean(id, "enabled", true)) { - if (!LAND_BIOMES.containsImmutable(id) && !VOID_BIOMES.containsImmutable(id) && !SUBBIOMES_UNMUTABLES.contains(id)) { - JsonObject config = configs.get(id.getNamespace()); - if (config == null) { - config = loadJsonConfig(id.getNamespace()); - configs.put(id.getNamespace(), config); - } - float fog = 1F; - float chance = 1F; - boolean isVoid = FABRIC_VOID.contains(id); - boolean hasCaves = true; - JsonElement element = config.get(id.getPath()); - if (element != null && element.isJsonObject()) { - fog = JsonFactory.getFloat(element.getAsJsonObject(), "fog_density", 1); - chance = JsonFactory.getFloat(element.getAsJsonObject(), "generation_chance", 1); - isVoid = JsonFactory.getString(element.getAsJsonObject(), "type", "land").equals("void"); - hasCaves = JsonFactory.getBoolean(element.getAsJsonObject(), "has_caves", true); - } - EndBiome endBiome = new EndBiome(id, biome, fog, chance, hasCaves); - - if (isVoid) { - VOID_BIOMES.addBiomeMutable(endBiome); - } - else { - LAND_BIOMES.addBiomeMutable(endBiome); - } - ID_MAP.put(id, endBiome); - } - } - } - }); - ModIntegrationAPI.getIntegrations().forEach(integration -> { - if (integration instanceof EndBiomeIntegration && integration.modIsInstalled()) { - ((EndBiomeIntegration) integration).addBiomes(); - } - }); - Configs.BIOME_CONFIG.saveChanges(); - - rebuildPicker(LAND_BIOMES, biomeRegistry); - rebuildPicker(VOID_BIOMES, biomeRegistry); - rebuildPicker(CAVE_BIOMES, biomeRegistry); - - SUBBIOMES.forEach((endBiome) -> { - endBiome.updateActualBiomes(biomeRegistry); - }); - } - - private static void rebuildPicker(BiomePicker picker, Registry biomeRegistry) { - picker.rebuild(); - picker.getBiomes().forEach((endBiome) -> { - endBiome.updateActualBiomes(biomeRegistry); - }); - } - - private static void loadFabricAPIBiomes() { - List> biomes = Lists.newArrayList(); - biomes.addAll(getBiomes(InternalBiomeData.getEndBiomesMap().get(Biomes.SMALL_END_ISLANDS))); - biomes.addAll(getBiomes(InternalBiomeData.getEndBarrensMap().get(Biomes.END_BARRENS))); - biomes.forEach((key) -> FABRIC_VOID.add(key.location())); - FABRIC_VOID.removeIf(id -> id.getNamespace().equals("endplus")); - - if (BCLib.isDevEnvironment()) { - System.out.println("=================================="); - System.out.println("Added void biomes from Fabric API:"); - FABRIC_VOID.forEach((id) -> { - System.out.println(id); - }); - System.out.println("=================================="); - } - } - - private static List> getBiomes(WeightedBiomePicker picker) { - IBiomeList biomeList = (IBiomeList) (Object) picker; - return biomeList == null ? Collections.emptyList() : biomeList.getBiomes(); - } - - private static JsonObject loadJsonConfig(String namespace) { - InputStream inputstream = EndBiomes.class.getResourceAsStream("/data/" + namespace + "/end_biome_properties.json"); - if (inputstream != null) { - return JsonFactory.getJsonObject(inputstream); - } - else { - return EMPTY_JSON; - } - } - - /** - * Registers new {@link EndBiome} and adds it to picker, can be used to add existing mod biomes into the End. - * @param biome - {@link Biome} instance - * @param type - {@link BiomeType} - * @param genChance - generation chance [0.0F - Infinity] - * @return registered {@link EndBiome} - */ - public static EndBiome registerBiome(Biome biome, BiomeType type, float genChance) { - return registerBiome(biome, type, 1, genChance); - } - - /** - * Registers new {@link EndBiome} and adds it to picker, can be used to add existing mod biomes into the End. - * @param biome - {@link Biome} instance - * @param type - {@link BiomeType} - * @param fogDensity - density of fog (def: 1F) [0.0F - Infinity] - * @param genChance - generation chance [0.0F - Infinity] - * @return registered {@link EndBiome} - */ - public static EndBiome registerBiome(Biome biome, BiomeType type, float fogDensity, float genChance) { - EndBiome endBiome = new EndBiome(BuiltinRegistries.BIOME.getKey(biome), biome, fogDensity, genChance, true); - if (Configs.BIOME_CONFIG.getBoolean(endBiome.getID(), "enabled", true)) { - addToPicker(endBiome, type); - } - return endBiome; - } - - /** - * Registers new {@link EndBiome} from existed {@link Biome} and put as a sub-biome into selected parent. - * @param biome - {@link Biome} instance - * @param parent - {@link EndBiome} to be linked with - * @param genChance - generation chance [0.0F - Infinity] - * @return registered {@link EndBiome} - */ - public static EndBiome registerSubBiome(Biome biome, EndBiome parent, float genChance, boolean hasCaves) { - return registerSubBiome(biome, parent, 1, genChance, hasCaves); - } - - /** - * Registers new {@link EndBiome} from existed {@link Biome} and put as a sub-biome into selected parent. - * @param biome - {@link Biome} instance - * @param parent - {@link EndBiome} to be linked with - * @param fogDensity - density of fog (def: 1F) [0.0F - Infinity] - * @param genChance - generation chance [0.0F - Infinity] - * @return registered {@link EndBiome} - */ - public static EndBiome registerSubBiome(Biome biome, EndBiome parent, float fogDensity, float genChance, boolean hasCaves) { - EndBiome endBiome = new EndBiome(BuiltinRegistries.BIOME.getKey(biome), biome, fogDensity, genChance, hasCaves); - if (Configs.BIOME_CONFIG.getBoolean(endBiome.getID(), "enabled", true)) { - BiomeAPI.registerBiome(endBiome); - parent.addSubBiome(endBiome); - SUBBIOMES.add(endBiome); - SUBBIOMES_UNMUTABLES.add(endBiome.getID()); - ID_MAP.put(endBiome.getID(), endBiome); - } - return endBiome; - } - - /** - * Put existing {@link EndBiome} as a sub-biome into selected parent. - * @param biome - {@link EndBiome} instance - * @param parent - {@link EndBiome} to be linked with - * @return registered {@link EndBiome} - */ - public static EndBiome registerSubBiome(EndBiome biome, EndBiome parent) { - if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { - BiomeAPI.registerBiome(biome); - parent.addSubBiome(biome); - SUBBIOMES.add(biome); - SUBBIOMES_UNMUTABLES.add(biome.getID()); - ID_MAP.put(biome.getID(), biome); - BiomeAPI.addEndLandBiomeToFabricApi(biome); - } - return biome; - } - - /** - * Registers {@link EndBiome} and adds it into worldgen. - * @param biome - {@link EndBiome} instance - * @param type - {@link BiomeType} - * @return registered {@link EndBiome} - */ - public static EndBiome registerBiome(EndBiome biome, BiomeType type) { - if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { - BiomeAPI.registerBiome(biome); - addToPicker(biome, type); - ID_MAP.put(biome.getID(), biome); - if (type == BiomeType.LAND) { - BiomeAPI.addEndLandBiomeToFabricApi(biome); - } - else { - BiomeAPI.addEndVoidBiomeToFabricApi(biome); - } - } - return biome; - } - - /** - * Put integration sub-biome {@link EndBiome} into subbiomes list and registers it. - * @param biome - {@link EndBiome} instance - * @return registered {@link EndBiome} - */ - public static EndBiome registerSubBiomeIntegration(EndBiome biome) { - if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { - BiomeAPI.registerBiome(biome); - SUBBIOMES.add(biome); - SUBBIOMES_UNMUTABLES.add(biome.getID()); - ID_MAP.put(biome.getID(), biome); - BiomeAPI.addEndLandBiomeToFabricApi(biome); - } - return biome; - } - - /** - * Link integration sub-biome with parent. - * @param biome - {@link EndBiome} instance - * @param parent - {@link ResourceLocation} parent id - */ - public static void addSubBiomeIntegration(EndBiome biome, ResourceLocation parent) { - if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { - EndBiome parentBiome = ID_MAP.get(parent); - if (parentBiome != null && !parentBiome.containsSubBiome(biome)) { - parentBiome.addSubBiome(biome); - } - } - } - - public static EndBiome registerBiome(ResourceKey key, BiomeType type, float genChance) { - return registerBiome(BuiltinRegistries.BIOME.get(key), type, genChance); - } - - public static EndBiome registerSubBiome(ResourceKey key, EndBiome parent, float genChance) { - return registerSubBiome(BuiltinRegistries.BIOME.get(key), parent, genChance, true); - } - - private static void addToPicker(EndBiome biome, BiomeType type) { - if (type == BiomeType.LAND) { - LAND_BIOMES.addBiome(biome); - } - else { - VOID_BIOMES.addBiome(biome); - } - } - - public static EndCaveBiome registerCaveBiome(EndCaveBiome biome) { - if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { - BiomeAPI.registerBiome(biome); - CAVE_BIOMES.addBiome(biome); - ID_MAP.put(biome.getID(), biome); - } - return biome; - } - - public static EndCaveBiome getCaveBiome(int x, int z) { - return (EndCaveBiome) caveBiomeMap.getBiome(x, z); - } - - public static boolean hasBiome(ResourceLocation biomeID) { - return ID_MAP.containsKey(biomeID); - } -} diff --git a/src/main/java/ru/betterend/registry/EndBlockEntities.java b/src/main/java/ru/betterend/registry/EndBlockEntities.java deleted file mode 100644 index 93535912..00000000 --- a/src/main/java/ru/betterend/registry/EndBlockEntities.java +++ /dev/null @@ -1,39 +0,0 @@ -package ru.betterend.registry; - -import net.minecraft.core.Registry; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.EndStoneSmelter; -import ru.betterend.blocks.basis.PedestalBlock; -import ru.betterend.blocks.entities.BlockEntityHydrothermalVent; -import ru.betterend.blocks.entities.EndStoneSmelterBlockEntity; -import ru.betterend.blocks.entities.EternalPedestalEntity; -import ru.betterend.blocks.entities.InfusionPedestalEntity; -import ru.betterend.blocks.entities.PedestalBlockEntity; - -public class EndBlockEntities { - public final static BlockEntityType END_STONE_SMELTER = registerBlockEntity(EndStoneSmelter.ID, - BlockEntityType.Builder.of(EndStoneSmelterBlockEntity::new, EndBlocks.END_STONE_SMELTER)); - public final static BlockEntityType PEDESTAL = registerBlockEntity("pedestal", - BlockEntityType.Builder.of(PedestalBlockEntity::new, getPedestals())); - public final static BlockEntityType ETERNAL_PEDESTAL = registerBlockEntity("eternal_pedestal", - BlockEntityType.Builder.of(EternalPedestalEntity::new, EndBlocks.ETERNAL_PEDESTAL)); - public final static BlockEntityType INFUSION_PEDESTAL = registerBlockEntity("infusion_pedestal", - BlockEntityType.Builder.of(InfusionPedestalEntity::new, EndBlocks.INFUSION_PEDESTAL)); - public final static BlockEntityType HYDROTHERMAL_VENT = registerBlockEntity("hydrother_malvent", - BlockEntityType.Builder.of(BlockEntityHydrothermalVent::new, EndBlocks.HYDROTHERMAL_VENT)); - - public static BlockEntityType registerBlockEntity(String id, BlockEntityType.Builder builder) { - return Registry.register(Registry.BLOCK_ENTITY_TYPE, BetterEnd.makeID(id), builder.build(null)); - } - - public static void register() {} - - static Block[] getPedestals() { - return EndBlocks.getModBlocks().stream() - .filter(block -> block instanceof PedestalBlock && !((PedestalBlock) block).hasUniqueEntity()) - .toArray(Block[]::new); - } -} diff --git a/src/main/java/ru/betterend/registry/EndBlockEntityRenders.java b/src/main/java/ru/betterend/registry/EndBlockEntityRenders.java deleted file mode 100644 index a568502a..00000000 --- a/src/main/java/ru/betterend/registry/EndBlockEntityRenders.java +++ /dev/null @@ -1,15 +0,0 @@ -package ru.betterend.registry; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.client.rendereregistry.v1.BlockEntityRendererRegistry; -import ru.betterend.client.render.PedestalItemRenderer; - -@Environment(EnvType.CLIENT) -public class EndBlockEntityRenders { - public static void register() { - BlockEntityRendererRegistry.INSTANCE.register(EndBlockEntities.PEDESTAL, PedestalItemRenderer::new); - BlockEntityRendererRegistry.INSTANCE.register(EndBlockEntities.ETERNAL_PEDESTAL, PedestalItemRenderer::new); - BlockEntityRendererRegistry.INSTANCE.register(EndBlockEntities.INFUSION_PEDESTAL, PedestalItemRenderer::new); - } -} diff --git a/src/main/java/ru/betterend/registry/EndBlocks.java b/src/main/java/ru/betterend/registry/EndBlocks.java deleted file mode 100644 index 246e9ba9..00000000 --- a/src/main/java/ru/betterend/registry/EndBlocks.java +++ /dev/null @@ -1,384 +0,0 @@ -package ru.betterend.registry; - -import java.util.List; -import java.util.stream.Collectors; - -import org.jetbrains.annotations.NotNull; - -import net.fabricmc.fabric.api.item.v1.FabricItemSettings; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.material.MaterialColor; -import ru.bclib.blocks.BaseBarrelBlock; -import ru.bclib.blocks.BaseChestBlock; -import ru.bclib.blocks.BaseCropBlock; -import ru.bclib.blocks.BaseFurnaceBlock; -import ru.bclib.blocks.BaseLeavesBlock; -import ru.bclib.blocks.BaseOreBlock; -import ru.bclib.blocks.BasePathBlock; -import ru.bclib.blocks.BaseRotatedPillarBlock; -import ru.bclib.blocks.BaseSignBlock; -import ru.bclib.blocks.BaseSlabBlock; -import ru.bclib.blocks.BaseStairsBlock; -import ru.bclib.blocks.BaseVineBlock; -import ru.bclib.blocks.SimpleLeavesBlock; -import ru.bclib.blocks.StalactiteBlock; -import ru.bclib.registry.BaseBlockEntities; -import ru.bclib.registry.BlocksRegistry; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.*; -import ru.betterend.blocks.basis.EndTerrainBlock; -import ru.betterend.blocks.basis.EndTripleTerrain; -import ru.betterend.blocks.basis.EndUnderwaterWallPlantBlock; -import ru.betterend.blocks.basis.EndWallMushroom; -import ru.betterend.blocks.basis.EndWallPlantBlock; -import ru.betterend.blocks.basis.FurBlock; -import ru.betterend.blocks.basis.StoneLanternBlock; -import ru.betterend.blocks.complex.ColoredMaterial; -import ru.betterend.blocks.complex.CrystalSubblocksMaterial; -import ru.betterend.blocks.complex.MetalMaterial; -import ru.betterend.blocks.complex.StoneMaterial; -import ru.betterend.blocks.complex.WoodenMaterial; -import ru.betterend.config.Configs; -import ru.betterend.item.material.EndArmorMaterial; -import ru.betterend.item.material.EndToolMaterial; -import ru.betterend.tab.CreativeTabs; - -public class EndBlocks extends BlocksRegistry { - // Terrain // - public static final Block ENDSTONE_DUST = registerBlock("endstone_dust", new EndstoneDustBlock()); - public static final Block END_MYCELIUM = registerBlock("end_mycelium", new EndTerrainBlock(MaterialColor.COLOR_LIGHT_BLUE)); - public static final Block END_MOSS = registerBlock("end_moss", new EndTerrainBlock(MaterialColor.COLOR_CYAN)); - public static final Block CHORUS_NYLIUM = registerBlock("chorus_nylium", new EndTerrainBlock(MaterialColor.COLOR_MAGENTA)); - public static final Block CAVE_MOSS = registerBlock("cave_moss", new EndTripleTerrain(MaterialColor.COLOR_PURPLE)); - public static final Block CRYSTAL_MOSS = registerBlock("crystal_moss", new EndTerrainBlock(MaterialColor.COLOR_PINK)); - public static final Block SHADOW_GRASS = registerBlock("shadow_grass", new ShadowGrassBlock()); - public static final Block PINK_MOSS = registerBlock("pink_moss", new EndTerrainBlock(MaterialColor.COLOR_PINK)); - public static final Block AMBER_MOSS = registerBlock("amber_moss", new EndTerrainBlock(MaterialColor.COLOR_ORANGE)); - public static final Block JUNGLE_MOSS = registerBlock("jungle_moss", new EndTerrainBlock(MaterialColor.COLOR_GREEN)); - public static final Block SANGNUM = registerBlock("sangnum", new EndTerrainBlock(MaterialColor.COLOR_RED)); - public static final Block RUTISCUS = registerBlock("rutiscus", new EndTerrainBlock(MaterialColor.COLOR_ORANGE)); - - // Roads // - public static final Block END_MYCELIUM_PATH = registerBlock("end_mycelium_path", new BasePathBlock(END_MYCELIUM)); - public static final Block END_MOSS_PATH = registerBlock("end_moss_path", new BasePathBlock(END_MOSS)); - public static final Block CHORUS_NYLIUM_PATH = registerBlock("chorus_nylium_path", new BasePathBlock(CHORUS_NYLIUM)); - public static final Block CAVE_MOSS_PATH = registerBlock("cave_moss_path", new BasePathBlock(CAVE_MOSS)); - public static final Block CRYSTAL_MOSS_PATH = registerBlock("crystal_moss_path", new BasePathBlock(CRYSTAL_MOSS)); - public static final Block SHADOW_GRASS_PATH = registerBlock("shadow_grass_path", new BasePathBlock(SHADOW_GRASS)); - public static final Block PINK_MOSS_PATH = registerBlock("pink_moss_path", new BasePathBlock(PINK_MOSS)); - public static final Block AMBER_MOSS_PATH = registerBlock("amber_moss_path", new BasePathBlock(AMBER_MOSS)); - public static final Block JUNGLE_MOSS_PATH = registerBlock("jungle_moss_path", new BasePathBlock(JUNGLE_MOSS)); - public static final Block SANGNUM_PATH = registerBlock("sangnum_path", new BasePathBlock(SANGNUM)); - public static final Block RUTISCUS_PATH = registerBlock("rutiscus_path", new BasePathBlock(RUTISCUS)); - - public static final Block MOSSY_OBSIDIAN = registerBlock("mossy_obsidian", new MossyObsidian()); - public static final Block DRAGON_BONE_BLOCK = registerBlock("dragon_bone_block", new BaseRotatedPillarBlock(Blocks.BONE_BLOCK)); - public static final Block DRAGON_BONE_STAIRS = registerBlock("dragon_bone_stairs", new BaseStairsBlock(DRAGON_BONE_BLOCK)); - public static final Block DRAGON_BONE_SLAB = registerBlock("dragon_bone_slab", new BaseSlabBlock(DRAGON_BONE_BLOCK)); - public static final Block MOSSY_DRAGON_BONE = registerBlock("mossy_dragon_bone", new MossyDragonBoneBlock()); - - // Rocks // - public static final StoneMaterial FLAVOLITE = new StoneMaterial("flavolite", MaterialColor.SAND); - public static final StoneMaterial VIOLECITE = new StoneMaterial("violecite", MaterialColor.COLOR_PURPLE); - public static final StoneMaterial SULPHURIC_ROCK = new StoneMaterial("sulphuric_rock", MaterialColor.COLOR_BROWN); - public static final StoneMaterial VIRID_JADESTONE = new StoneMaterial("virid_jadestone", MaterialColor.COLOR_GREEN); - public static final StoneMaterial AZURE_JADESTONE = new StoneMaterial("azure_jadestone", MaterialColor.COLOR_LIGHT_BLUE); - public static final StoneMaterial SANDY_JADESTONE = new StoneMaterial("sandy_jadestone", MaterialColor.COLOR_YELLOW); - public static final Block BRIMSTONE = registerBlock("brimstone", new BrimstoneBlock()); - public static final Block SULPHUR_CRYSTAL = registerBlock("sulphur_crystal", new SulphurCrystalBlock()); - public static final Block MISSING_TILE = registerBlock("missing_tile", new MissingTileBlock()); - - public static final Block FLAVOLITE_RUNED = registerBlock("flavolite_runed", new RunedFlavolite(false)); - public static final Block FLAVOLITE_RUNED_ETERNAL = registerBlock("flavolite_runed_eternal", new RunedFlavolite(true)); - - public static final Block ANDESITE_PEDESTAL = registerBlock("andesite_pedestal", new PedestalVanilla(Blocks.ANDESITE)); - public static final Block DIORITE_PEDESTAL = registerBlock("diorite_pedestal", new PedestalVanilla(Blocks.DIORITE)); - public static final Block GRANITE_PEDESTAL = registerBlock("granite_pedestal", new PedestalVanilla(Blocks.GRANITE)); - public static final Block QUARTZ_PEDESTAL = registerBlock("quartz_pedestal", new PedestalVanilla(Blocks.QUARTZ_BLOCK)); - public static final Block PURPUR_PEDESTAL = registerBlock("purpur_pedestal", new PedestalVanilla(Blocks.PURPUR_BLOCK)); - - public static final Block HYDROTHERMAL_VENT = registerBlock("hydrothermal_vent", new HydrothermalVentBlock()); - public static final Block VENT_BUBBLE_COLUMN = registerEndBlockOnly("vent_bubble_column", new VentBubbleColumnBlock()); - - public static final Block DENSE_SNOW = registerBlock("dense_snow", new DenseSnowBlock()); - public static final Block EMERALD_ICE = registerBlock("emerald_ice", new EmeraldIceBlock()); - public static final Block DENSE_EMERALD_ICE = registerBlock("dense_emerald_ice", new DenseEmeraldIceBlock()); - public static final Block ANCIENT_EMERALD_ICE = registerBlock("ancient_emerald_ice", new AncientEmeraldIceBlock()); - - public static final Block END_STONE_STALACTITE = registerBlock("end_stone_stalactite", new StalactiteBlock(Blocks.END_STONE)); - public static final Block END_STONE_STALACTITE_CAVEMOSS = registerBlock("end_stone_stalactite_cavemoss", new StalactiteBlock(CAVE_MOSS)); - - // Wooden Materials And Trees // - public static final Block MOSSY_GLOWSHROOM_SAPLING = registerBlock("mossy_glowshroom_sapling", new MossyGlowshroomSaplingBlock()); - public static final Block MOSSY_GLOWSHROOM_CAP = registerBlock("mossy_glowshroom_cap", new MossyGlowshroomCapBlock()); - public static final Block MOSSY_GLOWSHROOM_HYMENOPHORE = registerBlock("mossy_glowshroom_hymenophore", new GlowingHymenophoreBlock()); - public static final Block MOSSY_GLOWSHROOM_FUR = registerBlock("mossy_glowshroom_fur", new FurBlock(MOSSY_GLOWSHROOM_SAPLING, 15, 16, true)); - public static final WoodenMaterial MOSSY_GLOWSHROOM = new WoodenMaterial("mossy_glowshroom", MaterialColor.COLOR_GRAY, MaterialColor.WOOD); - - public static final Block PYTHADENDRON_SAPLING = registerBlock("pythadendron_sapling", new PythadendronSaplingBlock()); - public static final Block PYTHADENDRON_LEAVES = registerBlock("pythadendron_leaves", new BaseLeavesBlock(PYTHADENDRON_SAPLING, MaterialColor.COLOR_MAGENTA)); - public static final WoodenMaterial PYTHADENDRON = new WoodenMaterial("pythadendron", MaterialColor.COLOR_MAGENTA, MaterialColor.COLOR_PURPLE); - - public static final Block END_LOTUS_SEED = registerBlock("end_lotus_seed", new EndLotusSeedBlock()); - public static final Block END_LOTUS_STEM = registerBlock("end_lotus_stem", new EndLotusStemBlock()); - public static final Block END_LOTUS_LEAF = registerEndBlockOnly("end_lotus_leaf", new EndLotusLeafBlock()); - public static final Block END_LOTUS_FLOWER = registerEndBlockOnly("end_lotus_flower", new EndLotusFlowerBlock()); - public static final WoodenMaterial END_LOTUS = new WoodenMaterial("end_lotus", MaterialColor.COLOR_LIGHT_BLUE, MaterialColor.COLOR_CYAN); - - public static final Block LACUGROVE_SAPLING = registerBlock("lacugrove_sapling", new LacugroveSaplingBlock()); - public static final Block LACUGROVE_LEAVES = registerBlock("lacugrove_leaves", new BaseLeavesBlock(LACUGROVE_SAPLING, MaterialColor.COLOR_CYAN)); - public static final WoodenMaterial LACUGROVE = new WoodenMaterial("lacugrove", MaterialColor.COLOR_BROWN, MaterialColor.COLOR_YELLOW); - - public static final Block DRAGON_TREE_SAPLING = registerBlock("dragon_tree_sapling", new DragonTreeSaplingBlock()); - public static final Block DRAGON_TREE_LEAVES = registerBlock("dragon_tree_leaves", new BaseLeavesBlock(DRAGON_TREE_SAPLING, MaterialColor.COLOR_MAGENTA)); - public static final WoodenMaterial DRAGON_TREE = new WoodenMaterial("dragon_tree", MaterialColor.COLOR_BLACK, MaterialColor.COLOR_MAGENTA); - - public static final Block TENANEA_SAPLING = registerBlock("tenanea_sapling", new TenaneaSaplingBlock()); - public static final Block TENANEA_LEAVES = registerBlock("tenanea_leaves", new BaseLeavesBlock(TENANEA_SAPLING, MaterialColor.COLOR_PINK)); - public static final Block TENANEA_FLOWERS = registerBlock("tenanea_flowers", new TenaneaFlowersBlock()); - public static final Block TENANEA_OUTER_LEAVES = registerBlock("tenanea_outer_leaves", new FurBlock(TENANEA_SAPLING, 32)); - public static final WoodenMaterial TENANEA = new WoodenMaterial("tenanea", MaterialColor.COLOR_BROWN, MaterialColor.COLOR_PINK); - - public static final Block HELIX_TREE_SAPLING = registerBlock("helix_tree_sapling", new HelixTreeSaplingBlock()); - public static final Block HELIX_TREE_LEAVES = registerBlock("helix_tree_leaves", new HelixTreeLeavesBlock()); - public static final WoodenMaterial HELIX_TREE = new WoodenMaterial("helix_tree", MaterialColor.COLOR_GRAY, MaterialColor.COLOR_ORANGE); - - public static final Block UMBRELLA_TREE_SAPLING = registerBlock("umbrella_tree_sapling", new UmbrellaTreeSaplingBlock()); - public static final Block UMBRELLA_TREE_MEMBRANE = registerBlock("umbrella_tree_membrane", new UmbrellaTreeMembraneBlock()); - public static final Block UMBRELLA_TREE_CLUSTER = registerBlock("umbrella_tree_cluster", new UmbrellaTreeClusterBlock()); - public static final Block UMBRELLA_TREE_CLUSTER_EMPTY = registerBlock("umbrella_tree_cluster_empty", new UmbrellaTreeClusterEmptyBlock()); - public static final WoodenMaterial UMBRELLA_TREE = new WoodenMaterial("umbrella_tree", MaterialColor.COLOR_BLUE, MaterialColor.COLOR_GREEN); - - public static final Block JELLYSHROOM_CAP_PURPLE = registerBlock("jellyshroom_cap_purple", new JellyshroomCapBlock(217, 142, 255, 164, 0, 255)); - public static final WoodenMaterial JELLYSHROOM = new WoodenMaterial("jellyshroom", MaterialColor.COLOR_PURPLE, MaterialColor.COLOR_LIGHT_BLUE); - - public static final Block LUCERNIA_SAPLING = registerBlock("lucernia_sapling", new LucerniaSaplingBlock()); - public static final Block LUCERNIA_LEAVES = registerBlock("lucernia_leaves", new BaseLeavesBlock(LUCERNIA_SAPLING, MaterialColor.COLOR_ORANGE)); - public static final Block LUCERNIA_OUTER_LEAVES = registerBlock("lucernia_outer_leaves", new FurBlock(LUCERNIA_SAPLING, 32)); - public static final WoodenMaterial LUCERNIA = new WoodenMaterial("lucernia", MaterialColor.COLOR_ORANGE, MaterialColor.COLOR_ORANGE); - - // Small Plants // - public static final Block UMBRELLA_MOSS = registerBlock("umbrella_moss", new UmbrellaMossBlock()); - public static final Block UMBRELLA_MOSS_TALL = registerBlock("umbrella_moss_tall", new UmbrellaMossTallBlock()); - public static final Block CREEPING_MOSS = registerBlock("creeping_moss", new GlowingMossBlock(11)); - public static final Block CHORUS_GRASS = registerBlock("chorus_grass", new ChorusGrassBlock()); - public static final Block CAVE_GRASS = registerBlock("cave_grass", new TerrainPlantBlock(CAVE_MOSS)); - public static final Block CRYSTAL_GRASS = registerBlock("crystal_grass", new TerrainPlantBlock(CRYSTAL_MOSS)); - public static final Block SHADOW_PLANT = registerBlock("shadow_plant", new TerrainPlantBlock(SHADOW_GRASS)); - public static final Block BUSHY_GRASS = registerBlock("bushy_grass", new TerrainPlantBlock(PINK_MOSS)); - public static final Block AMBER_GRASS = registerBlock("amber_grass", new TerrainPlantBlock(AMBER_MOSS)); - public static final Block TWISTED_UMBRELLA_MOSS = registerBlock("twisted_umbrella_moss", new TwistedUmbrellaMossBlock()); - public static final Block TWISTED_UMBRELLA_MOSS_TALL = registerBlock("twisted_umbrella_moss_tall", new TwistedUmbrellaMossTallBlock()); - public static final Block JUNGLE_GRASS = registerBlock("jungle_grass", new TerrainPlantBlock(JUNGLE_MOSS)); - public static final Block BLOOMING_COOKSONIA = registerBlock("blooming_cooksonia", new TerrainPlantBlock(END_MOSS)); - public static final Block SALTEAGO = registerBlock("salteago", new TerrainPlantBlock(END_MOSS)); - public static final Block VAIOLUSH_FERN = registerBlock("vaiolush_fern", new TerrainPlantBlock(END_MOSS)); - public static final Block FRACTURN = registerBlock("fracturn", new TerrainPlantBlock(END_MOSS)); - public static final Block CLAWFERN = registerBlock("clawfern", new TerrainPlantBlock(SANGNUM, MOSSY_OBSIDIAN, MOSSY_DRAGON_BONE)); - public static final Block GLOBULAGUS = registerBlock("globulagus", new TerrainPlantBlock(SANGNUM, MOSSY_OBSIDIAN, MOSSY_DRAGON_BONE)); - public static final Block ORANGO = registerBlock("orango", new TerrainPlantBlock(RUTISCUS)); - public static final Block AERIDIUM = registerBlock("aeridium", new TerrainPlantBlock(RUTISCUS)); - public static final Block LUTEBUS = registerBlock("lutebus", new TerrainPlantBlock(RUTISCUS)); - public static final Block LAMELLARIUM = registerBlock("lamellarium", new TerrainPlantBlock(RUTISCUS)); - - public static final Block BLUE_VINE_SEED = registerBlock("blue_vine_seed", new BlueVineSeedBlock()); - public static final Block BLUE_VINE = registerEndBlockOnly("blue_vine", new BlueVineBlock()); - public static final Block BLUE_VINE_LANTERN = registerBlock("blue_vine_lantern", new BlueVineLanternBlock()); - public static final Block BLUE_VINE_FUR = registerBlock("blue_vine_fur", new FurBlock(BLUE_VINE_SEED, 15, 3, false)); - - public static final Block LANCELEAF_SEED = registerBlock("lanceleaf_seed", new LanceleafSeedBlock()); - public static final Block LANCELEAF = registerEndBlockOnly("lanceleaf", new LanceleafBlock()); - - public static final Block GLOWING_PILLAR_SEED = registerBlock("glowing_pillar_seed", new GlowingPillarSeedBlock()); - public static final Block GLOWING_PILLAR_ROOTS = registerEndBlockOnly("glowing_pillar_roots", new GlowingPillarRootsBlock()); - public static final Block GLOWING_PILLAR_LUMINOPHOR = registerBlock("glowing_pillar_luminophor", new GlowingPillarLuminophorBlock()); - public static final Block GLOWING_PILLAR_LEAVES = registerBlock("glowing_pillar_leaves", new FurBlock(GLOWING_PILLAR_SEED, 15, 3, false)); - - public static final Block SMALL_JELLYSHROOM = registerBlock("small_jellyshroom", new SmallJellyshroomBlock()); - public static final Block BOLUX_MUSHROOM = registerBlock("bolux_mushroom", new BoluxMushroomBlock()); - - public static final Block LUMECORN_SEED = registerBlock("lumecorn_seed", new LumecornSeedBlock()); - public static final Block LUMECORN = registerEndBlockOnly("lumecorn", new LumecornBlock()); - - public static final Block SMALL_AMARANITA_MUSHROOM = registerBlock("small_amaranita_mushroom", new SmallAmaranitaBlock()); - public static final Block LARGE_AMARANITA_MUSHROOM = registerEndBlockOnly("large_amaranita_mushroom", new LargeAmaranitaBlock()); - public static final Block AMARANITA_STEM = registerBlock("amaranita_stem", new AmaranitaStemBlock()); - public static final Block AMARANITA_HYPHAE = registerBlock("amaranita_hyphae", new AmaranitaStemBlock()); - public static final Block AMARANITA_HYMENOPHORE = registerBlock("amaranita_hymenophore", new AmaranitaHymenophoreBlock()); - public static final Block AMARANITA_LANTERN = registerBlock("amaranita_lantern", new GlowingHymenophoreBlock()); - public static final Block AMARANITA_FUR = registerBlock("amaranita_fur", new FurBlock(SMALL_AMARANITA_MUSHROOM, 15, 4, true)); - public static final Block AMARANITA_CAP = registerBlock("amaranita_cap", new AmaranitaCapBlock()); - - public static final Block NEON_CACTUS = registerBlock("neon_cactus", new NeonCactusPlantBlock()); - public static final Block NEON_CACTUS_BLOCK = registerBlock("neon_cactus_block", new NeonCactusBlock()); - public static final Block NEON_CACTUS_BLOCK_STAIRS = registerBlock("neon_cactus_stairs", new BaseStairsBlock(NEON_CACTUS_BLOCK)); - public static final Block NEON_CACTUS_BLOCK_SLAB = registerBlock("neon_cactus_slab", new BaseSlabBlock(NEON_CACTUS_BLOCK)); - - // Crops - public static final Block SHADOW_BERRY = registerBlock("shadow_berry", new ShadowBerryBlock()); - public static final Block BLOSSOM_BERRY = registerBlock("blossom_berry_seed", new BaseCropBlock(EndItems.BLOSSOM_BERRY, PINK_MOSS)); - public static final Block AMBER_ROOT = registerBlock("amber_root_seed", new BaseCropBlock(EndItems.AMBER_ROOT_RAW, AMBER_MOSS)); - public static final Block CHORUS_MUSHROOM = registerBlock("chorus_mushroom_seed", new BaseCropBlock(EndItems.CHORUS_MUSHROOM_RAW, CHORUS_NYLIUM)); - //public static final Block PEARLBERRY = registerBlock("pearlberry_seed", new EndCropBlock(EndItems.BLOSSOM_BERRY, END_MOSS, END_MYCELIUM)); - public static final Block CAVE_PUMPKIN_SEED = registerBlock("cave_pumpkin_seed", new CavePumpkinVineBlock()); - public static final Block CAVE_PUMPKIN = registerBlock("cave_pumpkin", new CavePumpkinBlock()); - - // Water plants - public static final Block BUBBLE_CORAL = registerBlock("bubble_coral", new BubbleCoralBlock()); - public static final Block MENGER_SPONGE = registerBlock("menger_sponge", new MengerSpongeBlock()); - public static final Block MENGER_SPONGE_WET = registerBlock("menger_sponge_wet", new MengerSpongeWetBlock()); - public static final Block CHARNIA_RED = registerBlock("charnia_red", new CharniaBlock()); - public static final Block CHARNIA_PURPLE = registerBlock("charnia_purple", new CharniaBlock()); - public static final Block CHARNIA_ORANGE = registerBlock("charnia_orange", new CharniaBlock()); - public static final Block CHARNIA_LIGHT_BLUE = registerBlock("charnia_light_blue", new CharniaBlock()); - public static final Block CHARNIA_CYAN = registerBlock("charnia_cyan", new CharniaBlock()); - public static final Block CHARNIA_GREEN = registerBlock("charnia_green", new CharniaBlock()); - - public static final Block END_LILY = registerEndBlockOnly("end_lily", new EndLilyBlock()); - public static final Block END_LILY_SEED = registerBlock("end_lily_seed", new EndLilySeedBlock()); - - public static final Block HYDRALUX_SAPLING = registerBlock("hydralux_sapling", new HydraluxSaplingBlock()); - public static final Block HYDRALUX = registerEndBlockOnly("hydralux", new HydraluxBlock()); - public static final Block HYDRALUX_PETAL_BLOCK = registerBlock("hydralux_petal_block", new HydraluxPetalBlock()); - public static final ColoredMaterial HYDRALUX_PETAL_BLOCK_COLORED = new ColoredMaterial(HydraluxPetalColoredBlock::new, HYDRALUX_PETAL_BLOCK, true); - - public static final Block POND_ANEMONE = registerBlock("pond_anemone", new PondAnemoneBlock()); - - public static final Block FLAMAEA = registerBlock("flamaea", new FlamaeaBlock()); - - public static final Block CAVE_BUSH = registerBlock("cave_bush", new SimpleLeavesBlock(MaterialColor.COLOR_MAGENTA)); - - public static final Block MURKWEED = registerBlock("murkweed", new MurkweedBlock()); - public static final Block NEEDLEGRASS = registerBlock("needlegrass", new NeedlegrassBlock()); - - // Wall Plants // - public static final Block PURPLE_POLYPORE = registerBlock("purple_polypore", new EndWallMushroom(13)); - public static final Block AURANT_POLYPORE = registerBlock("aurant_polypore", new EndWallMushroom(13)); - public static final Block TAIL_MOSS = registerBlock("tail_moss", new EndWallPlantBlock()); - public static final Block CYAN_MOSS = registerBlock("cyan_moss", new EndWallPlantBlock()); - public static final Block TWISTED_MOSS = registerBlock("twisted_moss", new EndWallPlantBlock()); - public static final Block TUBE_WORM = registerBlock("tube_worm", new EndUnderwaterWallPlantBlock()); - public static final Block BULB_MOSS = registerBlock("bulb_moss", new EndWallPlantBlock(12)); - public static final Block JUNGLE_FERN = registerBlock("jungle_fern", new EndWallPlantBlock()); - public static final Block RUSCUS = registerBlock("ruscus", new EndWallPlantBlock()); - - // Vines // - public static final Block DENSE_VINE = registerBlock("dense_vine", new BaseVineBlock(15, true)); - public static final Block TWISTED_VINE = registerBlock("twisted_vine", new BaseVineBlock()); - public static final Block BULB_VINE_SEED = registerBlock("bulb_vine_seed", new BulbVineSeedBlock()); - public static final Block BULB_VINE = registerBlock("bulb_vine", new BulbVineBlock()); - public static final Block JUNGLE_VINE = registerBlock("jungle_vine", new BaseVineBlock()); - public static final Block RUBINEA = registerBlock("rubinea", new BaseVineBlock()); - public static final Block MAGNULA = registerBlock("magnula", new BaseVineBlock()); - public static final Block FILALUX = registerBlock("filalux", new FilaluxBlock()); - public static final Block FILALUX_WINGS = registerBlock("filalux_wings", new FilaluxWingsBlock()); - public static final Block FILALUX_LANTERN = registerBlock("filalux_lantern", new FilaluxLanternBlock()); - - // Mob-Related - public static final Block SILK_MOTH_NEST = registerBlock("silk_moth_nest", new SilkMothNestBlock()); - public static final Block SILK_MOTH_HIVE = registerBlock("silk_moth_hive", new SilkMothHiveBlock()); - - // Ores // - public static final Block ENDER_ORE = registerBlock("ender_ore", new BaseOreBlock(EndItems.ENDER_SHARD, 1, 3, 5)); - public static final Block AMBER_ORE = registerBlock("amber_ore", new BaseOreBlock(EndItems.RAW_AMBER, 1, 2, 4)); - - // Materials // - public static final MetalMaterial THALLASIUM = MetalMaterial.makeNormal("thallasium", MaterialColor.COLOR_BLUE, EndToolMaterial.THALLASIUM, EndArmorMaterial.THALLASIUM); - public static final MetalMaterial TERMINITE = MetalMaterial.makeOreless("terminite", MaterialColor.WARPED_WART_BLOCK, 7F, 9F, EndToolMaterial.TERMINITE, EndArmorMaterial.TERMINITE); - public static final Block AETERNIUM_BLOCK = registerBlock("aeternium_block", new AeterniumBlock()); - public static final Block CHARCOAL_BLOCK = registerBlock("charcoal_block", new CharcoalBlock()); - - public static final Block ENDER_BLOCK = registerBlock("ender_block", new EnderBlock()); - public static final Block AURORA_CRYSTAL = registerBlock("aurora_crystal", new AuroraCrystalBlock()); - public static final Block AMBER_BLOCK = registerBlock("amber_block", new AmberBlock()); - public static final Block SMARAGDANT_CRYSTAL = registerBlock("smaragdant_crystal", new SmaragdantCrystalBlock()); - public static final CrystalSubblocksMaterial SMARAGDANT_SUBBLOCKS = new CrystalSubblocksMaterial("smaragdant_crystal", SMARAGDANT_CRYSTAL); - public static final Block SMARAGDANT_CRYSTAL_SHARD = registerBlock("smaragdant_crystal_shard", new SmaragdantCrystalShardBlock()); - - public static final Block RESPAWN_OBELISK = registerBlock("respawn_obelisk", new RespawnObeliskBlock()); - - // Lanterns - public static final Block ANDESITE_LANTERN = registerBlock("andesite_lantern", new StoneLanternBlock(Blocks.ANDESITE)); - public static final Block DIORITE_LANTERN = registerBlock("diorite_lantern", new StoneLanternBlock(Blocks.DIORITE)); - public static final Block GRANITE_LANTERN = registerBlock("granite_lantern", new StoneLanternBlock(Blocks.GRANITE)); - public static final Block QUARTZ_LANTERN = registerBlock("quartz_lantern", new StoneLanternBlock(Blocks.QUARTZ_BLOCK)); - public static final Block PURPUR_LANTERN = registerBlock("purpur_lantern", new StoneLanternBlock(Blocks.PURPUR_BLOCK)); - public static final Block END_STONE_LANTERN = registerBlock("end_stone_lantern", new StoneLanternBlock(Blocks.END_STONE)); - public static final Block BLACKSTONE_LANTERN = registerBlock("blackstone_lantern", new StoneLanternBlock(Blocks.BLACKSTONE)); - - public static final Block IRON_BULB_LANTERN = registerBlock("iron_bulb_lantern", new BulbVineLanternBlock()); - public static final ColoredMaterial IRON_BULB_LANTERN_COLORED = new ColoredMaterial(BulbVineLanternColoredBlock::new, IRON_BULB_LANTERN, false); - - public static final Block IRON_CHANDELIER = EndBlocks.registerBlock("iron_chandelier", new ChandelierBlock(Blocks.GOLD_BLOCK)); - public static final Block GOLD_CHANDELIER = EndBlocks.registerBlock("gold_chandelier", new ChandelierBlock(Blocks.GOLD_BLOCK)); - - // Blocks With Entity // - public static final Block END_STONE_FURNACE = registerBlock("end_stone_furnace", new BaseFurnaceBlock(Blocks.END_STONE)); - public static final Block END_STONE_SMELTER = registerBlock("end_stone_smelter", new EndStoneSmelter()); - public static final Block ETERNAL_PEDESTAL = registerBlock("eternal_pedestal", new EternalPedestal()); - public static final Block INFUSION_PEDESTAL = registerBlock("infusion_pedestal", new InfusionPedestal()); - public static final Block AETERNIUM_ANVIL = registerBlock("aeternium_anvil", new AeterniumAnvil()); - - // Technical - public static final Block END_PORTAL_BLOCK = registerEndBlockOnly("end_portal_block", new EndPortalBlock()); - - private static BlocksRegistry BLOCKS_REGISTRY; - - private EndBlocks(CreativeModeTab creativeTab) { - super(creativeTab); - } - - public static List getModBlocks() { - return getModBlocks(BetterEnd.MOD_ID).stream().filter(BlockItem.class::isInstance) - .map(item -> ((BlockItem) item).getBlock()).collect(Collectors.toList()); - } - - public static Block registerBlock(ResourceLocation id, Block block) { - if (!Configs.BLOCK_CONFIG.getBooleanRoot(id.getPath(), true)) { - return block; - } - if (block instanceof BaseChestBlock) { - BaseBlockEntities.CHEST.registerBlock(block); - } - if (block instanceof BaseSignBlock) { - BaseBlockEntities.SIGN.registerBlock(block); - } - if (block instanceof BaseBarrelBlock) { - BaseBlockEntities.BARREL.registerBlock(block); - } - if (block instanceof BaseFurnaceBlock) { - BaseBlockEntities.FURNACE.registerBlock(block); - } - getBlockRegistry().register(id, block); - return block; - } - - public static Block registerBlock(String name, Block block) { - return registerBlock(BetterEnd.makeID(name), block); - } - - public static Block registerEndBlockOnly(String name, Block block) { - return getBlockRegistry().registerBlockOnly(name, block); - } - - public static FabricItemSettings makeBlockItemSettings() { - return getBlockRegistry().makeItemSettings(); - } - - @Override - public ResourceLocation createModId(String name) { - return BetterEnd.makeID(name); - } - - @NotNull - private static BlocksRegistry getBlockRegistry() { - if (BLOCKS_REGISTRY == null) { - BLOCKS_REGISTRY = new EndBlocks(CreativeTabs.TAB_BLOCKS); - } - return BLOCKS_REGISTRY; - } -} diff --git a/src/main/java/ru/betterend/registry/EndEntities.java b/src/main/java/ru/betterend/registry/EndEntities.java deleted file mode 100644 index 0dedbfac..00000000 --- a/src/main/java/ru/betterend/registry/EndEntities.java +++ /dev/null @@ -1,61 +0,0 @@ -package ru.betterend.registry; - -import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; -import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityDimensions; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.EntityType.EntityFactory; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.MobCategory; -import net.minecraft.world.entity.ai.attributes.AttributeSupplier.Builder; -import ru.bclib.util.ColorUtil; -import ru.betterend.BetterEnd; -import ru.betterend.config.Configs; -import ru.betterend.entity.CubozoaEntity; -import ru.betterend.entity.DragonflyEntity; -import ru.betterend.entity.EndFishEntity; -import ru.betterend.entity.EndSlimeEntity; -import ru.betterend.entity.ShadowWalkerEntity; -import ru.betterend.entity.SilkMothEntity; -import ru.betterend.util.SpawnHelper; - -public class EndEntities { - public static final EntityType DRAGONFLY = register("dragonfly", MobCategory.AMBIENT, 0.6F, 0.5F, DragonflyEntity::new, DragonflyEntity.createMobAttributes(), true, ColorUtil.color(32, 42, 176), ColorUtil.color(115, 225, 249)); - public static final EntityType END_SLIME = register("end_slime", MobCategory.MONSTER, 2F, 2F, EndSlimeEntity::new, EndSlimeEntity.createMobAttributes(), false, ColorUtil.color(28, 28, 28), ColorUtil.color(99, 11, 99)); - public static final EntityType END_FISH = register("end_fish", MobCategory.WATER_AMBIENT, 0.5F, 0.5F, EndFishEntity::new, EndFishEntity.createMobAttributes(), true, ColorUtil.color(3, 50, 76), ColorUtil.color(120, 206, 255)); - public static final EntityType SHADOW_WALKER = register("shadow_walker", MobCategory.MONSTER, 0.6F, 1.95F, ShadowWalkerEntity::new, ShadowWalkerEntity.createMobAttributes(), true, ColorUtil.color(30, 30, 30), ColorUtil.color(5, 5, 5)); - public static final EntityType CUBOZOA = register("cubozoa", MobCategory.WATER_AMBIENT, 0.6F, 1F, CubozoaEntity::new, CubozoaEntity.createMobAttributes(), true, ColorUtil.color(151, 77, 181), ColorUtil.color(93, 176, 238)); - public static final EntityType SILK_MOTH = register("silk_moth", MobCategory.AMBIENT, 0.6F, 0.6F, SilkMothEntity::new, SilkMothEntity.createMobAttributes(), true, ColorUtil.color(198, 138, 204), ColorUtil.color(242, 220, 236)); - - public static void register() { - SpawnHelper.restrictionAir(DRAGONFLY, DragonflyEntity::canSpawn); - SpawnHelper.restrictionLand(END_SLIME, EndSlimeEntity::canSpawn); - SpawnHelper.restrictionWater(END_FISH, EndFishEntity::canSpawn); - SpawnHelper.restrictionLand(SHADOW_WALKER, ShadowWalkerEntity::canSpawn); - SpawnHelper.restrictionWater(CUBOZOA, CubozoaEntity::canSpawn); - SpawnHelper.restrictionAir(SILK_MOTH, SilkMothEntity::canSpawn); - } - - protected static EntityType register(String name, MobCategory group, float width, float height, EntityFactory entity) { - ResourceLocation id = BetterEnd.makeID(name); - EntityType type = FabricEntityTypeBuilder.create(group, entity).dimensions(EntityDimensions.fixed(width, height)).build(); - if (Configs.ENTITY_CONFIG.getBooleanRoot(id.getPath(), true)) { - return Registry.register(Registry.ENTITY_TYPE, id, type); - } - return type; - } - - private static EntityType register(String name, MobCategory group, float width, float height, EntityFactory entity, Builder attributes, boolean fixedSize, int eggColor, int dotsColor) { - ResourceLocation id = BetterEnd.makeID(name); - EntityType type = FabricEntityTypeBuilder.create(group, entity).dimensions(fixedSize ? EntityDimensions.fixed(width, height) : EntityDimensions.scalable(width, height)).build(); - if (Configs.ENTITY_CONFIG.getBooleanRoot(id.getPath(), true)) { - FabricDefaultAttributeRegistry.register(type, attributes); - EndItems.registerEndEgg("spawn_egg_" + name, type, eggColor, dotsColor); - return Registry.register(Registry.ENTITY_TYPE, BetterEnd.makeID(name), type); - } - return type; - } -} diff --git a/src/main/java/ru/betterend/registry/EndEntitiesRenders.java b/src/main/java/ru/betterend/registry/EndEntitiesRenders.java deleted file mode 100644 index 30384554..00000000 --- a/src/main/java/ru/betterend/registry/EndEntitiesRenders.java +++ /dev/null @@ -1,32 +0,0 @@ -package ru.betterend.registry; - -import java.util.function.Function; - -import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry; -import net.minecraft.client.renderer.entity.EntityRenderDispatcher; -import net.minecraft.client.renderer.entity.MobRenderer; -import net.minecraft.world.entity.EntityType; -import ru.betterend.entity.render.RendererEntityCubozoa; -import ru.betterend.entity.render.RendererEntityDragonfly; -import ru.betterend.entity.render.RendererEntityEndFish; -import ru.betterend.entity.render.RendererEntityEndSlime; -import ru.betterend.entity.render.RendererEntityShadowWalker; -import ru.betterend.entity.render.SilkMothEntityRenderer; - -public class EndEntitiesRenders { - - public static void register() { - register(EndEntities.DRAGONFLY, RendererEntityDragonfly::new); - register(EndEntities.END_SLIME, RendererEntityEndSlime::new); - register(EndEntities.END_FISH, RendererEntityEndFish::new); - register(EndEntities.SHADOW_WALKER, RendererEntityShadowWalker::new); - register(EndEntities.CUBOZOA, RendererEntityCubozoa::new); - register(EndEntities.SILK_MOTH, SilkMothEntityRenderer::new); - } - - private static void register(EntityType type, Function> render) { - EntityRendererRegistry.INSTANCE.register(type, (entityRenderDispatcher, context) -> { - return render.apply(entityRenderDispatcher); - }); - } -} diff --git a/src/main/java/ru/betterend/registry/EndFeatures.java b/src/main/java/ru/betterend/registry/EndFeatures.java deleted file mode 100644 index 0983d21f..00000000 --- a/src/main/java/ru/betterend/registry/EndFeatures.java +++ /dev/null @@ -1,342 +0,0 @@ -package ru.betterend.registry; - -import java.util.List; -import java.util.function.Supplier; - -import com.google.common.collect.Lists; - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.levelgen.GenerationStep; -import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; -import net.minecraft.world.level.levelgen.feature.Feature; -import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; -import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.levelgen.placement.FeatureDecorator; -import ru.bclib.api.BiomeAPI; -import ru.bclib.world.biomes.BCLBiome; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.bclib.world.features.BCLFeature; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.complex.StoneMaterial; -import ru.betterend.world.features.BiomeIslandFeature; -import ru.betterend.world.features.BlueVineFeature; -import ru.betterend.world.features.CavePumpkinFeature; -import ru.betterend.world.features.CharniaFeature; -import ru.betterend.world.features.CrashedShipFeature; -import ru.betterend.world.features.DoublePlantFeature; -import ru.betterend.world.features.EndLilyFeature; -import ru.betterend.world.features.EndLotusFeature; -import ru.betterend.world.features.EndLotusLeafFeature; -import ru.betterend.world.features.FilaluxFeature; -import ru.betterend.world.features.GlowPillarFeature; -import ru.betterend.world.features.HydraluxFeature; -import ru.betterend.world.features.LanceleafFeature; -import ru.betterend.world.features.MengerSpongeFeature; -import ru.betterend.world.features.NeonCactusFeature; -import ru.betterend.world.features.SilkMothNestFeature; -import ru.betterend.world.features.SingleInvertedScatterFeature; -import ru.betterend.world.features.SinglePlantFeature; -import ru.betterend.world.features.UnderwaterPlantFeature; -import ru.betterend.world.features.VineFeature; -import ru.betterend.world.features.WallPlantFeature; -import ru.betterend.world.features.WallPlantOnLogFeature; -import ru.betterend.world.features.bushes.BushFeature; -import ru.betterend.world.features.bushes.BushWithOuterFeature; -import ru.betterend.world.features.bushes.LargeAmaranitaFeature; -import ru.betterend.world.features.bushes.Lumecorn; -import ru.betterend.world.features.bushes.TenaneaBushFeature; -import ru.betterend.world.features.terrain.BigAuroraCrystalFeature; -import ru.betterend.world.features.terrain.DesertLakeFeature; -import ru.betterend.world.features.terrain.EndLakeFeature; -import ru.betterend.world.features.terrain.FallenPillarFeature; -import ru.betterend.world.features.terrain.FloatingSpireFeature; -import ru.betterend.world.features.terrain.GeyserFeature; -import ru.betterend.world.features.terrain.IceStarFeature; -import ru.betterend.world.features.terrain.ObsidianBoulderFeature; -import ru.betterend.world.features.terrain.ObsidianPillarBasementFeature; -import ru.betterend.world.features.terrain.OreLayerFeature; -import ru.betterend.world.features.terrain.SingleBlockFeature; -import ru.betterend.world.features.terrain.SmaragdantCrystalFeature; -import ru.betterend.world.features.terrain.SpireFeature; -import ru.betterend.world.features.terrain.StalactiteFeature; -import ru.betterend.world.features.terrain.SulphurHillFeature; -import ru.betterend.world.features.terrain.SulphuricCaveFeature; -import ru.betterend.world.features.terrain.SulphuricLakeFeature; -import ru.betterend.world.features.terrain.SurfaceVentFeature; -import ru.betterend.world.features.terrain.caves.RoundCaveFeature; -import ru.betterend.world.features.terrain.caves.TunelCaveFeature; -import ru.betterend.world.features.trees.DragonTreeFeature; -import ru.betterend.world.features.trees.GiganticAmaranitaFeature; -import ru.betterend.world.features.trees.HelixTreeFeature; -import ru.betterend.world.features.trees.JellyshroomFeature; -import ru.betterend.world.features.trees.LacugroveFeature; -import ru.betterend.world.features.trees.LucerniaFeature; -import ru.betterend.world.features.trees.MossyGlowshroomFeature; -import ru.betterend.world.features.trees.PythadendronTreeFeature; -import ru.betterend.world.features.trees.TenaneaFeature; -import ru.betterend.world.features.trees.UmbrellaTreeFeature; -import ru.betterend.world.generator.GeneratorOptions; - -public class EndFeatures { - // Trees // - public static final BCLFeature MOSSY_GLOWSHROOM = redisterVegetation("mossy_glowshroom", new MossyGlowshroomFeature(), 3); - public static final BCLFeature PYTHADENDRON_TREE = redisterVegetation("pythadendron_tree", new PythadendronTreeFeature(), 2); - public static final BCLFeature LACUGROVE = redisterVegetation("lacugrove", new LacugroveFeature(), 4); - public static final BCLFeature DRAGON_TREE = redisterVegetation("dragon_tree", new DragonTreeFeature(), 3); - public static final BCLFeature TENANEA = redisterVegetation("tenanea", new TenaneaFeature(), 3); - public static final BCLFeature HELIX_TREE = redisterVegetation("helix_tree", new HelixTreeFeature(), 2); - public static final BCLFeature UMBRELLA_TREE = redisterVegetation("umbrella_tree", new UmbrellaTreeFeature(), 4); - public static final BCLFeature JELLYSHROOM = redisterVegetation("jellyshroom", new JellyshroomFeature(), 3); - public static final BCLFeature GIGANTIC_AMARANITA = redisterVegetation("gigantic_amaranita", new GiganticAmaranitaFeature(), 1); - public static final BCLFeature LUCERNIA = redisterVegetation("lucernia", new LucerniaFeature(), 3); - - // Bushes // - public static final BCLFeature PYTHADENDRON_BUSH = redisterVegetation("pythadendron_bush", new BushFeature(EndBlocks.PYTHADENDRON_LEAVES, EndBlocks.PYTHADENDRON.bark), 4); - public static final BCLFeature DRAGON_TREE_BUSH = redisterVegetation("dragon_tree_bush", new BushFeature(EndBlocks.DRAGON_TREE_LEAVES, EndBlocks.DRAGON_TREE.bark), 15); - public static final BCLFeature TENANEA_BUSH = redisterVegetation("tenanea_bush", new TenaneaBushFeature(), 10); - public static final BCLFeature LUMECORN = redisterVegetation("lumecorn", new Lumecorn(), 5); - public static final BCLFeature LARGE_AMARANITA = redisterVegetation("large_amaranita", new LargeAmaranitaFeature(), 5); - public static final BCLFeature LUCERNIA_BUSH = redisterVegetation("lucernia_bush", new BushWithOuterFeature(EndBlocks.LUCERNIA_LEAVES, EndBlocks.LUCERNIA_OUTER_LEAVES, EndBlocks.LUCERNIA.bark), 10); - public static final BCLFeature LUCERNIA_BUSH_RARE = redisterVegetation("lucernia_bush_rare", new BushWithOuterFeature(EndBlocks.LUCERNIA_LEAVES, EndBlocks.LUCERNIA_OUTER_LEAVES, EndBlocks.LUCERNIA.bark), 1); - public static final BCLFeature NEON_CACTUS = redisterVegetation("neon_cactus", new NeonCactusFeature(), 2); - - // Plants // - public static final BCLFeature UMBRELLA_MOSS = redisterVegetation("umbrella_moss", new DoublePlantFeature(EndBlocks.UMBRELLA_MOSS, EndBlocks.UMBRELLA_MOSS_TALL, 5), 5); - public static final BCLFeature CREEPING_MOSS = redisterVegetation("creeping_moss", new SinglePlantFeature(EndBlocks.CREEPING_MOSS, 5), 5); - public static final BCLFeature BLUE_VINE = redisterVegetation("blue_vine", new BlueVineFeature(), 1); - public static final BCLFeature CHORUS_GRASS = redisterVegetation("chorus_grass", new SinglePlantFeature(EndBlocks.CHORUS_GRASS, 4), 5); - public static final BCLFeature CRYSTAL_GRASS = redisterVegetation("crystal_grass", new SinglePlantFeature(EndBlocks.CRYSTAL_GRASS, 8, false), 5); - public static final BCLFeature SHADOW_PLANT = redisterVegetation("shadow_plant", new SinglePlantFeature(EndBlocks.SHADOW_PLANT, 6), 9); - public static final BCLFeature MURKWEED = redisterVegetation("murkweed", new SinglePlantFeature(EndBlocks.MURKWEED, 3), 2); - public static final BCLFeature NEEDLEGRASS = redisterVegetation("needlegrass", new SinglePlantFeature(EndBlocks.NEEDLEGRASS, 3), 2); - public static final BCLFeature SHADOW_BERRY = redisterVegetation("shadow_berry", new SinglePlantFeature(EndBlocks.SHADOW_BERRY, 2), 1); - public static final BCLFeature BUSHY_GRASS = redisterVegetation("bushy_grass", new SinglePlantFeature(EndBlocks.BUSHY_GRASS, 8, false), 20); - public static final BCLFeature BUSHY_GRASS_WG = redisterVegetation("bushy_grass_wg", new SinglePlantFeature(EndBlocks.BUSHY_GRASS, 5), 10); - public static final BCLFeature AMBER_GRASS = redisterVegetation("amber_grass", new SinglePlantFeature(EndBlocks.AMBER_GRASS, 6), 9); - public static final BCLFeature LANCELEAF = redisterVegetation("lanceleaf", new LanceleafFeature(), 3); - public static final BCLFeature GLOW_PILLAR = redisterVegetation("glow_pillar", new GlowPillarFeature(), 1); - public static final BCLFeature TWISTED_UMBRELLA_MOSS = redisterVegetation("twisted_umbrella_moss", new DoublePlantFeature(EndBlocks.TWISTED_UMBRELLA_MOSS, EndBlocks.TWISTED_UMBRELLA_MOSS_TALL, 6), 5); - public static final BCLFeature JUNGLE_GRASS = redisterVegetation("jungle_grass", new SinglePlantFeature(EndBlocks.JUNGLE_GRASS, 7, 3), 8); - public static final BCLFeature SMALL_JELLYSHROOM_FLOOR = redisterVegetation("small_jellyshroom_floor", new SinglePlantFeature(EndBlocks.SMALL_JELLYSHROOM, 5, 5), 4); - public static final BCLFeature BLOSSOM_BERRY = redisterVegetation("blossom_berry", new SinglePlantFeature(EndBlocks.BLOSSOM_BERRY, 3, 3), 2); - public static final BCLFeature BLOOMING_COOKSONIA = redisterVegetation("blooming_cooksonia", new SinglePlantFeature(EndBlocks.BLOOMING_COOKSONIA, 5), 5); - public static final BCLFeature SALTEAGO = redisterVegetation("salteago", new SinglePlantFeature(EndBlocks.SALTEAGO, 5), 5); - public static final BCLFeature VAIOLUSH_FERN = redisterVegetation("vaiolush_fern", new SinglePlantFeature(EndBlocks.VAIOLUSH_FERN, 5), 5); - public static final BCLFeature FRACTURN = redisterVegetation("fracturn", new SinglePlantFeature(EndBlocks.FRACTURN, 5), 5); - public static final BCLFeature UMBRELLA_MOSS_RARE = redisterVegetation("umbrella_moss_rare", new SinglePlantFeature(EndBlocks.UMBRELLA_MOSS, 3), 2); - public static final BCLFeature CREEPING_MOSS_RARE = redisterVegetation("creeping_moss_rare", new SinglePlantFeature(EndBlocks.CREEPING_MOSS, 3), 2); - public static final BCLFeature TWISTED_UMBRELLA_MOSS_RARE = redisterVegetation("twisted_umbrella_moss_rare", new SinglePlantFeature(EndBlocks.TWISTED_UMBRELLA_MOSS, 3), 2); - public static final BCLFeature ORANGO = redisterVegetation("orango", new SinglePlantFeature(EndBlocks.ORANGO, 5), 6); - public static final BCLFeature AERIDIUM = redisterVegetation("aeridium", new SinglePlantFeature(EndBlocks.AERIDIUM, 5, 4), 5); - public static final BCLFeature LUTEBUS = redisterVegetation("lutebus", new SinglePlantFeature(EndBlocks.LUTEBUS, 5, 2), 5); - public static final BCLFeature LAMELLARIUM = redisterVegetation("lamellarium", new SinglePlantFeature(EndBlocks.LAMELLARIUM, 5), 6); - public static final BCLFeature SMALL_AMARANITA = redisterVegetation("small_amaranita", new SinglePlantFeature(EndBlocks.SMALL_AMARANITA_MUSHROOM, 5, 5), 4); - public static final BCLFeature GLOBULAGUS = redisterVegetation("globulagus", new SinglePlantFeature(EndBlocks.GLOBULAGUS, 5, 3), 6); - public static final BCLFeature CLAWFERN = redisterVegetation("clawfern", new SinglePlantFeature(EndBlocks.CLAWFERN, 5, 4), 5); - public static final BCLFeature BOLUX_MUSHROOM = redisterVegetation("bolux_mushroom", new SinglePlantFeature(EndBlocks.BOLUX_MUSHROOM, 5, 5), 2); - public static final BCLFeature CHORUS_MUSHROOM = redisterVegetation("chorus_mushroom", new SinglePlantFeature(EndBlocks.CHORUS_MUSHROOM, 5, 5), 1); - public static final BCLFeature AMBER_ROOT = redisterVegetation("amber_root", new SinglePlantFeature(EndBlocks.AMBER_ROOT, 5, 5), 1); - //public static final BCLFeature PEARLBERRY = redisterVegetation("pearlberry", new SinglePlantFeature(EndBlocks.PEARLBERRY, 5, 5), 1); - - // Vines // - public static final BCLFeature DENSE_VINE = redisterVegetation("dense_vine", new VineFeature(EndBlocks.DENSE_VINE, 24), 3); - public static final BCLFeature TWISTED_VINE = redisterVegetation("twisted_vine", new VineFeature(EndBlocks.TWISTED_VINE, 24), 3); - public static final BCLFeature BULB_VINE = redisterVegetation("bulb_vine", new VineFeature(EndBlocks.BULB_VINE, 24), 5); - public static final BCLFeature JUNGLE_VINE = redisterVegetation("jungle_vine", new VineFeature(EndBlocks.JUNGLE_VINE, 24), 5); - - // Ceil plants - public static final BCLFeature SMALL_JELLYSHROOM_CEIL = redisterVegetation("small_jellyshroom_ceil", new SingleInvertedScatterFeature(EndBlocks.SMALL_JELLYSHROOM, 8), 8); - - // Wall Plants // - public static final BCLFeature PURPLE_POLYPORE = redisterVegetation("purple_polypore", new WallPlantOnLogFeature(EndBlocks.PURPLE_POLYPORE, 3), 5); - public static final BCLFeature AURANT_POLYPORE = redisterVegetation("aurant_polypore", new WallPlantOnLogFeature(EndBlocks.AURANT_POLYPORE, 3), 5); - public static final BCLFeature TAIL_MOSS = redisterVegetation("tail_moss", new WallPlantFeature(EndBlocks.TAIL_MOSS, 3), 15); - public static final BCLFeature CYAN_MOSS = redisterVegetation("cyan_moss", new WallPlantFeature(EndBlocks.CYAN_MOSS, 3), 15); - public static final BCLFeature TAIL_MOSS_WOOD = redisterVegetation("tail_moss_wood", new WallPlantOnLogFeature(EndBlocks.TAIL_MOSS, 4), 25); - public static final BCLFeature CYAN_MOSS_WOOD = redisterVegetation("cyan_moss_wood", new WallPlantOnLogFeature(EndBlocks.CYAN_MOSS, 4), 25); - public static final BCLFeature TWISTED_MOSS = redisterVegetation("twisted_moss", new WallPlantFeature(EndBlocks.TWISTED_MOSS, 6), 15); - public static final BCLFeature TWISTED_MOSS_WOOD = redisterVegetation("twisted_moss_wood", new WallPlantOnLogFeature(EndBlocks.TWISTED_MOSS, 6), 25); - public static final BCLFeature BULB_MOSS = redisterVegetation("bulb_moss", new WallPlantFeature(EndBlocks.BULB_MOSS, 6), 1); - public static final BCLFeature BULB_MOSS_WOOD = redisterVegetation("bulb_moss_wood", new WallPlantOnLogFeature(EndBlocks.BULB_MOSS, 6), 15); - public static final BCLFeature SMALL_JELLYSHROOM_WALL = redisterVegetation("small_jellyshroom_wall", new WallPlantFeature(EndBlocks.SMALL_JELLYSHROOM, 4), 4); - public static final BCLFeature SMALL_JELLYSHROOM_WOOD = redisterVegetation("small_jellyshroom_wood", new WallPlantOnLogFeature(EndBlocks.SMALL_JELLYSHROOM, 4), 8); - public static final BCLFeature JUNGLE_FERN_WOOD = redisterVegetation("jungle_fern_wood", new WallPlantOnLogFeature(EndBlocks.JUNGLE_FERN, 3), 12); - public static final BCLFeature RUSCUS = redisterVegetation("ruscus", new WallPlantFeature(EndBlocks.RUSCUS, 6), 10); - public static final BCLFeature RUSCUS_WOOD = redisterVegetation("ruscus_wood", new WallPlantOnLogFeature(EndBlocks.RUSCUS, 6), 10); - - // Sky plants - public static final BCLFeature FILALUX = redisterVegetation("filalux", new FilaluxFeature(), 1); - - // Water // - public static final BCLFeature BUBBLE_CORAL = redisterVegetation("bubble_coral", new UnderwaterPlantFeature(EndBlocks.BUBBLE_CORAL, 6), 10); - public static final BCLFeature BUBBLE_CORAL_RARE = redisterVegetation("bubble_coral_rare", new UnderwaterPlantFeature(EndBlocks.BUBBLE_CORAL, 3), 4); - public static final BCLFeature END_LILY = redisterVegetation("end_lily", new EndLilyFeature(6), 10); - public static final BCLFeature END_LILY_RARE = redisterVegetation("end_lily_rare", new EndLilyFeature(3), 4); - public static final BCLFeature END_LOTUS = redisterVegetation("end_lotus", new EndLotusFeature(7), 5); - public static final BCLFeature END_LOTUS_LEAF = redisterVegetation("end_lotus_leaf", new EndLotusLeafFeature(20), 25); - public static final BCLFeature HYDRALUX = redisterVegetation("hydralux", new HydraluxFeature(5), 5); - public static final BCLFeature POND_ANEMONE = redisterVegetation("pond_anemone", new UnderwaterPlantFeature(EndBlocks.POND_ANEMONE, 6), 10); - - public static final BCLFeature CHARNIA_RED = redisterVegetation("charnia_red", new CharniaFeature(EndBlocks.CHARNIA_RED), 10); - public static final BCLFeature CHARNIA_PURPLE = redisterVegetation("charnia_purple", new CharniaFeature(EndBlocks.CHARNIA_PURPLE), 10); - public static final BCLFeature CHARNIA_CYAN = redisterVegetation("charnia_cyan", new CharniaFeature(EndBlocks.CHARNIA_CYAN), 10); - public static final BCLFeature CHARNIA_LIGHT_BLUE = redisterVegetation("charnia_light_blue", new CharniaFeature(EndBlocks.CHARNIA_LIGHT_BLUE), 10); - public static final BCLFeature CHARNIA_ORANGE = redisterVegetation("charnia_orange", new CharniaFeature(EndBlocks.CHARNIA_ORANGE), 10); - public static final BCLFeature CHARNIA_GREEN = redisterVegetation("charnia_green", new CharniaFeature(EndBlocks.CHARNIA_GREEN), 10); - public static final BCLFeature MENGER_SPONGE = redisterVegetation("menger_sponge", new MengerSpongeFeature(5), 1); - public static final BCLFeature CHARNIA_RED_RARE = redisterVegetation("charnia_red_rare", new CharniaFeature(EndBlocks.CHARNIA_RED), 2); - public static final BCLFeature BIOME_ISLAND = BCLFeature.makeFeatureConfigured(BetterEnd.makeID("overworld_island"), new BiomeIslandFeature()); - public static final BCLFeature FLAMAEA = redisterVegetation("flamaea", new SinglePlantFeature(EndBlocks.FLAMAEA, 12, false, 5), 20); - - // Terrain // - public static final BCLFeature END_LAKE= registerLake("end_lake", new EndLakeFeature(), 4); - public static final BCLFeature END_LAKE_NORMAL= registerLake("end_lake_normal", new EndLakeFeature(), 20); - public static final BCLFeature END_LAKE_RARE= registerLake("end_lake_rare", new EndLakeFeature(), 40); - public static final BCLFeature DESERT_LAKE= registerLake("desert_lake", new DesertLakeFeature(), 8); - public static final BCLFeature ROUND_CAVE = registerRawGen("round_cave", new RoundCaveFeature(), 2); - public static final BCLFeature SPIRE = registerRawGen("spire", new SpireFeature(), 2); - public static final BCLFeature FLOATING_SPIRE = registerRawGen("floating_spire", new FloatingSpireFeature(), 8); - public static final BCLFeature GEYSER = registerRawGen("geyser", new GeyserFeature(), 8); - public static final BCLFeature SULPHURIC_LAKE= registerLake("sulphuric_lake", new SulphuricLakeFeature(), 8); - public static final BCLFeature SULPHURIC_CAVE = BCLFeature.makeCountRawFeature(BetterEnd.makeID("sulphuric_cave"), new SulphuricCaveFeature(), 2); - public static final BCLFeature ICE_STAR = registerRawGen("ice_star", new IceStarFeature(5, 15, 10, 25), 15); - public static final BCLFeature ICE_STAR_SMALL = registerRawGen("ice_star_small", new IceStarFeature(3, 5, 7, 12), 8); - public static final BCLFeature SURFACE_VENT = registerChanced("surface_vent", new SurfaceVentFeature(), 4); - public static final BCLFeature SULPHUR_HILL = registerChanced("sulphur_hill", new SulphurHillFeature(), 8); - public static final BCLFeature OBSIDIAN_PILLAR_BASEMENT = registerChanced("obsidian_pillar_basement", new ObsidianPillarBasementFeature(), 8); - public static final BCLFeature OBSIDIAN_BOULDER = registerChanced("obsidian_boulder", new ObsidianBoulderFeature(), 10); - public static final BCLFeature FALLEN_PILLAR = registerChanced("fallen_pillar", new FallenPillarFeature(), 20); - public static final BCLFeature TUNEL_CAVE = BCLFeature.makeChunkFeature(BetterEnd.makeID("tunel_cave"), new TunelCaveFeature()); - - // Ores // - public static final BCLFeature THALLASIUM_ORE = registerOre("thallasium_ore", EndBlocks.THALLASIUM.ore, 12, 6, 0, 16, 128); - public static final BCLFeature ENDER_ORE = registerOre("ender_ore", EndBlocks.ENDER_ORE, 8, 3, 0, 16, 128); - public static final BCLFeature AMBER_ORE = registerOre("amber_ore", EndBlocks.AMBER_ORE, 12, 6, 0, 16, 128); - public static final BCLFeature VIOLECITE_LAYER = registerLayer("violecite_layer", EndBlocks.VIOLECITE, 15, 16, 128, 8); - public static final BCLFeature FLAVOLITE_LAYER = registerLayer("flavolite_layer", EndBlocks.FLAVOLITE, 12, 16, 128, 6); - - // Buildings - public static final BCLFeature CRASHED_SHIP = registerChanced("crashed_ship", new CrashedShipFeature(), 500); - - // Mobs - public static final BCLFeature SILK_MOTH_NEST = registerChanced("silk_moth_nest", new SilkMothNestFeature(), 2); - - // Caves - public static final DefaultFeature SMARAGDANT_CRYSTAL = new SmaragdantCrystalFeature(); - public static final DefaultFeature SMARAGDANT_CRYSTAL_SHARD = new SingleBlockFeature(EndBlocks.SMARAGDANT_CRYSTAL_SHARD); - public static final DefaultFeature BIG_AURORA_CRYSTAL = new BigAuroraCrystalFeature(); - public static final DefaultFeature CAVE_BUSH = new BushFeature(EndBlocks.CAVE_BUSH, EndBlocks.CAVE_BUSH); - public static final DefaultFeature CAVE_GRASS = new SingleBlockFeature(EndBlocks.CAVE_GRASS); - public static final DefaultFeature RUBINEA = new VineFeature(EndBlocks.RUBINEA, 8); - public static final DefaultFeature MAGNULA = new VineFeature(EndBlocks.MAGNULA, 8); - public static final DefaultFeature END_STONE_STALACTITE = new StalactiteFeature(true, EndBlocks.END_STONE_STALACTITE, Blocks.END_STONE); - public static final DefaultFeature END_STONE_STALAGMITE = new StalactiteFeature(false, EndBlocks.END_STONE_STALACTITE, Blocks.END_STONE); - public static final DefaultFeature END_STONE_STALACTITE_CAVEMOSS = new StalactiteFeature(true, EndBlocks.END_STONE_STALACTITE_CAVEMOSS, Blocks.END_STONE, EndBlocks.CAVE_MOSS); - public static final DefaultFeature END_STONE_STALAGMITE_CAVEMOSS = new StalactiteFeature(false, EndBlocks.END_STONE_STALACTITE_CAVEMOSS, EndBlocks.CAVE_MOSS); - public static final DefaultFeature CAVE_PUMPKIN = new CavePumpkinFeature(); - - private static BCLFeature redisterVegetation(String name, Feature feature, int density) { - return BCLFeature.makeVegetationFeature(BetterEnd.makeID(name), feature, density); - } - - private static BCLFeature registerRawGen(String name, Feature feature, int chance) { - return BCLFeature.makeRawGenFeature(BetterEnd.makeID(name), feature, chance); - } - - private static BCLFeature registerLake(String name, Feature feature, int chance) { - return BCLFeature.makeLakeFeature(BetterEnd.makeID(name), feature, chance); - } - - private static BCLFeature registerChanced(String name, Feature feature, int chance) { - return BCLFeature.makeChansedFeature(BetterEnd.makeID(name), feature, chance); - } - - private static BCLFeature registerOre(String name, Block blockOre, int veins, int veinSize, int offset, int minY, int maxY) { - return BCLFeature.makeOreFeature(BetterEnd.makeID(name), blockOre, veins, veinSize, offset, minY, maxY); - } - - private static BCLFeature registerLayer(String name, Block block, float radius, int minY, int maxY, int count) { - OreLayerFeature layer = new OreLayerFeature(block.defaultBlockState(), radius, minY, maxY); - ConfiguredFeature configured = layer.configured(FeatureConfiguration.NONE).decorated(FeatureDecorator.COUNT.configured(new CountConfiguration(count))); - return new BCLFeature(BetterEnd.makeID(name), layer, GenerationStep.Decoration.UNDERGROUND_ORES, configured); - } - - private static BCLFeature registerLayer(String name, StoneMaterial material, float radius, int minY, int maxY, int count) { - return registerLayer(name, material.stone, radius, minY, maxY, count); - } - - public static void registerBiomeFeatures(ResourceLocation id, Biome biome, List>>> features) { - if (id.getNamespace().equals(BetterEnd.MOD_ID)) { - return; - } - - if (GeneratorOptions.removeChorusFromVanillaBiomes()) { - if (id.getNamespace().equals("minecraft")) { - String path = id.getPath(); - if (path.equals("end_highlands") || path.equals("end_midlands") || path.equals("small_end_islands")) { - int pos = GenerationStep.Decoration.VEGETAL_DECORATION.ordinal(); - if (pos < features.size()) { - List>> list = features.get(pos); - // If only chorus plants are enabled - if (list.size() == 1) { - features.get(pos).clear(); - } - } - } - } - } - - addFeature(FLAVOLITE_LAYER, features); - addFeature(THALLASIUM_ORE, features); - addFeature(ENDER_ORE, features); - addFeature(CRASHED_SHIP, features); - - BCLBiome bclbiome = BiomeAPI.getBiome(id); - boolean hasCaves = bclbiome.getCustomData("has_caves", true); - if (hasCaves && !EndBiomes.VOID_BIOMES.containsImmutable(id)) { - addFeature(ROUND_CAVE, features); - addFeature(TUNEL_CAVE, features); - } - - BCLFeature feature = BiomeAPI.getBiome(id).getStructuresFeature(); - if (feature != null) { - addFeature(feature, features); - } - } - - public static void addDefaultFeatures(BCLBiomeDef def) { - def.addFeature(FLAVOLITE_LAYER); - def.addFeature(THALLASIUM_ORE); - def.addFeature(ENDER_ORE); - def.addFeature(CRASHED_SHIP); - - boolean hasCaves = def.getCustomData("has_caves", true); - if (hasCaves) { - def.addFeature(ROUND_CAVE); - def.addFeature(TUNEL_CAVE); - } - } - - private static void addFeature(BCLFeature feature, List>>> features) { - int index = feature.getFeatureStep().ordinal(); - if (features.size() > index) { - features.get(index).add(() -> { - return feature.getFeatureConfigured(); - }); - } - else { - List>> newFeature = Lists.newArrayList(); - newFeature.add(() -> { - return feature.getFeatureConfigured(); - }); - features.add(newFeature); - } - } - - public static void register() {} -} diff --git a/src/main/java/ru/betterend/registry/EndItems.java b/src/main/java/ru/betterend/registry/EndItems.java deleted file mode 100644 index f37b456a..00000000 --- a/src/main/java/ru/betterend/registry/EndItems.java +++ /dev/null @@ -1,218 +0,0 @@ -package ru.betterend.registry; - -import java.util.List; - -import org.jetbrains.annotations.NotNull; - -import net.fabricmc.fabric.api.item.v1.FabricItemSettings; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.effect.MobEffects; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.food.FoodProperties; -import net.minecraft.world.food.Foods; -import net.minecraft.world.item.ArmorItem; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.TieredItem; -import net.minecraft.world.item.Tiers; -import ru.bclib.items.BaseArmorItem; -import ru.bclib.items.tool.BaseAxeItem; -import ru.bclib.items.tool.BaseHoeItem; -import ru.bclib.items.tool.BasePickaxeItem; -import ru.bclib.items.tool.BaseShovelItem; -import ru.bclib.items.tool.BaseSwordItem; -import ru.bclib.registry.ItemsRegistry; -import ru.betterend.BetterEnd; -import ru.betterend.config.Configs; -import ru.betterend.item.ArmoredElytra; -import ru.betterend.item.CrystaliteBoots; -import ru.betterend.item.CrystaliteChestplate; -import ru.betterend.item.CrystaliteElytra; -import ru.betterend.item.CrystaliteHelmet; -import ru.betterend.item.CrystaliteLeggings; -import ru.betterend.item.EnchantedItem; -import ru.betterend.item.EndBucketItem; -import ru.betterend.item.EternalCrystalItem; -import ru.betterend.item.material.EndArmorMaterial; -import ru.betterend.item.material.EndToolMaterial; -import ru.betterend.item.tool.EndHammerItem; -import ru.betterend.tab.CreativeTabs; - -public class EndItems extends ItemsRegistry { - // Materials // - public final static Item ENDER_DUST = registerEndItem("ender_dust"); - public final static Item ENDER_SHARD = registerEndItem("ender_shard"); - public final static Item AETERNIUM_INGOT = registerEndItem("aeternium_ingot"); - public final static Item AETERNIUM_FORGED_PLATE = registerEndItem("aeternium_forged_plate"); - public final static Item END_LILY_LEAF = registerEndItem("end_lily_leaf"); - public final static Item END_LILY_LEAF_DRIED = registerEndItem("end_lily_leaf_dried"); - public final static Item CRYSTAL_SHARDS = registerEndItem("crystal_shards"); - public final static Item RAW_AMBER = registerEndItem("raw_amber"); - public final static Item AMBER_GEM = registerEndItem("amber_gem"); - public final static Item GLOWING_BULB = registerEndItem("glowing_bulb"); - public final static Item CRYSTALLINE_SULPHUR = registerEndItem("crystalline_sulphur"); - public final static Item HYDRALUX_PETAL = registerEndItem("hydralux_petal"); - public final static Item GELATINE = registerEndItem("gelatine"); - public static final Item ETERNAL_CRYSTAL = registerEndItem("eternal_crystal", new EternalCrystalItem()); - public final static Item ENCHANTED_PETAL = registerEndItem("enchanted_petal", new EnchantedItem(HYDRALUX_PETAL)); - public final static Item LEATHER_STRIPE = registerEndItem("leather_stripe"); - public final static Item LEATHER_WRAPPED_STICK = registerEndItem("leather_wrapped_stick"); - public final static Item SILK_FIBER = registerEndItem("silk_fiber"); - public final static Item LUMECORN_ROD = registerEndItem("lumecorn_rod"); - public final static Item SILK_MOTH_MATRIX = registerEndItem("silk_moth_matrix"); - public final static Item ENCHANTED_MEMBRANE = registerEndItem("enchanted_membrane", new EnchantedItem(Items.PHANTOM_MEMBRANE)); - - // Music Discs - public final static Item MUSIC_DISC_STRANGE_AND_ALIEN = registerEndDisc("music_disc_strange_and_alien", 0, EndSounds.RECORD_STRANGE_AND_ALIEN); - public final static Item MUSIC_DISC_GRASPING_AT_STARS = registerEndDisc("music_disc_grasping_at_stars", 0, EndSounds.RECORD_GRASPING_AT_STARS); - public final static Item MUSIC_DISC_ENDSEEKER = registerEndDisc("music_disc_endseeker", 0, EndSounds.RECORD_ENDSEEKER); - public final static Item MUSIC_DISC_EO_DRACONA = registerEndDisc("music_disc_eo_dracona", 0, EndSounds.RECORD_EO_DRACONA); - - // Armor // - public static final Item AETERNIUM_HELMET = registerEndItem("aeternium_helmet", new BaseArmorItem(EndArmorMaterial.AETERNIUM, EquipmentSlot.HEAD, makeEndItemSettings().fireResistant())); - public static final Item AETERNIUM_CHESTPLATE = registerEndItem("aeternium_chestplate", new BaseArmorItem(EndArmorMaterial.AETERNIUM, EquipmentSlot.CHEST, makeEndItemSettings().fireResistant())); - public static final Item AETERNIUM_LEGGINGS = registerEndItem("aeternium_leggings", new BaseArmorItem(EndArmorMaterial.AETERNIUM, EquipmentSlot.LEGS, makeEndItemSettings().fireResistant())); - public static final Item AETERNIUM_BOOTS = registerEndItem("aeternium_boots", new BaseArmorItem(EndArmorMaterial.AETERNIUM, EquipmentSlot.FEET, makeEndItemSettings().fireResistant())); - public static final Item CRYSTALITE_HELMET = registerEndItem("crystalite_helmet", new CrystaliteHelmet()); - public static final Item CRYSTALITE_CHESTPLATE = registerEndItem("crystalite_chestplate", new CrystaliteChestplate()); - public static final Item CRYSTALITE_LEGGINGS = registerEndItem("crystalite_leggings", new CrystaliteLeggings()); - public static final Item CRYSTALITE_BOOTS = registerEndItem("crystalite_boots", new CrystaliteBoots()); - public static final Item ARMORED_ELYTRA = registerEndItem("elytra_armored", new ArmoredElytra("elytra_armored", EndArmorMaterial.AETERNIUM, Items.PHANTOM_MEMBRANE, 900, 0.975D, true)); - public static final Item CRYSTALITE_ELYTRA = registerEndItem("elytra_crystalite", new CrystaliteElytra(650, 0.99D)); - - // Tools // - public static final TieredItem AETERNIUM_SHOVEL = registerEndTool("aeternium_shovel", new BaseShovelItem(EndToolMaterial.AETERNIUM, 1.5F, -3.0F, makeEndItemSettings().fireResistant())); - public static final TieredItem AETERNIUM_SWORD = registerEndTool("aeternium_sword", new BaseSwordItem(EndToolMaterial.AETERNIUM, 3, -2.4F, makeEndItemSettings().fireResistant())); - public static final TieredItem AETERNIUM_PICKAXE = registerEndTool("aeternium_pickaxe", new BasePickaxeItem(EndToolMaterial.AETERNIUM, 1, -2.8F, makeEndItemSettings().fireResistant())); - public static final TieredItem AETERNIUM_AXE = registerEndTool("aeternium_axe", new BaseAxeItem(EndToolMaterial.AETERNIUM, 5.0F, -3.0F, makeEndItemSettings().fireResistant())); - public static final TieredItem AETERNIUM_HOE = registerEndTool("aeternium_hoe", new BaseHoeItem(EndToolMaterial.AETERNIUM, -3, 0.0F, makeEndItemSettings().fireResistant())); - public static final TieredItem AETERNIUM_HAMMER = registerEndTool("aeternium_hammer", new EndHammerItem(EndToolMaterial.AETERNIUM, 6.0F, -3.0F, 0.3D, makeEndItemSettings().fireResistant())); - - // Toolparts // - public final static Item AETERNIUM_SHOVEL_HEAD = registerEndItem("aeternium_shovel_head"); - public final static Item AETERNIUM_PICKAXE_HEAD = registerEndItem("aeternium_pickaxe_head"); - public final static Item AETERNIUM_AXE_HEAD = registerEndItem("aeternium_axe_head"); - public final static Item AETERNIUM_HOE_HEAD = registerEndItem("aeternium_hoe_head"); - public final static Item AETERNIUM_HAMMER_HEAD = registerEndItem("aeternium_hammer_head"); - public final static Item AETERNIUM_SWORD_BLADE = registerEndItem("aeternium_sword_blade"); - public final static Item AETERNIUM_SWORD_HANDLE = registerEndItem("aeternium_sword_handle"); - - // Hammers // - public static final TieredItem IRON_HAMMER = registerEndTool("iron_hammer", new EndHammerItem(Tiers.IRON, 5.0F, -3.2F, 0.2D, makeEndItemSettings())); - public static final TieredItem GOLDEN_HAMMER = registerEndTool("golden_hammer", new EndHammerItem(Tiers.GOLD, 4.5F, -3.4F, 0.3D, makeEndItemSettings())); - public static final TieredItem DIAMOND_HAMMER = registerEndTool("diamond_hammer", new EndHammerItem(Tiers.DIAMOND, 5.5F, -3.1F, 0.2D, makeEndItemSettings())); - public static final TieredItem NETHERITE_HAMMER = registerEndTool("netherite_hammer", new EndHammerItem(Tiers.NETHERITE, 5.0F, -3.0F, 0.2D, makeEndItemSettings().fireResistant())); - - // Food // - public final static Item SHADOW_BERRY_RAW = registerEndFood("shadow_berry_raw", 4, 0.5F); - public final static Item SHADOW_BERRY_COOKED = registerEndFood("shadow_berry_cooked", 6, 0.7F); - public final static Item END_FISH_RAW = registerEndFood("end_fish_raw", Foods.SALMON); - public final static Item END_FISH_COOKED = registerEndFood("end_fish_cooked", Foods.COOKED_SALMON); - public final static Item BUCKET_END_FISH = registerEndItem("bucket_end_fish", new EndBucketItem(EndEntities.END_FISH)); - public final static Item BUCKET_CUBOZOA = registerEndItem("bucket_cubozoa", new EndBucketItem(EndEntities.CUBOZOA)); - public final static Item SWEET_BERRY_JELLY = registerEndFood("sweet_berry_jelly", 8, 0.7F); - public final static Item SHADOW_BERRY_JELLY = registerEndFood("shadow_berry_jelly", 6, 0.8F, new MobEffectInstance(MobEffects.NIGHT_VISION, 400)); - public final static Item BLOSSOM_BERRY_JELLY = registerEndFood("blossom_berry_jelly", 8, 0.7F); - public final static Item BLOSSOM_BERRY = registerEndFood("blossom_berry", Foods.APPLE); - public final static Item AMBER_ROOT_RAW = registerEndFood("amber_root_raw", 2, 0.8F); - public final static Item CHORUS_MUSHROOM_RAW = registerEndFood("chorus_mushroom_raw", 3, 0.5F); - public final static Item CHORUS_MUSHROOM_COOKED = registerEndFood("chorus_mushroom_cooked", Foods.MUSHROOM_STEW); - public final static Item BOLUX_MUSHROOM_COOKED = registerEndFood("bolux_mushroom_cooked", Foods.MUSHROOM_STEW); - public final static Item CAVE_PUMPKIN_PIE = registerEndFood("cave_pumpkin_pie", Foods.PUMPKIN_PIE); - - // Drinks // - public final static Item UMBRELLA_CLUSTER_JUICE = registerEndDrink("umbrella_cluster_juice", 5, 0.7F); - - private static ItemsRegistry itemRegistry; - - protected EndItems(CreativeModeTab creativeTab) { - super(creativeTab); - } - - public static List getModItems() { - return getModItems(BetterEnd.MOD_ID); - } - - public static Item registerEndDisc(String name, int power, SoundEvent sound) { - return getItemRegistry().registerDisc(name, power, sound); - } - - public static Item registerEndItem(String name) { - return getItemRegistry().registerItem(name); - } - - public static Item registerEndItem(String name, Item item) { - return getItemRegistry().register(BetterEnd.makeID(name), item); - } - - public static Item registerEndItem(ResourceLocation id, Item item) { - if (item instanceof ArmorItem) { - return registerEndArmor(id, item); - } - if (!Configs.ITEM_CONFIG.getBoolean("items", id.getPath(), true)) { - return item; - } - getItemRegistry().register(id, item); - return item; - } - - private static Item registerEndArmor(ResourceLocation itemId, Item item) { - if (!Configs.ITEM_CONFIG.getBoolean("armor", itemId.getPath(), true)) { - return item; - } - getItemRegistry().register(itemId, item); - return item; - } - - public static TieredItem registerEndTool(String name, TieredItem item) { - if (!Configs.ITEM_CONFIG.getBoolean("tools", name, true)) { - return item; - } - return getItemRegistry().registerTool(name, item); - } - - public static Item registerEndEgg(String name, EntityType type, int background, int dots) { - return getItemRegistry().registerEgg(name, type, background, dots); - } - - public static Item registerEndFood(String name, int hunger, float saturation, MobEffectInstance... effects) { - return getItemRegistry().registerFood(name, hunger, saturation, effects); - } - - public static Item registerEndFood(String name, FoodProperties foodComponent) { - return getItemRegistry().registerFood(name, foodComponent); - } - - public static Item registerEndDrink(String name) { - return getItemRegistry().registerDrink(name); - } - - public static Item registerEndDrink(String name, FoodProperties foodComponent) { - return getItemRegistry().registerDrink(name, foodComponent); - } - - public static Item registerEndDrink(String name, int hunger, float saturation) { - return getItemRegistry().registerDrink(name, hunger, saturation); - } - - public static FabricItemSettings makeEndItemSettings() { - return itemRegistry.makeItemSettings(); - } - - @Override - public ResourceLocation createModId(String name) { - return BetterEnd.makeID(name); - } - - @NotNull - private static ItemsRegistry getItemRegistry() { - if (itemRegistry == null) { - itemRegistry = new EndItems(CreativeTabs.TAB_ITEMS); - } - return itemRegistry; - } -} diff --git a/src/main/java/ru/betterend/registry/EndModelProviders.java b/src/main/java/ru/betterend/registry/EndModelProviders.java deleted file mode 100644 index 80952641..00000000 --- a/src/main/java/ru/betterend/registry/EndModelProviders.java +++ /dev/null @@ -1,17 +0,0 @@ -package ru.betterend.registry; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.client.rendering.v1.ArmorRenderingRegistry; -import ru.betterend.item.model.CrystaliteArmorProvider; - -@Environment(EnvType.CLIENT) -public class EndModelProviders { - - public final static CrystaliteArmorProvider CRYSTALITE_PROVIDER = new CrystaliteArmorProvider(); - - public final static void register() { - ArmorRenderingRegistry.registerModel(CRYSTALITE_PROVIDER, CRYSTALITE_PROVIDER.getRenderedItems()); - ArmorRenderingRegistry.registerTexture(CRYSTALITE_PROVIDER, CRYSTALITE_PROVIDER.getRenderedItems()); - } -} diff --git a/src/main/java/ru/betterend/registry/EndParticles.java b/src/main/java/ru/betterend/registry/EndParticles.java deleted file mode 100644 index 2fb673a6..00000000 --- a/src/main/java/ru/betterend/registry/EndParticles.java +++ /dev/null @@ -1,63 +0,0 @@ -package ru.betterend.registry; - -import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry; -import net.fabricmc.fabric.api.particle.v1.FabricParticleTypes; -import net.minecraft.core.Registry; -import net.minecraft.core.particles.ParticleOptions; -import net.minecraft.core.particles.ParticleType; -import net.minecraft.core.particles.SimpleParticleType; -import ru.betterend.BetterEnd; -import ru.betterend.particle.FireflyParticle; -import ru.betterend.particle.InfusionParticle; -import ru.betterend.particle.InfusionParticleType; -import ru.betterend.particle.ParticleBlackSpore; -import ru.betterend.particle.ParticleGeyser; -import ru.betterend.particle.ParticleGlowingSphere; -import ru.betterend.particle.ParticleJungleSpore; -import ru.betterend.particle.ParticleSnowflake; -import ru.betterend.particle.ParticleSulphur; -import ru.betterend.particle.ParticleTenaneaPetal; -import ru.betterend.particle.PaticlePortalSphere; -import ru.betterend.particle.SmaragdantParticle; - -public class EndParticles { - public static final SimpleParticleType GLOWING_SPHERE = register("glowing_sphere"); - public static final SimpleParticleType PORTAL_SPHERE = register("portal_sphere"); - public static final ParticleType INFUSION = register("infusion", FabricParticleTypes.complex(InfusionParticleType.PARAMETERS_FACTORY)); - public static final SimpleParticleType SULPHUR_PARTICLE = register("sulphur_particle"); - public static final SimpleParticleType GEYSER_PARTICLE = registerFar("geyser_particle"); - public static final SimpleParticleType SNOWFLAKE = register("snowflake"); - public static final SimpleParticleType AMBER_SPHERE = register("amber_sphere"); - public static final SimpleParticleType BLACK_SPORE = register("black_spore"); - public static final SimpleParticleType TENANEA_PETAL = register("tenanea_petal"); - public static final SimpleParticleType JUNGLE_SPORE = register("jungle_spore"); - public static final SimpleParticleType FIREFLY = register("firefly"); - public static final SimpleParticleType SMARAGDANT = register("smaragdant_particle"); - - public static void register() { - ParticleFactoryRegistry.getInstance().register(GLOWING_SPHERE, ParticleGlowingSphere.FactoryGlowingSphere::new); - ParticleFactoryRegistry.getInstance().register(PORTAL_SPHERE, PaticlePortalSphere.FactoryPortalSphere::new); - ParticleFactoryRegistry.getInstance().register(INFUSION, InfusionParticle.InfusionFactory::new); - ParticleFactoryRegistry.getInstance().register(SULPHUR_PARTICLE, ParticleSulphur.FactorySulphur::new); - ParticleFactoryRegistry.getInstance().register(GEYSER_PARTICLE, ParticleGeyser.FactoryGeyser::new); - ParticleFactoryRegistry.getInstance().register(SNOWFLAKE, ParticleSnowflake.FactorySnowflake::new); - ParticleFactoryRegistry.getInstance().register(AMBER_SPHERE, ParticleGlowingSphere.FactoryGlowingSphere::new); - ParticleFactoryRegistry.getInstance().register(BLACK_SPORE, ParticleBlackSpore.FactoryBlackSpore::new); - ParticleFactoryRegistry.getInstance().register(TENANEA_PETAL, ParticleTenaneaPetal.FactoryTenaneaPetal::new); - ParticleFactoryRegistry.getInstance().register(JUNGLE_SPORE, ParticleJungleSpore.FactoryJungleSpore::new); - ParticleFactoryRegistry.getInstance().register(FIREFLY, FireflyParticle.FireflyParticleFactory::new); - ParticleFactoryRegistry.getInstance().register(SMARAGDANT, SmaragdantParticle.SmaragdantParticleFactory::new); - } - - private static SimpleParticleType register(String name) { - return Registry.register(Registry.PARTICLE_TYPE, BetterEnd.makeID(name), FabricParticleTypes.simple()); - } - - private static SimpleParticleType registerFar(String name) { - return Registry.register(Registry.PARTICLE_TYPE, BetterEnd.makeID(name), FabricParticleTypes.simple(true)); - } - - private static ParticleType register(String name, ParticleType type) { - return Registry.register(Registry.PARTICLE_TYPE, BetterEnd.makeID(name), type); - } -} diff --git a/src/main/java/ru/betterend/registry/EndPortals.java b/src/main/java/ru/betterend/registry/EndPortals.java deleted file mode 100644 index e09d0ac2..00000000 --- a/src/main/java/ru/betterend/registry/EndPortals.java +++ /dev/null @@ -1,154 +0,0 @@ -package ru.betterend.registry; - -import java.io.File; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; - -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.Level; -import ru.bclib.util.ColorUtil; -import ru.bclib.util.JsonFactory; -import ru.bclib.util.MHelper; -import ru.betterend.BetterEnd; - -public class EndPortals { - - public final static ResourceLocation OVERWORLD_ID = Level.OVERWORLD.location(); - - private static PortalInfo[] portals; - - public static void loadPortals() { - File file = new File(FabricLoader.getInstance().getConfigDir().toString(), "betterend/portals.json"); - JsonObject json; - if (!file.exists()) { - file.getParentFile().mkdirs(); - json = makeDefault(file); - } else { - json = JsonFactory.getJsonObject(file); - } - if (!json.has("portals") || !json.get("portals").isJsonArray()) { - json = makeDefault(file); - } - JsonArray array = json.get("portals").getAsJsonArray(); - if (array.size() == 0) { - json = makeDefault(file); - array = json.get("portals").getAsJsonArray(); - } - portals = new PortalInfo[array.size()]; - for (int i = 0; i < portals.length; i++) { - portals[i] = new PortalInfo(array.get(i).getAsJsonObject()); - } - } - - public static int getCount() { - return MHelper.max(portals.length - 1, 1); - } - - public static ServerLevel getWorld(MinecraftServer server, int portalId) { - if (portalId < 0 || portalId >= portals.length) { - return server.overworld(); - } - return portals[portalId].getWorld(server); - } - - public static ResourceLocation getWorldId(int portalId) { - if (portalId < 0 || portalId >= portals.length) { - return OVERWORLD_ID; - } - return portals[portalId].dimension; - } - - public static int getPortalIdByItem(ResourceLocation item) { - for (int i = 0; i < portals.length; i++) { - if (portals[i].item.equals(item)) { - return i; - } - } - return 0; - } - public static int getPortalIdByWorld(ResourceLocation world) { - for (int i = 0; i < portals.length; i++) { - if (portals[i].dimension.equals(world)) { - return i; - } - } - return 0; - } - - public static int getColor(int state) { - return portals[state].color; - } - - public static boolean isAvailableItem(ResourceLocation item) { - for (PortalInfo portal : portals) { - if (portal.item.equals(item)) { - return true; - } - } - return false; - } - - private static JsonObject makeDefault(File file) { - JsonObject jsonObject = new JsonObject(); - JsonFactory.storeJson(file, jsonObject); - JsonArray array = new JsonArray(); - jsonObject.add("portals", array); - array.add(makeDefault().toJson()); - JsonFactory.storeJson(file, jsonObject); - return jsonObject; - } - - private static PortalInfo makeDefault() { - return new PortalInfo(new ResourceLocation("minecraft:overworld"), BetterEnd.makeID("eternal_crystal"), 255, 255, 255); - } - - private static class PortalInfo { - private final ResourceLocation dimension; - private final ResourceLocation item; - private final int color; - private ServerLevel world; - - PortalInfo(JsonObject obj) { - this( - new ResourceLocation(JsonFactory.getString(obj, "dimension", "minecraft:overworld")), - new ResourceLocation(JsonFactory.getString(obj, "item", "betterend:eternal_crystal")), - JsonFactory.getInt(obj, "colorRed", 255), - JsonFactory.getInt(obj, "colorGreen", 255), - JsonFactory.getInt(obj, "colorBlue", 255) - ); - } - - PortalInfo(ResourceLocation dimension, ResourceLocation item, int r, int g, int b) { - this.dimension = dimension; - this.item = item; - this.color = ColorUtil.color(r, g, b); - } - - ServerLevel getWorld(MinecraftServer server) { - if (world != null) { - return world; - } - for (ServerLevel world : server.getAllLevels()) { - if (world.dimension().location().equals(dimension)) { - this.world = world; - return world; - } - } - return server.overworld(); - } - - JsonObject toJson() { - JsonObject obj = new JsonObject(); - obj.addProperty("dimension", dimension.toString()); - obj.addProperty("item", item.toString()); - obj.addProperty("colorRed", (color >> 16) & 255); - obj.addProperty("colorGreen", (color >> 8) & 255); - obj.addProperty("colorBlue", color & 255); - return obj; - } - } -} diff --git a/src/main/java/ru/betterend/registry/EndScreens.java b/src/main/java/ru/betterend/registry/EndScreens.java deleted file mode 100644 index a0464bc1..00000000 --- a/src/main/java/ru/betterend/registry/EndScreens.java +++ /dev/null @@ -1,11 +0,0 @@ -package ru.betterend.registry; - -import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry; -import ru.betterend.client.gui.EndStoneSmelterScreen; -import ru.betterend.client.gui.EndStoneSmelterScreenHandler; - -public class EndScreens { - public static void register() { - ScreenRegistry.register(EndStoneSmelterScreenHandler.HANDLER_TYPE, EndStoneSmelterScreen::new); - } -} diff --git a/src/main/java/ru/betterend/registry/EndSounds.java b/src/main/java/ru/betterend/registry/EndSounds.java deleted file mode 100644 index c0ecf7eb..00000000 --- a/src/main/java/ru/betterend/registry/EndSounds.java +++ /dev/null @@ -1,45 +0,0 @@ -package ru.betterend.registry; - -import net.minecraft.core.Registry; -import net.minecraft.sounds.SoundEvent; -import ru.betterend.BetterEnd; - -public class EndSounds { - // Music - public static final SoundEvent MUSIC_FOREST = register("music", "forest"); - public static final SoundEvent MUSIC_WATER = register("music", "water"); - public static final SoundEvent MUSIC_DARK = register("music", "dark"); - public static final SoundEvent MUSIC_OPENSPACE = register("music", "openspace"); - public static final SoundEvent MUSIC_CAVES = register("music", "caves"); - - // Ambient - public static final SoundEvent AMBIENT_FOGGY_MUSHROOMLAND = register("ambient", "foggy_mushroomland"); - public static final SoundEvent AMBIENT_CHORUS_FOREST = register("ambient", "chorus_forest"); - public static final SoundEvent AMBIENT_MEGALAKE = register("ambient", "megalake"); - public static final SoundEvent AMBIENT_DUST_WASTELANDS = register("ambient", "dust_wastelands"); - public static final SoundEvent AMBIENT_MEGALAKE_GROVE = register("ambient", "megalake_grove"); - public static final SoundEvent AMBIENT_BLOSSOMING_SPIRES = register("ambient", "blossoming_spires"); - public static final SoundEvent AMBIENT_SULPHUR_SPRINGS = register("ambient", "sulphur_springs"); - public static final SoundEvent AMBIENT_UMBRELLA_JUNGLE = register("ambient", "umbrella_jungle"); - public static final SoundEvent AMBIENT_GLOWING_GRASSLANDS = register("ambient", "glowing_grasslands"); - public static final SoundEvent AMBIENT_CAVES = register("ambient", "caves"); - - // Entity - public static final SoundEvent ENTITY_DRAGONFLY = register("entity", "dragonfly"); - public static final SoundEvent ENTITY_SHADOW_WALKER = register("entity", "shadow_walker"); - public static final SoundEvent ENTITY_SHADOW_WALKER_DAMAGE = register("entity", "shadow_walker_damage"); - public static final SoundEvent ENTITY_SHADOW_WALKER_DEATH = register("entity", "shadow_walker_death"); - - // Records - public static final SoundEvent RECORD_STRANGE_AND_ALIEN = register("record", "strange_and_alien"); - public static final SoundEvent RECORD_GRASPING_AT_STARS = register("record", "grasping_at_stars"); - public static final SoundEvent RECORD_ENDSEEKER = register("record", "endseeker"); - public static final SoundEvent RECORD_EO_DRACONA = register("record", "eo_dracona"); - - public static void register() {} - - private static SoundEvent register(String type, String id) { - id = "betterend." + type + "." + id; - return Registry.register(Registry.SOUND_EVENT, id, new SoundEvent(BetterEnd.makeID(id))); - } -} diff --git a/src/main/java/ru/betterend/registry/EndStructures.java b/src/main/java/ru/betterend/registry/EndStructures.java deleted file mode 100644 index c3ed2370..00000000 --- a/src/main/java/ru/betterend/registry/EndStructures.java +++ /dev/null @@ -1,59 +0,0 @@ -package ru.betterend.registry; - -import java.util.Collection; -import java.util.function.Supplier; - -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.levelgen.GenerationStep.Decoration; -import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; -import net.minecraft.world.level.levelgen.feature.StructurePieceType; -import ru.betterend.BetterEnd; -import ru.betterend.world.structures.EndStructureFeature; -import ru.betterend.world.structures.features.EternalPortalStructure; -import ru.betterend.world.structures.features.GiantIceStarStructure; -import ru.betterend.world.structures.features.GiantMossyGlowshroomStructure; -import ru.betterend.world.structures.features.MegaLakeSmallStructure; -import ru.betterend.world.structures.features.MegaLakeStructure; -import ru.betterend.world.structures.features.MountainStructure; -import ru.betterend.world.structures.features.PaintedMountainStructure; -import ru.betterend.world.structures.piece.CavePiece; -import ru.betterend.world.structures.piece.CrystalMountainPiece; -import ru.betterend.world.structures.piece.LakePiece; -import ru.betterend.world.structures.piece.NBTPiece; -import ru.betterend.world.structures.piece.PaintedMountainPiece; -import ru.betterend.world.structures.piece.VoxelPiece; - -public class EndStructures { - public static final StructurePieceType VOXEL_PIECE = register("voxel", VoxelPiece::new); - public static final StructurePieceType MOUNTAIN_PIECE = register("mountain_piece", CrystalMountainPiece::new); - public static final StructurePieceType CAVE_PIECE = register("cave_piece", CavePiece::new); - public static final StructurePieceType LAKE_PIECE = register("lake_piece", LakePiece::new); - public static final StructurePieceType PAINTED_MOUNTAIN_PIECE = register("painted_mountain_piece", PaintedMountainPiece::new); - public static final StructurePieceType NBT_PIECE = register("nbt_piece", NBTPiece::new); - - public static final EndStructureFeature GIANT_MOSSY_GLOWSHROOM = new EndStructureFeature("giant_mossy_glowshroom", new GiantMossyGlowshroomStructure(), Decoration.SURFACE_STRUCTURES, 16, 8); - public static final EndStructureFeature MEGALAKE = new EndStructureFeature("megalake", new MegaLakeStructure(), Decoration.RAW_GENERATION, 4, 1); - public static final EndStructureFeature MEGALAKE_SMALL = new EndStructureFeature("megalake_small", new MegaLakeSmallStructure(), Decoration.RAW_GENERATION, 4, 1); - public static final EndStructureFeature MOUNTAIN = new EndStructureFeature("mountain", new MountainStructure(), Decoration.RAW_GENERATION, 3, 2); - public static final EndStructureFeature PAINTED_MOUNTAIN = new EndStructureFeature("painted_mountain", new PaintedMountainStructure(), Decoration.RAW_GENERATION, 3, 2); - public static final EndStructureFeature ETERNAL_PORTAL = new EndStructureFeature("eternal_portal", new EternalPortalStructure(), Decoration.SURFACE_STRUCTURES, 16, 6); - public static final EndStructureFeature GIANT_ICE_STAR = new EndStructureFeature("giant_ice_star", new GiantIceStarStructure(), Decoration.SURFACE_STRUCTURES, 16, 8); - - public static void register() {} - - private static StructurePieceType register(String id, StructurePieceType pieceType) { - return Registry.register(Registry.STRUCTURE_PIECE, BetterEnd.makeID(id), pieceType); - } - - public static void registerBiomeStructures(ResourceLocation id, Biome biome, Collection>> structures) { - if (!id.getPath().contains("mountain") && !id.getPath().contains("lake")) { - addStructure(ETERNAL_PORTAL, structures); - } - } - - private static void addStructure(EndStructureFeature feature, Collection>> structures) { - structures.add(() -> { return feature.getFeatureConfigured(); }); - } -} diff --git a/src/main/java/ru/betterend/registry/EndTags.java b/src/main/java/ru/betterend/registry/EndTags.java deleted file mode 100644 index 7ce95c65..00000000 --- a/src/main/java/ru/betterend/registry/EndTags.java +++ /dev/null @@ -1,160 +0,0 @@ -package ru.betterend.registry; - -import java.util.List; -import java.util.function.Supplier; - -import com.google.common.collect.Lists; - -import net.fabricmc.fabric.api.tag.TagRegistry; -import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl; -import net.fabricmc.fabric.impl.tool.attribute.handlers.ModdedToolsVanillaBlocksToolHandler; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.BlockTags; -import net.minecraft.tags.ItemTags; -import net.minecraft.tags.Tag; -import net.minecraft.tags.Tag.Named; -import net.minecraft.tags.TagCollection; -import net.minecraft.world.food.FoodProperties; -import net.minecraft.world.item.Item; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.Biome.BiomeCategory; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.LeavesBlock; -import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilderConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.BonemealAPI; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BaseVineBlock; -import ru.bclib.blocks.SimpleLeavesBlock; -import ru.bclib.util.TagHelper; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.basis.EndTerrainBlock; -import ru.betterend.blocks.basis.PedestalBlock; -import ru.betterend.item.tool.EndHammerItem; -import ru.betterend.mixin.common.ComposterBlockAccessor; - -public class EndTags { - // Table with common (c) tags: - // https://fabricmc.net/wiki/tutorial:tags - - // Block Tags - public static final Tag.Named PEDESTALS = makeBlockTag("pedestal"); - public static final Tag.Named END_STONES = makeCommonBlockTag("end_stones"); - public static final Tag.Named DRAGON_IMMUNE = getMCBlockTag("dragon_immune"); - - // Item Tags - public final static Tag.Named HAMMERS = makeFabricItemTag("hammers"); - - public static Tag.Named makeTag(Supplier> containerSupplier, ResourceLocation id) { - Tag tag = containerSupplier.get().getTag(id); - return tag == null ? TagRegistry.create(id, containerSupplier) : (Named) tag; - } - - public static Tag.Named makeBlockTag(String name) { - return makeTag(BlockTags::getAllTags, BetterEnd.makeID(name)); - } - - public static Tag.Named makeItemTag(String name) { - return makeTag(ItemTags::getAllTags, BetterEnd.makeID(name)); - } - - public static Tag.Named makeCommonBlockTag(String name) { - return makeTag(BlockTags::getAllTags, new ResourceLocation("c", name)); - } - - public static Tag.Named makeCommonItemTag(String name) { - return makeTag(ItemTags::getAllTags, new ResourceLocation("c", name)); - } - - public static Tag.Named makeFabricItemTag(String name) { - return makeTag(ItemTags::getAllTags, new ResourceLocation("fabric", name)); - } - - public static Tag.Named getMCBlockTag(String name) { - ResourceLocation id = new ResourceLocation(name); - Tag tag = BlockTags.getAllTags().getTag(id); - return tag == null ? (Named) TagRegistry.block(id) : (Named) tag; - } - - public static void register() { - TagAPI.addEndGround(EndBlocks.THALLASIUM.ore); - TagAPI.addEndGround(EndBlocks.ENDSTONE_DUST); - TagAPI.addEndGround(EndBlocks.AMBER_ORE); - - EndBlocks.getModBlocks().forEach(block -> { - if (block instanceof EndTerrainBlock) { - TagAPI.addEndGround(block); - TagHelper.addTag(BlockTags.NYLIUM, block); - BonemealAPI.addSpreadableBlock(block); - } - else if (block instanceof LeavesBlock || block instanceof SimpleLeavesBlock) { - TagHelper.addTag(BlockTags.LEAVES, block); - ComposterBlockAccessor.callAdd(0.3F, block); - } - else if (block instanceof BaseVineBlock) { - TagHelper.addTag(BlockTags.CLIMBABLE, block); - } - else if (block instanceof PedestalBlock) { - TagHelper.addTag(PEDESTALS, block); - } - - Material mat = block.defaultBlockState().getMaterial(); - if (mat.equals(Material.PLANT) || mat.equals(Material.REPLACEABLE_PLANT)) { - ComposterBlockAccessor.callAdd(0.1F, block); - } - }); - BonemealAPI.addSpreadableBlock(EndBlocks.CAVE_MOSS); - - List hammers = Lists.newArrayList(); - EndItems.getModItems(BetterEnd.MOD_ID).forEach(item -> { - if (item.isEdible()) { - FoodProperties food = item.getFoodProperties(); - if (food != null) { - float compost = food.getNutrition() * food.getSaturationModifier() * 0.18F; - ComposterBlockAccessor.callAdd(compost, item); - } - } - if (item instanceof EndHammerItem) { - hammers.add(item); - } - }); - ToolManagerImpl.tag(HAMMERS).register(new ModdedToolsVanillaBlocksToolHandler(hammers)); - - TagHelper.addTag( - TagAPI.GEN_TERRAIN, - EndBlocks.ENDER_ORE, - EndBlocks.FLAVOLITE.stone, - EndBlocks.VIOLECITE.stone, - EndBlocks.SULPHURIC_ROCK.stone, - EndBlocks.BRIMSTONE, - EndBlocks.VIRID_JADESTONE.stone, - EndBlocks.AZURE_JADESTONE.stone, - EndBlocks.SANDY_JADESTONE.stone - ); - TagHelper.addTag(TagAPI.END_GROUND, EndBlocks.SULPHURIC_ROCK.stone, EndBlocks.BRIMSTONE); - TagHelper.addTag(BlockTags.ANVIL, EndBlocks.AETERNIUM_ANVIL); - TagHelper.addTag(BlockTags.BEACON_BASE_BLOCKS, EndBlocks.AETERNIUM_BLOCK); - TagHelper.addTag(ItemTags.BEACON_PAYMENT_ITEMS, EndItems.AETERNIUM_INGOT); - TagHelper.addTag(EndTags.DRAGON_IMMUNE, - EndBlocks.ENDER_ORE, - EndBlocks.ETERNAL_PEDESTAL, - EndBlocks.FLAVOLITE_RUNED_ETERNAL, - EndBlocks.FLAVOLITE_RUNED - ); - TagHelper.addTag(TagAPI.IRON_INGOTS, EndBlocks.THALLASIUM.ingot); - } - - public static void addTerrainTags(Registry biomeRegistry) { - biomeRegistry.forEach((biome) -> { - if (biome.getBiomeCategory() == BiomeCategory.THEEND) { - SurfaceBuilderConfiguration config = biome.getGenerationSettings().getSurfaceBuilderConfig(); - Block under = config.getUnderMaterial().getBlock(); - Block surface = config.getTopMaterial().getBlock(); - TagHelper.addTag(TagAPI.GEN_TERRAIN, under, surface); - TagHelper.addTag(TagAPI.END_GROUND, surface); - } - }); - END_STONES.getValues().forEach(TagAPI::addEndGround); - } -} diff --git a/src/main/java/ru/betterend/rituals/EternalRitual.java b/src/main/java/ru/betterend/rituals/EternalRitual.java deleted file mode 100644 index 1d7ebbdc..00000000 --- a/src/main/java/ru/betterend/rituals/EternalRitual.java +++ /dev/null @@ -1,649 +0,0 @@ -package ru.betterend.rituals; - -import java.awt.Point; -import java.util.List; -import java.util.Objects; -import java.util.Random; -import java.util.Set; -import java.util.function.Predicate; - -import org.jetbrains.annotations.Nullable; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Registry; -import net.minecraft.core.particles.BlockParticleOption; -import net.minecraft.core.particles.ParticleOptions; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.data.worldgen.Features; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.item.Item; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import net.minecraft.world.level.dimension.DimensionType; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.material.Material; -import ru.bclib.blocks.BlockProperties; -import ru.betterend.BetterEnd; -import ru.betterend.blocks.EndPortalBlock; -import ru.betterend.blocks.RunedFlavolite; -import ru.betterend.blocks.entities.EternalPedestalEntity; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndPortals; - -public class EternalRitual { - private final static Set STRUCTURE_MAP = Sets.newHashSet( - new Point(-4, -5), new Point(-4, 5), new Point(-6, 0), - new Point(4, -5), new Point(4, 5), new Point(6, 0)); - private final static Set FRAME_MAP = Sets.newHashSet( - new Point(0, 0), new Point(0, 6), new Point(1, 0), - new Point(1, 6), new Point(2, 1), new Point(2, 5), - new Point(3, 2), new Point(3, 3), new Point(3, 4)); - private final static Set PORTAL_MAP = Sets.newHashSet( - new Point(0, 0), new Point(0, 1), new Point(0, 2), - new Point(0, 3), new Point(0, 4), new Point(1, 0), - new Point(1, 1), new Point(1, 2), new Point(1, 3), - new Point(1, 4), new Point(2, 1), new Point(2, 2), - new Point(2, 3)); - private final static Set BASE_MAP = Sets.newHashSet( - new Point(3, 0), new Point(2, 0), new Point(2, 1), new Point(1, 1), - new Point(1, 2), new Point(0, 1), new Point(0, 2)); - - private final static Block BASE = EndBlocks.FLAVOLITE.tiles; - private final static Block PEDESTAL = EndBlocks.ETERNAL_PEDESTAL; - private final static Block FRAME = EndBlocks.FLAVOLITE_RUNED_ETERNAL; - private final static Block PORTAL = EndBlocks.END_PORTAL_BLOCK; - private final static BooleanProperty ACTIVE = BlockProperties.ACTIVE; - - public final static int SEARCH_RADIUS = calculateSearchSteps(48); - - private Level world; - private Direction.Axis axis; - private ResourceLocation targetWorldId; - private BlockPos center; - private BlockPos exit; - private boolean active = false; - - public EternalRitual(Level world) { - this.world = world; - } - - public EternalRitual(Level world, BlockPos initial) { - this(world); - this.configure(initial); - } - - public void setWorld(Level world) { - this.world = world; - } - - @Nullable - public ResourceLocation getTargetWorldId() { - return targetWorldId; - } - - private boolean isInvalid() { - return world == null || world.isClientSide() || - center == null || axis == null; - } - - public void checkStructure() { - if (isInvalid()) return; - Direction moveX, moveY; - if (Direction.Axis.X == axis) { - moveX = Direction.EAST; - moveY = Direction.NORTH; - } - else { - moveX = Direction.SOUTH; - moveY = Direction.EAST; - } - boolean valid = checkFrame(world, center.below()); - Item item = null; - for (Point pos : STRUCTURE_MAP) { - BlockPos.MutableBlockPos checkPos = center.mutable(); - checkPos.move(moveX, pos.x).move(moveY, pos.y); - valid &= isActive(checkPos); - if (valid) { - EternalPedestalEntity pedestal = (EternalPedestalEntity) world.getBlockEntity(checkPos); - if (pedestal != null) { - Item pItem = pedestal.getItem(0).getItem(); - if (item == null) { - item = pItem; - } else if (!item.equals(pItem)) { - valid = false; - } - } - } - } - if (valid && item != null) { - activatePortal(item); - } - } - - private boolean checkFrame(Level world, BlockPos framePos) { - Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH : Direction.EAST; - boolean valid = true; - for (Point point : FRAME_MAP) { - BlockPos pos = framePos.mutable().move(moveDir, point.x).move(Direction.UP, point.y); - BlockState state = world.getBlockState(pos); - valid &= state.getBlock() instanceof RunedFlavolite; - pos = framePos.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); - state = world.getBlockState(pos); - valid &= state.getBlock() instanceof RunedFlavolite; - } - return valid; - } - - public boolean isActive() { - return active; - } - - private void activatePortal(Item keyItem) { - if (active) return; - ResourceLocation itemId = Registry.ITEM.getKey(keyItem); - int portalId = EndPortals.getPortalIdByItem(itemId); - Level targetWorld = getTargetWorld(portalId); - ResourceLocation worldId = targetWorld.dimension().location(); - try { - if (exit == null) { - initPortal(worldId, portalId); - } else { - if (!worldId.equals(targetWorldId)) { - initPortal(worldId, portalId); - } else if (!checkFrame(targetWorld, exit.below())) { - Direction.Axis portalAxis = (Direction.Axis.X == axis) ? Direction.Axis.Z : Direction.Axis.X; - generatePortal(targetWorld, exit, portalAxis, portalId); - } - activatePortal(targetWorld, exit, portalId); - } - activatePortal(world, center, portalId); - doEffects((ServerLevel) world, center); - active = true; - } catch (Exception ex) { - BetterEnd.LOGGER.error("Create End portals error.", ex); - removePortal(targetWorld, exit); - removePortal(world, center); - active = false; - } - } - - private void initPortal(ResourceLocation worldId, int portalId) { - targetWorldId = worldId; - exit = findPortalPos(portalId); - } - - private void doEffects(ServerLevel serverWorld, BlockPos center) { - Direction moveX, moveY; - if (Direction.Axis.X == axis) { - moveX = Direction.EAST; - moveY = Direction.NORTH; - } - else { - moveX = Direction.SOUTH; - moveY = Direction.EAST; - } - for (Point pos : STRUCTURE_MAP) { - BlockPos.MutableBlockPos p = center.mutable(); - p.move(moveX, pos.x).move(moveY, pos.y); - serverWorld.sendParticles(ParticleTypes.PORTAL, p.getX() + 0.5, p.getY() + 1.5, p.getZ() + 0.5, 20, 0, 0, 0, 1); - serverWorld.sendParticles(ParticleTypes.REVERSE_PORTAL, p.getX() + 0.5, p.getY() + 1.5, p.getZ() + 0.5, 20, 0, 0, 0, 0.3); - } - serverWorld.playSound(null, center, SoundEvents.END_PORTAL_SPAWN, SoundSource.NEUTRAL, 16, 1); - } - - private void activatePortal(Level world, BlockPos center, int portalId) { - BlockPos framePos = center.below(); - Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH : Direction.EAST; - BlockState frame = FRAME.defaultBlockState().setValue(ACTIVE, true); - FRAME_MAP.forEach(point -> { - BlockPos pos = framePos.mutable().move(moveDir, point.x).move(Direction.UP, point.y); - BlockState state = world.getBlockState(pos); - if (state.hasProperty(ACTIVE) && !state.getValue(ACTIVE)) { - world.setBlockAndUpdate(pos, frame); - } - pos = framePos.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); - state = world.getBlockState(pos); - if (state.hasProperty(ACTIVE) && !state.getValue(ACTIVE)) { - world.setBlockAndUpdate(pos, frame); - } - }); - Direction.Axis portalAxis = Direction.Axis.X == axis ? Direction.Axis.Z : Direction.Axis.X; - BlockState portal = PORTAL.defaultBlockState().setValue(EndPortalBlock.AXIS, portalAxis).setValue(EndPortalBlock.PORTAL, portalId); - ParticleOptions effect = new BlockParticleOption(ParticleTypes.BLOCK, portal); - ServerLevel serverWorld = (ServerLevel) world; - - PORTAL_MAP.forEach(point -> { - BlockPos pos = center.mutable().move(moveDir, point.x).move(Direction.UP, point.y); - if (!world.getBlockState(pos).is(PORTAL)) { - world.setBlockAndUpdate(pos, portal); - serverWorld.sendParticles(effect, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 10, 0.5, 0.5, 0.5, 0.1); - serverWorld.sendParticles(ParticleTypes.REVERSE_PORTAL, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 10, 0.5, 0.5, 0.5, 0.3); - } - pos = center.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); - if (!world.getBlockState(pos).is(PORTAL)) { - world.setBlockAndUpdate(pos, portal); - serverWorld.sendParticles(effect, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 10, 0.5, 0.5, 0.5, 0.1); - serverWorld.sendParticles(ParticleTypes.REVERSE_PORTAL, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 10, 0.5, 0.5, 0.5, 0.3); - } - }); - } - - public void disablePortal(int state) { - if (!active || isInvalid()) return; - removePortal(getTargetWorld(state), exit); - removePortal(world, center); - } - - private void removePortal(Level world, BlockPos center) { - BlockPos framePos = center.below(); - Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH : Direction.EAST; - FRAME_MAP.forEach(point -> { - BlockPos pos = framePos.mutable().move(moveDir, point.x).move(Direction.UP, point.y); - BlockState state = world.getBlockState(pos); - if (state.is(FRAME) && state.getValue(ACTIVE)) { - world.setBlockAndUpdate(pos, state.setValue(ACTIVE, false)); - } - pos = framePos.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); - state = world.getBlockState(pos); - if (state.is(FRAME) && state.getValue(ACTIVE)) { - world.setBlockAndUpdate(pos, state.setValue(ACTIVE, false)); - } - }); - PORTAL_MAP.forEach(point -> { - BlockPos pos = center.mutable().move(moveDir, point.x).move(Direction.UP, point.y); - if (world.getBlockState(pos).is(PORTAL)) { - world.removeBlock(pos, false); - } - pos = center.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); - if (world.getBlockState(pos).is(PORTAL)) { - world.removeBlock(pos, false); - } - }); - this.active = false; - } - - @Nullable - private BlockPos findFrame(Level world, BlockPos.MutableBlockPos startPos) { - List foundPos = findAllBlockPos(world, startPos, (SEARCH_RADIUS >> 4) + 1, FRAME, - blockState -> blockState.is(FRAME) && !blockState.getValue(ACTIVE)); - for(BlockPos.MutableBlockPos testPos : foundPos) { - if (checkFrame(world, testPos)) { - return testPos; - } - } - return null; - } - - private BlockPos findPortalPos(int portalId) { - MinecraftServer server = world.getServer(); - ServerLevel targetWorld = (ServerLevel) getTargetWorld(portalId); - Registry registry = Objects.requireNonNull(server).registryAccess().dimensionTypes(); - double multiplier = Objects.requireNonNull(registry.get(targetWorldId)).coordinateScale(); - BlockPos.MutableBlockPos basePos = center.mutable().set(center.getX() / multiplier, center.getY(), center.getZ() / multiplier); - BlockPos framePos = findFrame(targetWorld, basePos.mutable()); - if (framePos != null) { - return framePos.above(); - } - Direction.Axis portalAxis = (Direction.Axis.X == axis) ? Direction.Axis.Z : Direction.Axis.X; - int worldCeil = targetWorld.getHeight() - 1; - if (checkIsAreaValid(targetWorld, basePos, portalAxis)) { - generatePortal(targetWorld, basePos, portalAxis, portalId); - return basePos.immutable(); - } else { - Direction direction = Direction.EAST; - BlockPos.MutableBlockPos checkPos = basePos.mutable(); - int radius = (int) ((SEARCH_RADIUS / multiplier) + 1); - for (int step = 1; step < radius; step++) { - for (int i = 0; i < (step >> 1); i++) { - ChunkAccess chunk = targetWorld.getChunk(checkPos); - if (chunk != null) { - int surfaceY = chunk.getHeight(Heightmap.Types.WORLD_SURFACE, checkPos.getX() & 15, checkPos.getZ() & 15); - int motionY = chunk.getHeight(Heightmap.Types.MOTION_BLOCKING, checkPos.getX() & 15, checkPos.getZ() & 15); - int ceil = Math.min(Math.max(surfaceY, motionY) + 1, worldCeil); - if (ceil < 5) continue; - checkPos.setY(ceil); - while (checkPos.getY() >= 5) { - if(checkIsAreaValid(targetWorld, checkPos, portalAxis)) { - generatePortal(targetWorld, checkPos, portalAxis, portalId); - return checkPos.immutable(); - } - checkPos.move(Direction.DOWN); - } - } - checkPos.move(direction); - } - direction = direction.getClockWise(); - } - } - if (targetWorld.dimension() == Level.END) { - Features.END_ISLAND.place(targetWorld, targetWorld.getChunkSource().getGenerator(), new Random(basePos.asLong()), basePos.below()); - } else if (targetWorld.dimension() == Level.OVERWORLD) { - basePos.setY(targetWorld.getChunk(basePos).getHeight(Heightmap.Types.WORLD_SURFACE, basePos.getX(), basePos.getZ()) + 1); - } - EndFeatures.BIOME_ISLAND.getFeatureConfigured().place(targetWorld, targetWorld.getChunkSource().getGenerator(), new Random(basePos.asLong()), basePos.below()); - generatePortal(targetWorld, basePos, portalAxis, portalId); - return basePos.immutable(); - } - - private Level getTargetWorld(int state) { - if (world.dimension() == Level.END) { - return EndPortals.getWorld(world.getServer(), state); - } - return Objects.requireNonNull(world.getServer()).getLevel(Level.END); - } - - private boolean checkIsAreaValid(Level world, BlockPos pos, Direction.Axis axis) { - if (pos.getY() >= world.getHeight() - 1) return false; - if (!isBaseValid(world, pos, axis)) return false; - return EternalRitual.checkArea(world, pos, axis); - } - - private boolean isBaseValid(Level world, BlockPos pos, Direction.Axis axis) { - boolean solid = true; - if (axis.equals(Direction.Axis.X)) { - pos = pos.below().offset(0, 0, -3); - for (int i = 0; i < 7; i++) { - BlockPos checkPos = pos.offset(0, 0, i); - BlockState state = world.getBlockState(checkPos); - solid &= validBlock(world, checkPos, state); - } - } - else { - pos = pos.below().offset(-3, 0, 0); - for (int i = 0; i < 7; i++) { - BlockPos checkPos = pos.offset(i, 0, 0); - BlockState state = world.getBlockState(checkPos); - solid &= validBlock(world, checkPos, state); - } - } - return solid; - } - - private boolean validBlock(Level world, BlockPos pos, BlockState state) { - return state.isRedstoneConductor(world, pos) && state.isCollisionShapeFullBlock(world, pos); - } - - public void configure(BlockPos initial) { - BlockPos checkPos = initial.east(12); - if (this.hasPedestal(checkPos)) { - this.axis = Direction.Axis.X; - this.center = initial.east(6); - return; - } - checkPos = initial.west(12); - if (this.hasPedestal(checkPos)) { - this.axis = Direction.Axis.X; - this.center = initial.west(6); - return; - } - checkPos = initial.south(12); - if (this.hasPedestal(checkPos)) { - this.axis = Direction.Axis.Z; - this.center = initial.south(6); - return; - } - checkPos = initial.north(12); - if (this.hasPedestal(checkPos)) { - this.axis = Direction.Axis.Z; - this.center = initial.north(6); - return; - } - checkPos = initial.north(10); - if (this.hasPedestal(checkPos)) { - this.axis = Direction.Axis.X; - checkPos = checkPos.east(8); - if (this.hasPedestal(checkPos)) { - this.center = initial.north(5).east(4); - } else { - this.center = initial.north(5).west(4); - } - return; - } - checkPos = initial.south(10); - if (this.hasPedestal(checkPos)) { - this.axis = Direction.Axis.X; - checkPos = checkPos.east(8); - if (this.hasPedestal(checkPos)) { - this.center = initial.south(5).east(4); - } else { - this.center = initial.south(5).west(4); - } - return; - } - checkPos = initial.east(10); - if (this.hasPedestal(checkPos)) { - this.axis = Direction.Axis.Z; - checkPos = checkPos.south(8); - if (this.hasPedestal(checkPos)) { - this.center = initial.east(5).south(4); - } else { - this.center = initial.east(5).north(4); - } - return; - } - checkPos = initial.west(10); - if (this.hasPedestal(checkPos)) { - this.axis = Direction.Axis.Z; - checkPos = checkPos.south(8); - if (this.hasPedestal(checkPos)) { - this.center = initial.west(5).south(4); - } else { - this.center = initial.west(5).north(4); - } - } - } - - private boolean hasPedestal(BlockPos pos) { - return world.getBlockState(pos).is(PEDESTAL); - } - - private boolean isActive(BlockPos pos) { - BlockState state = world.getBlockState(pos); - if (state.is(PEDESTAL)) { - EternalPedestalEntity pedestal = (EternalPedestalEntity) world.getBlockEntity(pos); - if (pedestal != null) { - if (!pedestal.hasRitual()) { - pedestal.linkRitual(this); - } else { - EternalRitual ritual = pedestal.getRitual(); - if (!ritual.equals(this)) { - pedestal.linkRitual(this); - } - } - } - return state.getValue(ACTIVE); - } - return false; - } - - public CompoundTag toTag(CompoundTag tag) { - tag.put("center", NbtUtils.writeBlockPos(center)); - tag.putString("axis", axis.getName()); - tag.putBoolean("active", active); - if (targetWorldId != null) { - tag.putString("key_item", targetWorldId.toString()); - } - if (exit != null) { - tag.put("exit", NbtUtils.writeBlockPos(exit)); - } - return tag; - } - - public void fromTag(CompoundTag tag) { - axis = Direction.Axis.byName(tag.getString("axis")); - center = NbtUtils.readBlockPos(tag.getCompound("center")); - active = tag.getBoolean("active"); - if (tag.contains("exit")) { - exit = NbtUtils.readBlockPos(tag.getCompound("exit")); - } - if (tag.contains("key_item")) { - targetWorldId = new ResourceLocation(tag.getString("key_item")); - } - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - EternalRitual ritual = (EternalRitual) o; - return world.equals(ritual.world) && - Objects.equals(center, ritual.center) && - Objects.equals(exit, ritual.exit); - } - - public static void generatePortal(Level world, BlockPos center, Direction.Axis axis, int portalId) { - BlockPos framePos = center.below(); - Direction moveDir = Direction.Axis.X == axis ? Direction.EAST : Direction.NORTH; - BlockState frame = FRAME.defaultBlockState().setValue(ACTIVE, true); - FRAME_MAP.forEach(point -> { - BlockPos pos = framePos.mutable().move(moveDir, point.x).move(Direction.UP, point.y); - world.setBlockAndUpdate(pos, frame); - pos = framePos.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); - world.setBlockAndUpdate(pos, frame); - }); - BlockState portal = PORTAL.defaultBlockState().setValue(EndPortalBlock.AXIS, axis).setValue(EndPortalBlock.PORTAL, portalId); - PORTAL_MAP.forEach(point -> { - BlockPos pos = center.mutable().move(moveDir, point.x).move(Direction.UP, point.y); - world.setBlockAndUpdate(pos, portal); - pos = center.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); - world.setBlockAndUpdate(pos, portal); - }); - generateBase(world, framePos, moveDir); - } - - private static void generateBase(Level world, BlockPos center, Direction moveX) { - BlockState base = BASE.defaultBlockState(); - Direction moveY = moveX.getClockWise(); - BASE_MAP.forEach(point -> { - BlockPos pos = center.mutable().move(moveX, point.x).move(moveY, point.y); - world.setBlockAndUpdate(pos, base); - pos = center.mutable().move(moveX, -point.x).move(moveY, point.y); - world.setBlockAndUpdate(pos, base); - pos = center.mutable().move(moveX, point.x).move(moveY, -point.y); - world.setBlockAndUpdate(pos, base); - pos = center.mutable().move(moveX, -point.x).move(moveY, -point.y); - world.setBlockAndUpdate(pos, base); - }); - } - - public static boolean checkArea(Level world, BlockPos center, Direction.Axis axis) { - Direction moveDir = Direction.Axis.X == axis ? Direction.NORTH : Direction.EAST; - for (BlockPos checkPos : BlockPos.betweenClosed(center.relative(moveDir.getClockWise()), center.relative(moveDir.getCounterClockWise()))) { - for (Point point : PORTAL_MAP) { - BlockPos pos = checkPos.mutable().move(moveDir, point.x).move(Direction.UP, point.y); - BlockState state = world.getBlockState(pos); - if (isStateInvalid(state)) return false; - pos = checkPos.mutable().move(moveDir, -point.x).move(Direction.UP, point.y); - state = world.getBlockState(pos); - if (isStateInvalid(state)) return false; - } - } - return true; - } - - private static boolean isStateInvalid(BlockState state) { - if (!state.getFluidState().isEmpty()) return true; - Material material = state.getMaterial(); - return !material.isReplaceable() && !material.equals(Material.PLANT); - } - - /** - * @param world World for search - * @param checkPos Start search position - * @param radius Search radius - * @param searchBlock Target block - * @param condition Predicate for test block states in the chunk section - * - * @return Position of the first found block or null. - */ - @Nullable - public static BlockPos.MutableBlockPos findBlockPos(Level world, BlockPos.MutableBlockPos checkPos, int radius, Block searchBlock, Predicate condition) { - Direction moveDirection = Direction.EAST; - for (int step = 1; step < radius; step++) { - for (int i = 0; i < (step >> 1); i++) { - ChunkAccess chunk = world.getChunk(checkPos); - if (!(chunk instanceof LevelChunk) || ((LevelChunk) chunk).isEmpty()) continue; - for (LevelChunkSection section : chunk.getSections()) { - if (section == null || !section.getStates().maybeHas(condition)) continue; - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for(int z = 0; z < 16; z++) { - BlockState checkState = section.getBlockState(x, y, z); - if (checkState.is(searchBlock)) { - int worldX = (chunk.getPos().x << 4) + x; - int worldY = section.bottomBlockY() + y; - int worldZ = (chunk.getPos().z << 4) + z; - checkPos.set(worldX, worldY, worldZ); - return checkPos; - } - } - } - } - } - checkPos.move(moveDirection, 16); - } - moveDirection = moveDirection.getClockWise(); - } - return null; - } - - /** - * @param world World for search - * @param checkPos Start search position - * @param radius Search radius - * @param searchBlock Target block - * @param condition Predicate for test block states in the chunk section - * - * @return List of positions of the all found blocks or empty list. - */ - public static List findAllBlockPos(Level world, BlockPos.MutableBlockPos checkPos, int radius, Block searchBlock, Predicate condition) { - List posFound = Lists.newArrayList(); - Direction moveDirection = Direction.EAST; - for (int step = 1; step < radius; step++) { - for (int i = 0; i < (step >> 1); i++) { - ChunkAccess chunk = world.getChunk(checkPos); - if (!(chunk instanceof LevelChunk) || ((LevelChunk) chunk).isEmpty()) continue; - for (LevelChunkSection section : chunk.getSections()) { - if (section == null || !section.getStates().maybeHas(condition)) continue; - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for(int z = 0; z < 16; z++) { - BlockState checkState = section.getBlockState(x, y, z); - if (checkState.is(searchBlock)) { - int worldX = (chunk.getPos().x << 4) + x; - int worldY = section.bottomBlockY() + y; - int worldZ = (chunk.getPos().z << 4) + z; - checkPos.set(worldX, worldY, worldZ); - posFound.add(checkPos.mutable()); - } - } - } - } - } - checkPos.move(moveDirection, 16); - } - moveDirection = moveDirection.getClockWise(); - } - return posFound; - } - - public static int calculateSearchSteps(int radius) { - return radius * 4 - 1; - } -} diff --git a/src/main/java/ru/betterend/rituals/InfusionRitual.java b/src/main/java/ru/betterend/rituals/InfusionRitual.java deleted file mode 100644 index f240ec47..00000000 --- a/src/main/java/ru/betterend/rituals/InfusionRitual.java +++ /dev/null @@ -1,245 +0,0 @@ -package ru.betterend.rituals; - -import java.awt.Point; -import java.util.Arrays; -import java.util.Objects; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.Container; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import ru.betterend.blocks.entities.InfusionPedestalEntity; -import ru.betterend.blocks.entities.PedestalBlockEntity; -import ru.betterend.particle.InfusionParticleType; -import ru.betterend.recipe.builders.InfusionRecipe; - -public class InfusionRitual implements Container { - private static final Point[] PEDESTALS_MAP = new Point[] { - new Point(0, 3), - new Point(2, 2), - new Point(3, 0), - new Point(2, -2), - new Point(0, -3), - new Point(-2, -2), - new Point(-3, 0), - new Point(-2, 2) - }; - - private Level world; - private BlockPos worldPos; - private InfusionRecipe activeRecipe; - private boolean isDirty = false; - private boolean hasRecipe = false; - private int progress = 0; - private int time = 0; - - private final PedestalBlockEntity[] catalysts = new PedestalBlockEntity[8]; - private final InfusionPedestalEntity input; - - public InfusionRitual(InfusionPedestalEntity pedestal, Level world, BlockPos pos) { - this.input = pedestal; - this.world = world; - this.worldPos = pos; - configure(); - } - - public void configure() { - if (world == null || worldPos == null || world.isClientSide) return; - for (int i = 0; i < catalysts.length; i++) { - Point point = PEDESTALS_MAP[i]; - MutableBlockPos checkPos = worldPos.mutable().move(Direction.EAST, point.x).move(Direction.NORTH, point.y); - BlockEntity catalystEntity = world.getBlockEntity(checkPos); - if (catalystEntity instanceof PedestalBlockEntity) { - catalysts[i] = (PedestalBlockEntity) catalystEntity; - } else { - catalysts[i] = null; - } - } - } - - public boolean checkRecipe() { - if (!isValid()) return false; - InfusionRecipe recipe = world.getRecipeManager().getRecipeFor(InfusionRecipe.TYPE, this, world).orElse(null); - if (hasRecipe()) { - if (recipe == null) { - reset(); - return false; - } else if (activeRecipe == null || recipe.getInfusionTime() != time) { - updateRecipe(recipe); - } - return true; - } - if (recipe != null) { - updateRecipe(recipe); - return true; - } - return false; - } - - private void updateRecipe(InfusionRecipe recipe) { - activeRecipe = recipe; - hasRecipe = true; - resetTimer(); - setChanged(); - } - - private void resetTimer() { - time = activeRecipe != null ? activeRecipe.getInfusionTime() : 0; - progress = 0; - } - - public void reset() { - activeRecipe = null; - hasRecipe = false; - resetTimer(); - setChanged(); - } - - public void tick() { - if (isDirty) { - configure(); - isDirty = false; - } - if (!checkRecipe()) return; - progress++; - if (progress == time) { - clearContent(); - input.setItem(0, activeRecipe.assemble(this)); - reset(); - } else { - ServerLevel serverLevel = (ServerLevel) world; - BlockPos target = worldPos.above(); - double tx = target.getX() + 0.5; - double ty = target.getY() + 0.5; - double tz = target.getZ() + 0.5; - for (PedestalBlockEntity catalyst : catalysts) { - ItemStack stack = catalyst.getItem(0); - if (!stack.isEmpty()) { - BlockPos start = catalyst.getBlockPos(); - double sx = start.getX() + 0.5; - double sy = start.getY() + 1.25; - double sz = start.getZ() + 0.5; - serverLevel.sendParticles(new InfusionParticleType(stack), sx, sy, sz, 0, tx - sx, ty - sy, tz - sz, 0.5); - } - } - } - - } - - @Override - public boolean canPlaceItem(int slot, ItemStack stack) { - return isValid(); - } - - public boolean isValid() { - if (world == null || world.isClientSide || worldPos == null || input == null) return false; - return Arrays.stream(catalysts).noneMatch(Objects::isNull); - } - - public boolean hasRecipe() { - return hasRecipe; - } - - public void setLocation(Level world, BlockPos pos) { - this.world = world; - this.worldPos = pos; - this.isDirty = true; - } - - @Override - public void clearContent() { - if (!isValid()) return; - input.clearContent(); - Arrays.stream(catalysts).forEach(PedestalBlockEntity::clearContent); - } - - @Override - public int getContainerSize() { - return 9; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public ItemStack getItem(int slot) { - if (slot > 8) return ItemStack.EMPTY; - if (slot == 0) { - return input.getItem(0); - } else { - return catalysts[slot - 1].getItem(0); - } - } - - @Override - public ItemStack removeItem(int slot, int amount) { - return removeItemNoUpdate(slot); - } - - @Override - public ItemStack removeItemNoUpdate(int slot) { - if (slot > 8) return ItemStack.EMPTY; - if (slot == 0) { - return input.removeItemNoUpdate(0); - } else { - return catalysts[slot - 1].removeItemNoUpdate(0); - } - } - - @Override - public void setItem(int slot, ItemStack stack) { - if (slot > 8) return; - if (slot == 0) { - input.setItem(0, stack); - } else { - catalysts[slot - 1].setItem(0, stack); - } - } - - @Override - public void setChanged() { - if (isValid()) { - input.setChanged(); - Arrays.stream(catalysts).forEach(PedestalBlockEntity::setChanged); - } - } - - public void markDirty() { - this.isDirty = true; - } - - @Override - public boolean stillValid(Player player) { - return true; - } - - public void fromTag(CompoundTag tag) { - if (tag.contains("recipe")) { - hasRecipe = tag.getBoolean("recipe"); - progress = tag.getInt("progress"); - time = tag.getInt("time"); - } - } - - public CompoundTag toTag(CompoundTag tag) { - if (hasRecipe()) { - tag.putBoolean("recipe", hasRecipe); - tag.putInt("progress", progress); - tag.putInt("time", time); - } - return tag; - } - - public static Point[] getMap() { - return PEDESTALS_MAP; - } -} diff --git a/src/main/java/ru/betterend/tab/CreativeTabs.java b/src/main/java/ru/betterend/tab/CreativeTabs.java deleted file mode 100644 index fab36d20..00000000 --- a/src/main/java/ru/betterend/tab/CreativeTabs.java +++ /dev/null @@ -1,28 +0,0 @@ -package ru.betterend.tab; - -import java.util.stream.Collectors; - -import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.ItemStack; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndItems; - -public class CreativeTabs { - public static final CreativeModeTab TAB_BLOCKS; - public static final CreativeModeTab TAB_ITEMS; - - static { - TAB_BLOCKS = FabricItemGroupBuilder.create(BetterEnd.makeID("end_blocks")) - .icon(() -> new ItemStack(EndBlocks.END_MYCELIUM)).appendItems(stacks -> { - stacks.addAll(EndBlocks.getModBlocks().stream() - .map(ItemStack::new).collect(Collectors.toList())); - }).build(); - TAB_ITEMS = FabricItemGroupBuilder.create(BetterEnd.makeID("end_items")) - .icon(() -> new ItemStack(EndItems.ETERNAL_CRYSTAL)).appendItems(stacks -> { - stacks.addAll(EndItems.getModItems().stream() - .map(ItemStack::new).collect(Collectors.toList())); - }).build(); - } -} diff --git a/src/main/java/ru/betterend/util/BlockFixer.java b/src/main/java/ru/betterend/util/BlockFixer.java deleted file mode 100644 index 9e9a0dcb..00000000 --- a/src/main/java/ru/betterend/util/BlockFixer.java +++ /dev/null @@ -1,206 +0,0 @@ -package ru.betterend.util; - -import java.util.Set; - -import com.google.common.collect.Sets; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.FallingBlock; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BaseDoublePlantBlock; -import ru.bclib.blocks.BaseVineBlock; -import ru.bclib.blocks.StalactiteBlock; -import ru.bclib.util.BlocksHelper; -import ru.betterend.blocks.BlueVineBlock; -import ru.betterend.blocks.basis.FurBlock; -import ru.betterend.registry.EndBlocks; - -public class BlockFixer { - private static final MutableBlockPos POS = new MutableBlockPos(); - private static final BlockState AIR = Blocks.AIR.defaultBlockState(); - private static final BlockState WATER = Blocks.WATER.defaultBlockState(); - - public static void fixBlocks(LevelAccessor world, BlockPos start, BlockPos end) { - BlockState state; - Set doubleCheck = Sets.newHashSet(); - for (int x = start.getX(); x <= end.getX(); x++) { - POS.setX(x); - for (int z = start.getZ(); z <= end.getZ(); z++) { - POS.setZ(z); - for (int y = start.getY(); y <= end.getY(); y++) { - POS.setY(y); - state = world.getBlockState(POS); - - if (state.getBlock() instanceof FurBlock) { - doubleCheck.add(POS.immutable()); - } - // Liquids - else if (!state.getFluidState().isEmpty()) { - if (!state.canSurvive(world, POS)) { - BlocksHelper.setWithoutUpdate(world, POS, WATER); - POS.setY(POS.getY() - 1); - state = world.getBlockState(POS); - while (!state.canSurvive(world, POS)) { - state = state.getFluidState().isEmpty() ? AIR : WATER; - BlocksHelper.setWithoutUpdate(world, POS, state); - POS.setY(POS.getY() - 1); - state = world.getBlockState(POS); - } - } - POS.setY(y - 1); - if (world.isEmptyBlock(POS)) { - POS.setY(y); - while (!world.getFluidState(POS).isEmpty()) { - BlocksHelper.setWithoutUpdate(world, POS, AIR); - POS.setY(POS.getY() + 1); - } - continue; - } - for (Direction dir : BlocksHelper.HORIZONTAL) { - if (world.isEmptyBlock(POS.relative(dir))) { - world.getLiquidTicks().scheduleTick(POS, state.getFluidState().getType(), 0); - break; - } - } - } - else if (state.is(EndBlocks.SMARAGDANT_CRYSTAL)) { - POS.setY(POS.getY() - 1); - if (world.isEmptyBlock(POS)) { - POS.setY(POS.getY() + 1); - while (state.is(EndBlocks.SMARAGDANT_CRYSTAL)) { - BlocksHelper.setWithoutUpdate(world, POS, AIR); - POS.setY(POS.getY() + 1); - state = world.getBlockState(POS); - } - } - } - else if (state.getBlock() instanceof StalactiteBlock) { - if (!state.canSurvive(world, POS)) { - if (world.getBlockState(POS.above()).getBlock() instanceof StalactiteBlock) { - while (state.getBlock() instanceof StalactiteBlock) { - BlocksHelper.setWithoutUpdate(world, POS, AIR); - POS.setY(POS.getY() + 1); - state = world.getBlockState(POS); - } - } - else { - while (state.getBlock() instanceof StalactiteBlock) { - BlocksHelper.setWithoutUpdate(world, POS, AIR); - POS.setY(POS.getY() - 1); - state = world.getBlockState(POS); - } - } - } - } - else if (state.is(EndBlocks.CAVE_PUMPKIN)) { - if (!world.getBlockState(POS.above()).is(EndBlocks.CAVE_PUMPKIN_SEED)) { - BlocksHelper.setWithoutUpdate(world, POS, AIR); - } - } - else if (!state.canSurvive(world, POS)) { - // Chorus - if (state.is(Blocks.CHORUS_PLANT)) { - Set ends = Sets.newHashSet(); - Set add = Sets.newHashSet(); - ends.add(POS.immutable()); - - for (int i = 0; i < 64 && !ends.isEmpty(); i++) { - ends.forEach((pos) -> { - BlocksHelper.setWithoutUpdate(world, pos, AIR); - for (Direction dir : BlocksHelper.HORIZONTAL) { - BlockPos p = pos.relative(dir); - BlockState st = world.getBlockState(p); - if ((st.is(Blocks.CHORUS_PLANT) || st.is(Blocks.CHORUS_FLOWER)) && !st.canSurvive(world, p)) { - add.add(p); - } - } - BlockPos p = pos.above(); - BlockState st = world.getBlockState(p); - if ((st.is(Blocks.CHORUS_PLANT) || st.is(Blocks.CHORUS_FLOWER)) && !st.canSurvive(world, p)) { - add.add(p); - } - }); - ends.clear(); - ends.addAll(add); - add.clear(); - } - } - // Vines - else if (state.getBlock() instanceof BaseVineBlock) { - while (world.getBlockState(POS).getBlock() instanceof BaseVineBlock) { - BlocksHelper.setWithoutUpdate(world, POS, AIR); - POS.setY(POS.getY() - 1); - } - } - // Falling blocks - else if (state.getBlock() instanceof FallingBlock) { - BlockState falling = state; - - POS.setY(POS.getY() - 1); - state = world.getBlockState(POS); - - int ray = BlocksHelper.downRayRep(world, POS.immutable(), 64); - if (ray > 32) { - BlocksHelper.setWithoutUpdate(world, POS, Blocks.END_STONE.defaultBlockState()); - if (world.getRandom().nextBoolean()) { - POS.setY(POS.getY() - 1); - state = world.getBlockState(POS); - BlocksHelper.setWithoutUpdate(world, POS, Blocks.END_STONE.defaultBlockState()); - } - } - else { - POS.setY(y); - BlockState replacement = AIR; - for (Direction dir : BlocksHelper.HORIZONTAL) { - state = world.getBlockState(POS.relative(dir)); - if (!state.getFluidState().isEmpty()) { - replacement = state; - break; - } - } - BlocksHelper.setWithoutUpdate(world, POS, replacement); - POS.setY(y - ray); - BlocksHelper.setWithoutUpdate(world, POS, falling); - } - } - // Blocks without support - else { - // Blue Vine - if (state.getBlock() instanceof BlueVineBlock) { - while (state.is(EndBlocks.BLUE_VINE) || state.is(EndBlocks.BLUE_VINE_LANTERN) || state.is(EndBlocks.BLUE_VINE_FUR)) { - BlocksHelper.setWithoutUpdate(world, POS, AIR); - POS.setY(POS.getY() + 1); - state = world.getBlockState(POS); - } - } - // Double plants - if (state.getBlock() instanceof BaseDoublePlantBlock) { - BlocksHelper.setWithoutUpdate(world, POS, AIR); - POS.setY(POS.getY() + 1); - BlocksHelper.setWithoutUpdate(world, POS, AIR); - } - // Other blocks - else { - BlocksHelper.setWithoutUpdate(world, POS, getAirOrFluid(state)); - } - } - } - } - } - } - - doubleCheck.forEach((pos) -> { - if (!world.getBlockState(pos).canSurvive(world, pos)) { - BlocksHelper.setWithoutUpdate(world, pos, AIR); - } - }); - } - - private static BlockState getAirOrFluid(BlockState state) { - return state.getFluidState().isEmpty() ? AIR : state.getFluidState().createLegacyBlock(); - } -} diff --git a/src/main/java/ru/betterend/util/BonemealPlants.java b/src/main/java/ru/betterend/util/BonemealPlants.java deleted file mode 100644 index b2a5cdf6..00000000 --- a/src/main/java/ru/betterend/util/BonemealPlants.java +++ /dev/null @@ -1,57 +0,0 @@ -package ru.betterend.util; - -import ru.bclib.api.BonemealAPI; -import ru.betterend.registry.EndBiomes; -import ru.betterend.registry.EndBlocks; - -public class BonemealPlants { - public static void init() { - BonemealAPI.addLandGrass(EndBlocks.CREEPING_MOSS, EndBlocks.END_MOSS); - BonemealAPI.addLandGrass(EndBlocks.UMBRELLA_MOSS, EndBlocks.END_MOSS); - BonemealAPI.addLandGrass(EndBlocks.CREEPING_MOSS, EndBlocks.END_MYCELIUM); - BonemealAPI.addLandGrass(EndBlocks.UMBRELLA_MOSS, EndBlocks.END_MYCELIUM); - - BonemealAPI.addLandGrass(EndBlocks.CAVE_GRASS, EndBlocks.CAVE_MOSS); - BonemealAPI.addLandGrass(EndBlocks.CHORUS_GRASS, EndBlocks.CHORUS_NYLIUM); - BonemealAPI.addLandGrass(EndBlocks.CRYSTAL_GRASS, EndBlocks.CRYSTAL_MOSS); - BonemealAPI.addLandGrass(EndBlocks.SHADOW_PLANT, EndBlocks.SHADOW_GRASS); - BonemealAPI.addLandGrass(EndBlocks.BUSHY_GRASS, EndBlocks.PINK_MOSS); - BonemealAPI.addLandGrass(EndBlocks.AMBER_GRASS, EndBlocks.AMBER_MOSS); - - BonemealAPI.addLandGrass(EndBlocks.JUNGLE_GRASS, EndBlocks.JUNGLE_MOSS); - BonemealAPI.addLandGrass(EndBlocks.TWISTED_UMBRELLA_MOSS, EndBlocks.JUNGLE_MOSS); - BonemealAPI.addLandGrass(EndBlocks.JUNGLE_MOSS, EndBlocks.SMALL_JELLYSHROOM, 0.1F); - - BonemealAPI.addLandGrass(EndBiomes.GLOWING_GRASSLANDS.getID(), EndBlocks.BLOOMING_COOKSONIA, EndBlocks.END_MOSS); - BonemealAPI.addLandGrass(EndBiomes.GLOWING_GRASSLANDS.getID(), EndBlocks.VAIOLUSH_FERN, EndBlocks.END_MOSS); - BonemealAPI.addLandGrass(EndBiomes.GLOWING_GRASSLANDS.getID(), EndBlocks.FRACTURN, EndBlocks.END_MOSS); - BonemealAPI.addLandGrass(EndBiomes.GLOWING_GRASSLANDS.getID(), EndBlocks.SALTEAGO, EndBlocks.END_MOSS); - - BonemealAPI.addLandGrass(EndBiomes.GLOWING_GRASSLANDS.getID(), EndBlocks.END_MOSS, EndBlocks.CREEPING_MOSS, 0.1F); - BonemealAPI.addLandGrass(EndBiomes.GLOWING_GRASSLANDS.getID(), EndBlocks.END_MOSS, EndBlocks.UMBRELLA_MOSS, 0.1F); - BonemealAPI.addLandGrass(EndBiomes.GLOWING_GRASSLANDS.getID(), EndBlocks.END_MOSS, EndBlocks.TWISTED_UMBRELLA_MOSS, 0.1F); - - BonemealAPI.addLandGrass(EndBlocks.ORANGO, EndBlocks.RUTISCUS); - BonemealAPI.addLandGrass(EndBlocks.RUTISCUS, EndBlocks.AERIDIUM, 0.2F); - BonemealAPI.addLandGrass(EndBlocks.RUTISCUS, EndBlocks.LUTEBUS, 0.2F); - BonemealAPI.addLandGrass(EndBlocks.RUTISCUS, EndBlocks.LAMELLARIUM); - - BonemealAPI.addLandGrass(EndBiomes.LANTERN_WOODS.getID(), EndBlocks.RUTISCUS, EndBlocks.AERIDIUM, 0.2F); - BonemealAPI.addLandGrass(EndBiomes.LANTERN_WOODS.getID(), EndBlocks.LAMELLARIUM, EndBlocks.RUTISCUS); - BonemealAPI.addLandGrass(EndBiomes.LANTERN_WOODS.getID(), EndBlocks.RUTISCUS, EndBlocks.BOLUX_MUSHROOM, 0.05F); - - BonemealAPI.addLandGrass(EndBlocks.GLOBULAGUS, EndBlocks.SANGNUM, EndBlocks.MOSSY_OBSIDIAN, EndBlocks.MOSSY_DRAGON_BONE); - BonemealAPI.addLandGrass(EndBlocks.CLAWFERN, EndBlocks.SANGNUM, EndBlocks.MOSSY_OBSIDIAN, EndBlocks.MOSSY_DRAGON_BONE); - BonemealAPI.addLandGrass(EndBlocks.SANGNUM, EndBlocks.SMALL_AMARANITA_MUSHROOM, 0.1F); - BonemealAPI.addLandGrass(EndBlocks.MOSSY_OBSIDIAN, EndBlocks.SMALL_AMARANITA_MUSHROOM, 0.1F); - BonemealAPI.addLandGrass(EndBlocks.MOSSY_DRAGON_BONE, EndBlocks.SMALL_AMARANITA_MUSHROOM, 0.1F); - - BonemealAPI.addLandGrass(EndBlocks.GLOBULAGUS, EndBlocks.MOSSY_DRAGON_BONE); - BonemealAPI.addLandGrass(EndBlocks.CLAWFERN, EndBlocks.MOSSY_DRAGON_BONE); - BonemealAPI.addLandGrass(EndBlocks.MOSSY_DRAGON_BONE, EndBlocks.SMALL_AMARANITA_MUSHROOM, 0.1F); - - BonemealAPI.addLandGrass(EndBlocks.GLOBULAGUS, EndBlocks.MOSSY_OBSIDIAN); - BonemealAPI.addLandGrass(EndBlocks.CLAWFERN, EndBlocks.MOSSY_OBSIDIAN); - BonemealAPI.addLandGrass(EndBlocks.MOSSY_OBSIDIAN, EndBlocks.SMALL_AMARANITA_MUSHROOM, 0.1F); - } -} diff --git a/src/main/java/ru/betterend/util/FeaturesHelper.java b/src/main/java/ru/betterend/util/FeaturesHelper.java deleted file mode 100644 index d2b9658c..00000000 --- a/src/main/java/ru/betterend/util/FeaturesHelper.java +++ /dev/null @@ -1,42 +0,0 @@ -package ru.betterend.util; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.function.Supplier; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; - -import net.minecraft.core.Registry; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; -import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; -import ru.betterend.mixin.common.BiomeGenerationSettingsAccessor; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndStructures; - -public class FeaturesHelper { - private static final Set INJECTED = Sets.newHashSet(); - - public static void addFeatures(Registry biomeRegistry) { - biomeRegistry.forEach((biome) -> { - if (biome.getBiomeCategory() == Biome.BiomeCategory.THEEND && !INJECTED.contains(biome)) { - BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) biome.getGenerationSettings(); - List>> structures = Lists.newArrayList(accessor.be_getStructures()); - List>>> preFeatures = accessor.be_getFeatures(); - List>>> features = new ArrayList>>>(preFeatures.size()); - preFeatures.forEach((list) -> { - features.add(Lists.newArrayList(list)); - }); - - EndFeatures.registerBiomeFeatures(biomeRegistry.getKey(biome), biome, features); - EndStructures.registerBiomeStructures(biomeRegistry.getKey(biome), biome, structures); - - accessor.be_setFeatures(features); - accessor.be_setStructures(structures); - INJECTED.add(biome); - } - }); - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/util/ItemUtil.java b/src/main/java/ru/betterend/util/ItemUtil.java deleted file mode 100644 index 20f57987..00000000 --- a/src/main/java/ru/betterend/util/ItemUtil.java +++ /dev/null @@ -1,73 +0,0 @@ -package ru.betterend.util; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import com.google.gson.JsonObject; - -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.GsonHelper; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import ru.betterend.BetterEnd; - -public class ItemUtil { - - public static String toStackString(@NotNull ItemStack stack) { - try { - if (stack == null) { - throw new IllegalStateException("Stack can't be null!"); - } - Item item = stack.getItem(); - return Registry.ITEM.getKey(item) + ":" + stack.getCount(); - } catch (Exception ex) { - BetterEnd.LOGGER.error("ItemStack serialization error!", ex); - } - return ""; - } - - @Nullable - public static ItemStack fromStackString(String stackString) { - if (stackString == null || stackString.equals("")) { - return null; - } - try { - String[] parts = stackString.split(":"); - if (parts.length < 2) return null; - if (parts.length == 2) { - ResourceLocation itemId = new ResourceLocation(stackString); - Item item = Registry.ITEM.getOptional(itemId).orElseThrow(() -> { - return new IllegalStateException("Output item " + itemId + " does not exists!"); - }); - return new ItemStack(item); - } - ResourceLocation itemId = new ResourceLocation(parts[0], parts[1]); - Item item = Registry.ITEM.getOptional(itemId).orElseThrow(() -> { - return new IllegalStateException("Output item " + itemId + " does not exists!"); - }); - return new ItemStack(item, Integer.valueOf(parts[2])); - } catch (Exception ex) { - BetterEnd.LOGGER.error("ItemStack deserialization error!", ex); - } - return null; - } - - @Nullable - public static ItemStack fromJsonRecipe(JsonObject recipe) { - try { - if (!recipe.has("item")) { - throw new IllegalStateException("Invalid JsonObject. Entry 'item' does not exists!"); - } - ResourceLocation itemId = new ResourceLocation(GsonHelper.getAsString(recipe, "item")); - Item item = Registry.ITEM.getOptional(itemId).orElseThrow(() -> { - return new IllegalStateException("Output item " + itemId + " does not exists!"); - }); - int count = GsonHelper.getAsInt(recipe, "count", 1); - return new ItemStack(item, count); - } catch (Exception ex) { - BetterEnd.LOGGER.error("ItemStack deserialization error!", ex); - } - return null; - } -} diff --git a/src/main/java/ru/betterend/util/LangUtil.java b/src/main/java/ru/betterend/util/LangUtil.java deleted file mode 100644 index bc051bf8..00000000 --- a/src/main/java/ru/betterend/util/LangUtil.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.betterend.util; - -import net.minecraft.client.resources.language.I18n; -import net.minecraft.network.chat.TranslatableComponent; - -public class LangUtil { - public final static String CONFIG_ELEMENT = "configuration"; - - private String element; - - public LangUtil(String element) { - this.element = element; - } - - public void setElement(String key) { - this.element = key; - } - - public String getString(String key) { - return getString(element, key); - } - - public TranslatableComponent getText(String key) { - return getText(element, key); - } - - public static String translate(String key) { - return I18n.get(key); - } - - public static String getString(String element, String key) { - return translate(String.format("%s.%s", element, key)); - } - - public static TranslatableComponent getText(String element, String key) { - return new TranslatableComponent(getString(element, key)); - } -} diff --git a/src/main/java/ru/betterend/util/LootTableUtil.java b/src/main/java/ru/betterend/util/LootTableUtil.java deleted file mode 100644 index 1b8cb09d..00000000 --- a/src/main/java/ru/betterend/util/LootTableUtil.java +++ /dev/null @@ -1,35 +0,0 @@ -package ru.betterend.util; - -import net.fabricmc.fabric.api.loot.v1.FabricLootPoolBuilder; -import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.storage.loot.RandomValueBounds; -import net.minecraft.world.level.storage.loot.entries.LootItem; -import net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition; -import ru.betterend.registry.EndItems; - -public class LootTableUtil { - private static final ResourceLocation END_CITY_TREASURE_ID = new ResourceLocation("chests/end_city_treasure"); - - public static void init() { - LootTableLoadingCallback.EVENT.register((resourceManager, lootManager, id, supplier, setter) -> { - if (END_CITY_TREASURE_ID.equals(id)) { - FabricLootPoolBuilder builder = FabricLootPoolBuilder.builder(); - builder.setRolls(RandomValueBounds.between(0, 5)); - builder.withCondition(LootItemRandomChanceCondition.randomChance(0.5f).build()); - builder.withEntry(LootItem.lootTableItem(Items.GHAST_TEAR).build()); - supplier.withPool(builder); - - builder = FabricLootPoolBuilder.builder(); - builder.setRolls(RandomValueBounds.between(0, 5)); - builder.withCondition(LootItemRandomChanceCondition.randomChance(0.1f).build()); - builder.withEntry(LootItem.lootTableItem(EndItems.MUSIC_DISC_STRANGE_AND_ALIEN).build()); - builder.withEntry(LootItem.lootTableItem(EndItems.MUSIC_DISC_GRASPING_AT_STARS).build()); - builder.withEntry(LootItem.lootTableItem(EndItems.MUSIC_DISC_ENDSEEKER).build()); - builder.withEntry(LootItem.lootTableItem(EndItems.MUSIC_DISC_EO_DRACONA).build()); - supplier.withPool(builder); - } - }); - } -} diff --git a/src/main/java/ru/betterend/util/RecipeHelper.java b/src/main/java/ru/betterend/util/RecipeHelper.java deleted file mode 100644 index 7b0f879e..00000000 --- a/src/main/java/ru/betterend/util/RecipeHelper.java +++ /dev/null @@ -1,24 +0,0 @@ -package ru.betterend.util; - -import net.minecraft.core.Registry; -import net.minecraft.world.level.ItemLike; -import net.minecraft.world.level.block.Block; - -public class RecipeHelper { - public static boolean exists(ItemLike item) { - if (item instanceof Block) { - return Registry.BLOCK.getKey((Block) item) != Registry.BLOCK.getDefaultKey(); - } else { - return Registry.ITEM.getKey(item.asItem()) != Registry.ITEM.getDefaultKey(); - } - } - - public static boolean exists(ItemLike... items) { - for (ItemLike item : items) { - if (!exists(item)) { - return false; - } - } - return true; - } -} diff --git a/src/main/java/ru/betterend/util/SpawnHelper.java b/src/main/java/ru/betterend/util/SpawnHelper.java deleted file mode 100644 index e42a688a..00000000 --- a/src/main/java/ru/betterend/util/SpawnHelper.java +++ /dev/null @@ -1,22 +0,0 @@ -package ru.betterend.util; - -import net.fabricmc.fabric.mixin.object.builder.SpawnRestrictionAccessor; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.Mob; -import net.minecraft.world.entity.SpawnPlacements.SpawnPredicate; -import net.minecraft.world.entity.SpawnPlacements.Type; -import net.minecraft.world.level.levelgen.Heightmap.Types; - -public class SpawnHelper { - public static void restrictionAir(EntityType entity, SpawnPredicate predicate) { - SpawnRestrictionAccessor.callRegister(entity, Type.NO_RESTRICTIONS, Types.MOTION_BLOCKING, predicate); - } - - public static void restrictionLand(EntityType entity, SpawnPredicate predicate) { - SpawnRestrictionAccessor.callRegister(entity, Type.ON_GROUND, Types.MOTION_BLOCKING, predicate); - } - - public static void restrictionWater(EntityType entity, SpawnPredicate predicate) { - SpawnRestrictionAccessor.callRegister(entity, Type.IN_WATER, Types.MOTION_BLOCKING, predicate); - } -} diff --git a/src/main/java/ru/betterend/world/biome/EndBiome.java b/src/main/java/ru/betterend/world/biome/EndBiome.java deleted file mode 100644 index e2c210b5..00000000 --- a/src/main/java/ru/betterend/world/biome/EndBiome.java +++ /dev/null @@ -1,18 +0,0 @@ -package ru.betterend.world.biome; - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome; -import ru.bclib.world.biomes.BCLBiome; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.config.Configs; - -public class EndBiome extends BCLBiome { - public EndBiome(BCLBiomeDef definition) { - super(definition.loadConfigValues(Configs.BIOME_CONFIG)); - } - - public EndBiome(ResourceLocation id, Biome biome, float fogDensity, float genChance, boolean hasCaves) { - super(id, biome, fogDensity, genChance); - this.addCustomData("has_caves", hasCaves); - } -} diff --git a/src/main/java/ru/betterend/world/biome/air/BiomeIceStarfield.java b/src/main/java/ru/betterend/world/biome/air/BiomeIceStarfield.java deleted file mode 100644 index ac5109ee..00000000 --- a/src/main/java/ru/betterend/world/biome/air/BiomeIceStarfield.java +++ /dev/null @@ -1,26 +0,0 @@ -package ru.betterend.world.biome.air; - -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndStructures; -import ru.betterend.world.biome.EndBiome; - -public class BiomeIceStarfield extends EndBiome { - public BiomeIceStarfield() { - super(new BCLBiomeDef(BetterEnd.makeID("ice_starfield")) - .addCustomData("has_caves", false) - .addStructureFeature(EndStructures.GIANT_ICE_STAR.getFeatureConfigured()) - .setFogColor(224, 245, 254) - .setTemperature(0F) - .setFogDensity(2.2F) - .setFoliageColor(193, 244, 244) - .setGenChance(0.25F) - .setParticles(EndParticles.SNOWFLAKE, 0.002F) - .addFeature(EndFeatures.ICE_STAR) - .addFeature(EndFeatures.ICE_STAR_SMALL) - .addMobSpawn(EntityType.ENDERMAN, 20, 1, 4)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/cave/EmptyAuroraCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/EmptyAuroraCaveBiome.java deleted file mode 100644 index 7ab06f41..00000000 --- a/src/main/java/ru/betterend/world/biome/cave/EmptyAuroraCaveBiome.java +++ /dev/null @@ -1,31 +0,0 @@ -package ru.betterend.world.biome.cave; - -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndParticles; - -public class EmptyAuroraCaveBiome extends EndCaveBiome { - public EmptyAuroraCaveBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("empty_aurora_cave")) - .setFogColor(150, 30, 68) - .setFogDensity(2.0F) - .setPlantsColor(108, 25, 46) - .setWaterAndFogColor(186, 77, 237) - .setParticles(EndParticles.GLOWING_SPHERE, 0.001F)); - - this.addFloorFeature(EndFeatures.BIG_AURORA_CRYSTAL, 1); - - this.addCeilFeature(EndFeatures.END_STONE_STALACTITE, 1); - } - - @Override - public float getFloorDensity() { - return 0.01F; - } - - @Override - public float getCeilDensity() { - return 0.1F; - } -} diff --git a/src/main/java/ru/betterend/world/biome/cave/EmptyEndCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/EmptyEndCaveBiome.java deleted file mode 100644 index 151e7475..00000000 --- a/src/main/java/ru/betterend/world/biome/cave/EmptyEndCaveBiome.java +++ /dev/null @@ -1,23 +0,0 @@ -package ru.betterend.world.biome.cave; - -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndFeatures; - -public class EmptyEndCaveBiome extends EndCaveBiome { - public EmptyEndCaveBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("empty_end_cave")).setFogDensity(2.0F)); - this.addFloorFeature(EndFeatures.END_STONE_STALAGMITE, 1); - this.addCeilFeature(EndFeatures.END_STONE_STALACTITE, 1); - } - - @Override - public float getFloorDensity() { - return 0.1F; - } - - @Override - public float getCeilDensity() { - return 0.1F; - } -} diff --git a/src/main/java/ru/betterend/world/biome/cave/EmptySmaragdantCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/EmptySmaragdantCaveBiome.java deleted file mode 100644 index 8fe0f4a8..00000000 --- a/src/main/java/ru/betterend/world/biome/cave/EmptySmaragdantCaveBiome.java +++ /dev/null @@ -1,32 +0,0 @@ -package ru.betterend.world.biome.cave; - -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndParticles; - -public class EmptySmaragdantCaveBiome extends EndCaveBiome { - public EmptySmaragdantCaveBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("empty_smaragdant_cave")) - .setFogColor(0, 253, 182) - .setFogDensity(2.0F) - .setPlantsColor(0, 131, 145) - .setWaterAndFogColor(31, 167, 212) - .setParticles(EndParticles.SMARAGDANT, 0.001F)); - - this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL, 1); - this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL_SHARD, 20); - - this.addCeilFeature(EndFeatures.END_STONE_STALACTITE, 1); - } - - @Override - public float getFloorDensity() { - return 0.1F; - } - - @Override - public float getCeilDensity() { - return 0.1F; - } -} diff --git a/src/main/java/ru/betterend/world/biome/cave/EndCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/EndCaveBiome.java deleted file mode 100644 index e25ea7db..00000000 --- a/src/main/java/ru/betterend/world/biome/cave/EndCaveBiome.java +++ /dev/null @@ -1,68 +0,0 @@ -package ru.betterend.world.biome.cave; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.entity.ai.behavior.WeightedList; -import net.minecraft.world.level.biome.Biome.BiomeCategory; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.feature.Feature; -import ru.bclib.api.BiomeAPI; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.bclib.world.features.BCLFeature; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndSounds; -import ru.betterend.world.biome.EndBiome; -import ru.betterend.world.features.terrain.caves.CaveChunkPopulatorFeature; - -public class EndCaveBiome extends EndBiome { - private WeightedList> floorFeatures = new WeightedList>(); - private WeightedList> ceilFeatures = new WeightedList>(); - - public EndCaveBiome(BCLBiomeDef definition) { - super(makeDef(definition)); - } - - private static BCLBiomeDef makeDef(BCLBiomeDef definition) { - BCLFeature feature = BCLFeature.makeChunkFeature( - BetterEnd.makeID(definition.getID().getPath() + "_cave_populator"), - new CaveChunkPopulatorFeature(() -> (EndCaveBiome) BiomeAPI.getBiome(definition.getID())) - ); - definition.setCategory(BiomeCategory.NONE).addFeature(feature); - definition.setMusic(EndSounds.MUSIC_CAVES); - definition.setLoop(EndSounds.AMBIENT_CAVES); - return definition; - } - - public void addFloorFeature(Feature feature, int weight) { - floorFeatures.add(feature, weight); - } - - public void addCeilFeature(Feature feature, int weight) { - ceilFeatures.add(feature, weight); - } - - public Feature getFloorFeature(Random random) { - return floorFeatures.isEmpty() ? null : floorFeatures.getOne(random); - } - - public Feature getCeilFeature(Random random) { - return ceilFeatures.isEmpty() ? null : ceilFeatures.getOne(random); - } - - public float getFloorDensity() { - return 0; - } - - public float getCeilDensity() { - return 0; - } - - public BlockState getCeil(BlockPos pos) { - return null; - } - - public BlockState getWall(BlockPos pos) { - return null; - } -} diff --git a/src/main/java/ru/betterend/world/biome/cave/JadeCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/JadeCaveBiome.java deleted file mode 100644 index 17c9b05e..00000000 --- a/src/main/java/ru/betterend/world/biome/cave/JadeCaveBiome.java +++ /dev/null @@ -1,34 +0,0 @@ -package ru.betterend.world.biome.cave; - -import net.minecraft.core.BlockPos; -import net.minecraft.util.Mth; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class JadeCaveBiome extends EndCaveBiome { - private static final OpenSimplexNoise WALL_NOISE = new OpenSimplexNoise("jade_cave".hashCode()); - private static final OpenSimplexNoise DEPTH_NOISE = new OpenSimplexNoise("depth_noise".hashCode()); - private static final BlockState[] JADE = new BlockState[3]; - - public JadeCaveBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("jade_cave")) - .setFogColor(118, 150, 112) - .setFogDensity(2.0F) - .setWaterAndFogColor(95, 223, 255) - ); - JADE[0] = EndBlocks.VIRID_JADESTONE.stone.defaultBlockState(); - JADE[1] = EndBlocks.AZURE_JADESTONE.stone.defaultBlockState(); - JADE[2] = EndBlocks.SANDY_JADESTONE.stone.defaultBlockState(); - } - - @Override - public BlockState getWall(BlockPos pos) { - double depth = DEPTH_NOISE.eval(pos.getX() * 0.02, pos.getZ() * 0.02) * 0.2 + 0.5; - int index = Mth.floor((pos.getY() + WALL_NOISE.eval(pos.getX() * 0.2, pos.getZ() * 0.2) * 1.5) * depth + 0.5); - index = Mth.abs(index) % 3; - return JADE[index]; - } -} diff --git a/src/main/java/ru/betterend/world/biome/cave/LushAuroraCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/LushAuroraCaveBiome.java deleted file mode 100644 index 0ac0206e..00000000 --- a/src/main/java/ru/betterend/world/biome/cave/LushAuroraCaveBiome.java +++ /dev/null @@ -1,48 +0,0 @@ -package ru.betterend.world.biome.cave; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndParticles; - -public class LushAuroraCaveBiome extends EndCaveBiome { - public LushAuroraCaveBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("lush_aurora_cave")) - .setFogColor(150, 30, 68) - .setFogDensity(2.0F) - .setPlantsColor(108, 25, 46) - .setWaterAndFogColor(186, 77, 237) - .setParticles(EndParticles.GLOWING_SPHERE, 0.001F) - .setSurface(EndBlocks.CAVE_MOSS)); - - this.addFloorFeature(EndFeatures.BIG_AURORA_CRYSTAL, 1); - this.addFloorFeature(EndFeatures.CAVE_BUSH, 5); - this.addFloorFeature(EndFeatures.CAVE_GRASS, 40); - this.addFloorFeature(EndFeatures.END_STONE_STALAGMITE_CAVEMOSS, 5); - - this.addCeilFeature(EndFeatures.CAVE_BUSH, 1); - this.addCeilFeature(EndFeatures.CAVE_PUMPKIN, 1); - this.addCeilFeature(EndFeatures.RUBINEA, 3); - this.addCeilFeature(EndFeatures.MAGNULA, 1); - this.addCeilFeature(EndFeatures.END_STONE_STALACTITE_CAVEMOSS, 10); - } - - @Override - public float getFloorDensity() { - return 0.2F; - } - - @Override - public float getCeilDensity() { - return 0.1F; - } - - @Override - public BlockState getCeil(BlockPos pos) { - return EndBlocks.CAVE_MOSS.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, BlockProperties.TripleShape.TOP); - } -} diff --git a/src/main/java/ru/betterend/world/biome/cave/LushSmaragdantCaveBiome.java b/src/main/java/ru/betterend/world/biome/cave/LushSmaragdantCaveBiome.java deleted file mode 100644 index 814ad4a6..00000000 --- a/src/main/java/ru/betterend/world/biome/cave/LushSmaragdantCaveBiome.java +++ /dev/null @@ -1,34 +0,0 @@ -package ru.betterend.world.biome.cave; - -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndParticles; - -public class LushSmaragdantCaveBiome extends EndCaveBiome { - public LushSmaragdantCaveBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("lush_smaragdant_cave")) - .setFogColor(0, 253, 182) - .setFogDensity(2.0F) - .setPlantsColor(0, 131, 145) - .setWaterAndFogColor(31, 167, 212) - .setParticles(EndParticles.SMARAGDANT, 0.001F) - .setSurface(EndBlocks.CAVE_MOSS)); - - this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL, 1); - this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL_SHARD, 20); - - this.addCeilFeature(EndFeatures.END_STONE_STALACTITE, 1); - } - - @Override - public float getFloorDensity() { - return 0.1F; - } - - @Override - public float getCeilDensity() { - return 0.1F; - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/AmberLandBiome.java b/src/main/java/ru/betterend/world/biome/land/AmberLandBiome.java deleted file mode 100644 index 63032057..00000000 --- a/src/main/java/ru/betterend/world/biome/land/AmberLandBiome.java +++ /dev/null @@ -1,39 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.data.worldgen.StructureFeatures; -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndEntities; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndSounds; -import ru.betterend.world.biome.EndBiome; - -public class AmberLandBiome extends EndBiome { - public AmberLandBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("amber_land")) - .setFogColor(255, 184, 71) - .setFogDensity(2.0F) - .setPlantsColor(219, 115, 38) - .setWaterAndFogColor(145, 108, 72) - .setMusic(EndSounds.MUSIC_FOREST) - .setParticles(EndParticles.AMBER_SPHERE, 0.001F) - .setSurface(EndBlocks.AMBER_MOSS) - .addFeature(EndFeatures.AMBER_ORE) - .addFeature(EndFeatures.END_LAKE_RARE) - .addFeature(EndFeatures.HELIX_TREE) - .addFeature(EndFeatures.LANCELEAF) - .addFeature(EndFeatures.GLOW_PILLAR) - .addFeature(EndFeatures.AMBER_GRASS) - .addFeature(EndFeatures.AMBER_ROOT) - .addFeature(EndFeatures.BULB_MOSS) - .addFeature(EndFeatures.BULB_MOSS_WOOD) - .addFeature(EndFeatures.CHARNIA_ORANGE) - .addFeature(EndFeatures.CHARNIA_RED) - .addStructureFeature(StructureFeatures.END_CITY) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 4) - .addMobSpawn(EndEntities.END_SLIME, 30, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/BlossomingSpiresBiome.java b/src/main/java/ru/betterend/world/biome/land/BlossomingSpiresBiome.java deleted file mode 100644 index 46e0c3a8..00000000 --- a/src/main/java/ru/betterend/world/biome/land/BlossomingSpiresBiome.java +++ /dev/null @@ -1,36 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndEntities; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndSounds; -import ru.betterend.world.biome.EndBiome; - -public class BlossomingSpiresBiome extends EndBiome { - public BlossomingSpiresBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("blossoming_spires")) - .addCustomData("has_caves", false) - .setFogColor(241, 146, 229) - .setFogDensity(1.7F) - .setPlantsColor(122, 45, 122) - .setSurface(EndBlocks.PINK_MOSS) - .setMusic(EndSounds.MUSIC_FOREST) - .setLoop(EndSounds.AMBIENT_BLOSSOMING_SPIRES) - .addFeature(EndFeatures.SPIRE) - .addFeature(EndFeatures.FLOATING_SPIRE) - .addFeature(EndFeatures.TENANEA) - .addFeature(EndFeatures.TENANEA_BUSH) - .addFeature(EndFeatures.BULB_VINE) - .addFeature(EndFeatures.BUSHY_GRASS) - .addFeature(EndFeatures.BUSHY_GRASS_WG) - .addFeature(EndFeatures.BLOSSOM_BERRY) - .addFeature(EndFeatures.TWISTED_MOSS) - .addFeature(EndFeatures.TWISTED_MOSS_WOOD) - .addFeature(EndFeatures.SILK_MOTH_NEST) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 4) - .addMobSpawn(EndEntities.SILK_MOTH, 5, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/ChorusForestBiome.java b/src/main/java/ru/betterend/world/biome/land/ChorusForestBiome.java deleted file mode 100644 index 5a2024cc..00000000 --- a/src/main/java/ru/betterend/world/biome/land/ChorusForestBiome.java +++ /dev/null @@ -1,44 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.data.worldgen.Features; -import net.minecraft.data.worldgen.StructureFeatures; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.levelgen.GenerationStep.Decoration; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndEntities; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndSounds; -import ru.betterend.world.biome.EndBiome; - -public class ChorusForestBiome extends EndBiome { - public ChorusForestBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("chorus_forest")) - .setFogColor(87, 26, 87) - .setFogDensity(1.5F) - .setPlantsColor(122, 45, 122) - .setWaterAndFogColor(73, 30, 73) - .setSurface(EndBlocks.CHORUS_NYLIUM) - .setParticles(ParticleTypes.PORTAL, 0.01F) - .setLoop(EndSounds.AMBIENT_CHORUS_FOREST) - .setMusic(EndSounds.MUSIC_DARK) - .addFeature(EndFeatures.VIOLECITE_LAYER) - .addFeature(EndFeatures.END_LAKE_RARE) - .addFeature(EndFeatures.PYTHADENDRON_TREE) - .addFeature(EndFeatures.PYTHADENDRON_BUSH) - .addFeature(EndFeatures.PURPLE_POLYPORE) - .addFeature(Decoration.VEGETAL_DECORATION, Features.CHORUS_PLANT) - .addFeature(Decoration.VEGETAL_DECORATION, Features.CHORUS_PLANT) - .addFeature(EndFeatures.CHORUS_GRASS) - .addFeature(EndFeatures.CHORUS_MUSHROOM) - .addFeature(EndFeatures.TAIL_MOSS) - .addFeature(EndFeatures.TAIL_MOSS_WOOD) - .addFeature(EndFeatures.CHARNIA_PURPLE) - .addFeature(EndFeatures.CHARNIA_RED_RARE) - .addStructureFeature(StructureFeatures.END_CITY) - .addMobSpawn(EndEntities.END_SLIME, 5, 1, 2) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 4)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/CrystalMountainsBiome.java b/src/main/java/ru/betterend/world/biome/land/CrystalMountainsBiome.java deleted file mode 100644 index bbdbfc9e..00000000 --- a/src/main/java/ru/betterend/world/biome/land/CrystalMountainsBiome.java +++ /dev/null @@ -1,23 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndSounds; -import ru.betterend.registry.EndStructures; -import ru.betterend.world.biome.EndBiome; - -public class CrystalMountainsBiome extends EndBiome { - public CrystalMountainsBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("crystal_mountains")) - .addStructureFeature(EndStructures.MOUNTAIN.getFeatureConfigured()) - .setPlantsColor(255, 133, 211) - .setSurface(EndBlocks.CRYSTAL_MOSS) - .setMusic(EndSounds.MUSIC_OPENSPACE) - .addFeature(EndFeatures.ROUND_CAVE) - .addFeature(EndFeatures.CRYSTAL_GRASS) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/DragonGraveyardsBiome.java b/src/main/java/ru/betterend/world/biome/land/DragonGraveyardsBiome.java deleted file mode 100644 index 57e1fc00..00000000 --- a/src/main/java/ru/betterend/world/biome/land/DragonGraveyardsBiome.java +++ /dev/null @@ -1,34 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndSounds; -import ru.betterend.world.biome.EndBiome; - -public class DragonGraveyardsBiome extends EndBiome { - public DragonGraveyardsBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("dragon_graveyards")) - .setGenChance(0.1F) - .setFogColor(244, 46, 79) - .setFogDensity(1.3F) - .setParticles(EndParticles.FIREFLY, 0.0007F) - .setMusic(EndSounds.MUSIC_OPENSPACE) - .setLoop(EndSounds.AMBIENT_GLOWING_GRASSLANDS) - .setSurface(EndBlocks.SANGNUM) - .setWaterAndFogColor(203, 59, 167) - .setPlantsColor(244, 46, 79) - .addFeature(EndFeatures.OBSIDIAN_PILLAR_BASEMENT) - .addFeature(EndFeatures.FALLEN_PILLAR) - .addFeature(EndFeatures.OBSIDIAN_BOULDER) - .addFeature(EndFeatures.GIGANTIC_AMARANITA) - .addFeature(EndFeatures.LARGE_AMARANITA) - .addFeature(EndFeatures.SMALL_AMARANITA) - .addFeature(EndFeatures.GLOBULAGUS) - .addFeature(EndFeatures.CLAWFERN) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/DryShrublandBiome.java b/src/main/java/ru/betterend/world/biome/land/DryShrublandBiome.java deleted file mode 100644 index 6d78ad1a..00000000 --- a/src/main/java/ru/betterend/world/biome/land/DryShrublandBiome.java +++ /dev/null @@ -1,29 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.data.worldgen.StructureFeatures; -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndSounds; -import ru.betterend.world.biome.EndBiome; - -public class DryShrublandBiome extends EndBiome { - public DryShrublandBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("dry_shrubland")) - .setFogColor(132, 35, 13) - .setFogDensity(1.2F) - .setWaterAndFogColor(113, 88, 53) - .setPlantsColor(237, 122, 66) - .setSurface(EndBlocks.RUTISCUS) - .setMusic(EndSounds.MUSIC_OPENSPACE) - .addFeature(EndFeatures.LUCERNIA_BUSH_RARE) - .addFeature(EndFeatures.ORANGO) - .addFeature(EndFeatures.AERIDIUM) - .addFeature(EndFeatures.LUTEBUS) - .addFeature(EndFeatures.LAMELLARIUM) - .addStructureFeature(StructureFeatures.END_CITY) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/DustWastelandsBiome.java b/src/main/java/ru/betterend/world/biome/land/DustWastelandsBiome.java deleted file mode 100644 index e13be0f7..00000000 --- a/src/main/java/ru/betterend/world/biome/land/DustWastelandsBiome.java +++ /dev/null @@ -1,26 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.data.worldgen.StructureFeatures; -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndSounds; -import ru.betterend.world.biome.EndBiome; - -public class DustWastelandsBiome extends EndBiome { - public DustWastelandsBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("dust_wastelands")) - .setFogColor(226, 239, 168) - .setFogDensity(2) - .setWaterAndFogColor(192, 180, 131) - .setSurface(EndBlocks.ENDSTONE_DUST) - .setDepth(1.5F) - .setParticles(ParticleTypes.WHITE_ASH, 0.01F) - .setLoop(EndSounds.AMBIENT_DUST_WASTELANDS) - .setMusic(EndSounds.MUSIC_OPENSPACE) - .addStructureFeature(StructureFeatures.END_CITY) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/FoggyMushroomlandBiome.java b/src/main/java/ru/betterend/world/biome/land/FoggyMushroomlandBiome.java deleted file mode 100644 index 3896e6a6..00000000 --- a/src/main/java/ru/betterend/world/biome/land/FoggyMushroomlandBiome.java +++ /dev/null @@ -1,48 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.data.worldgen.StructureFeatures; -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndEntities; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndSounds; -import ru.betterend.registry.EndStructures; -import ru.betterend.world.biome.EndBiome; - -public class FoggyMushroomlandBiome extends EndBiome { - public FoggyMushroomlandBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("foggy_mushroomland")) - .addStructureFeature(EndStructures.GIANT_MOSSY_GLOWSHROOM.getFeatureConfigured()) - .setPlantsColor(73, 210, 209) - .setFogColor(41, 122, 173) - .setFogDensity(3) - .setWaterAndFogColor(119, 227, 250) - .setSurface(EndBlocks.END_MOSS, EndBlocks.END_MYCELIUM) - .setParticles(EndParticles.GLOWING_SPHERE, 0.001F) - .setLoop(EndSounds.AMBIENT_FOGGY_MUSHROOMLAND) - .setMusic(EndSounds.MUSIC_FOREST) - .addFeature(EndFeatures.END_LAKE) - .addFeature(EndFeatures.MOSSY_GLOWSHROOM) - .addFeature(EndFeatures.BLUE_VINE) - .addFeature(EndFeatures.UMBRELLA_MOSS) - .addFeature(EndFeatures.CREEPING_MOSS) - .addFeature(EndFeatures.DENSE_VINE) - //.addFeature(EndFeatures.PEARLBERRY) - .addFeature(EndFeatures.CYAN_MOSS) - .addFeature(EndFeatures.CYAN_MOSS_WOOD) - .addFeature(EndFeatures.END_LILY) - .addFeature(EndFeatures.BUBBLE_CORAL) - .addFeature(EndFeatures.CHARNIA_CYAN) - .addFeature(EndFeatures.CHARNIA_LIGHT_BLUE) - .addFeature(EndFeatures.CHARNIA_RED_RARE) - .addStructureFeature(StructureFeatures.END_CITY) - .addMobSpawn(EndEntities.DRAGONFLY, 80, 2, 5) - .addMobSpawn(EndEntities.END_FISH, 20, 2, 5) - .addMobSpawn(EndEntities.CUBOZOA, 10, 3, 8) - .addMobSpawn(EndEntities.END_SLIME, 10, 1, 2) - .addMobSpawn(EntityType.ENDERMAN, 10, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/GlowingGrasslandsBiome.java b/src/main/java/ru/betterend/world/biome/land/GlowingGrasslandsBiome.java deleted file mode 100644 index 5435e994..00000000 --- a/src/main/java/ru/betterend/world/biome/land/GlowingGrasslandsBiome.java +++ /dev/null @@ -1,40 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.data.worldgen.StructureFeatures; -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndSounds; -import ru.betterend.world.biome.EndBiome; - -public class GlowingGrasslandsBiome extends EndBiome { - public GlowingGrasslandsBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("glowing_grasslands")) - .setFogColor(99, 228, 247) - .setFogDensity(1.3F) - .setParticles(EndParticles.FIREFLY, 0.001F) - .setMusic(EndSounds.MUSIC_OPENSPACE) - .setLoop(EndSounds.AMBIENT_GLOWING_GRASSLANDS) - .setSurface(EndBlocks.END_MOSS) - .setWaterAndFogColor(92, 250, 230) - .setPlantsColor(73, 210, 209) - .addFeature(EndFeatures.END_LAKE_RARE) - .addFeature(EndFeatures.LUMECORN) - .addFeature(EndFeatures.BLOOMING_COOKSONIA) - .addFeature(EndFeatures.SALTEAGO) - .addFeature(EndFeatures.VAIOLUSH_FERN) - .addFeature(EndFeatures.FRACTURN) - .addFeature(EndFeatures.UMBRELLA_MOSS_RARE) - .addFeature(EndFeatures.CREEPING_MOSS_RARE) - .addFeature(EndFeatures.TWISTED_UMBRELLA_MOSS_RARE) - .addFeature(EndFeatures.CHARNIA_CYAN) - .addFeature(EndFeatures.CHARNIA_GREEN) - .addFeature(EndFeatures.CHARNIA_LIGHT_BLUE) - .addFeature(EndFeatures.CHARNIA_RED_RARE) - .addStructureFeature(StructureFeatures.END_CITY) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/LanternWoodsBiome.java b/src/main/java/ru/betterend/world/biome/land/LanternWoodsBiome.java deleted file mode 100644 index a7954a63..00000000 --- a/src/main/java/ru/betterend/world/biome/land/LanternWoodsBiome.java +++ /dev/null @@ -1,40 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.data.worldgen.StructureFeatures; -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndSounds; -import ru.betterend.world.biome.EndBiome; - -public class LanternWoodsBiome extends EndBiome { - public LanternWoodsBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("lantern_woods")) - .setFogColor(189, 82, 70) - .setFogDensity(1.1F) - .setWaterAndFogColor(171, 234, 226) - .setPlantsColor(254, 85, 57) - .setSurface(EndBlocks.RUTISCUS) - .setMusic(EndSounds.MUSIC_FOREST) - .setParticles(EndParticles.GLOWING_SPHERE, 0.001F) - .addFeature(EndFeatures.END_LAKE_NORMAL) - .addFeature(EndFeatures.FLAMAEA) - .addFeature(EndFeatures.LUCERNIA) - .addFeature(EndFeatures.LUCERNIA_BUSH) - .addFeature(EndFeatures.FILALUX) - .addFeature(EndFeatures.AERIDIUM) - .addFeature(EndFeatures.LAMELLARIUM) - .addFeature(EndFeatures.BOLUX_MUSHROOM) - .addFeature(EndFeatures.AURANT_POLYPORE) - .addFeature(EndFeatures.POND_ANEMONE) - .addFeature(EndFeatures.CHARNIA_ORANGE) - .addFeature(EndFeatures.CHARNIA_RED) - .addFeature(EndFeatures.RUSCUS) - .addFeature(EndFeatures.RUSCUS_WOOD) - .addStructureFeature(StructureFeatures.END_CITY) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/MegalakeBiome.java b/src/main/java/ru/betterend/world/biome/land/MegalakeBiome.java deleted file mode 100644 index 7a42bccd..00000000 --- a/src/main/java/ru/betterend/world/biome/land/MegalakeBiome.java +++ /dev/null @@ -1,42 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndEntities; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndSounds; -import ru.betterend.registry.EndStructures; -import ru.betterend.world.biome.EndBiome; - -public class MegalakeBiome extends EndBiome { - public MegalakeBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("megalake")) - .addStructureFeature(EndStructures.MEGALAKE.getFeatureConfigured()) - .setPlantsColor(73, 210, 209) - .setFogColor(178, 209, 248) - .setWaterAndFogColor(96, 163, 255) - .setFogDensity(1.75F) - .setMusic(EndSounds.MUSIC_WATER) - .setLoop(EndSounds.AMBIENT_MEGALAKE) - .setSurface(EndBlocks.END_MOSS, EndBlocks.ENDSTONE_DUST) - .setDepth(0F) - .addFeature(EndFeatures.END_LOTUS) - .addFeature(EndFeatures.END_LOTUS_LEAF) - .addFeature(EndFeatures.BUBBLE_CORAL_RARE) - .addFeature(EndFeatures.END_LILY_RARE) - .addFeature(EndFeatures.UMBRELLA_MOSS) - .addFeature(EndFeatures.CREEPING_MOSS) - //.addFeature(EndFeatures.PEARLBERRY) - .addFeature(EndFeatures.CHARNIA_CYAN) - .addFeature(EndFeatures.CHARNIA_LIGHT_BLUE) - .addFeature(EndFeatures.CHARNIA_RED_RARE) - .addFeature(EndFeatures.MENGER_SPONGE) - .addMobSpawn(EndEntities.DRAGONFLY, 50, 1, 3) - .addMobSpawn(EndEntities.END_FISH, 50, 3, 8) - .addMobSpawn(EndEntities.CUBOZOA, 50, 3, 8) - .addMobSpawn(EndEntities.END_SLIME, 5, 1, 2) - .addMobSpawn(EntityType.ENDERMAN, 10, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/MegalakeGroveBiome.java b/src/main/java/ru/betterend/world/biome/land/MegalakeGroveBiome.java deleted file mode 100644 index a5e16704..00000000 --- a/src/main/java/ru/betterend/world/biome/land/MegalakeGroveBiome.java +++ /dev/null @@ -1,45 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndEntities; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndSounds; -import ru.betterend.registry.EndStructures; -import ru.betterend.world.biome.EndBiome; - -public class MegalakeGroveBiome extends EndBiome { - public MegalakeGroveBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("megalake_grove")) - .addStructureFeature(EndStructures.MEGALAKE_SMALL.getFeatureConfigured()) - .setPlantsColor(73, 210, 209) - .setFogColor(178, 209, 248) - .setWaterAndFogColor(96, 163, 255) - .setFogDensity(2.0F) - .setParticles(EndParticles.GLOWING_SPHERE, 0.001F) - .setMusic(EndSounds.MUSIC_WATER) - .setLoop(EndSounds.AMBIENT_MEGALAKE_GROVE) - .setSurface(EndBlocks.END_MOSS) - .setDepth(0F) - .addFeature(EndFeatures.LACUGROVE) - .addFeature(EndFeatures.END_LOTUS) - .addFeature(EndFeatures.END_LOTUS_LEAF) - .addFeature(EndFeatures.BUBBLE_CORAL_RARE) - .addFeature(EndFeatures.END_LILY_RARE) - .addFeature(EndFeatures.UMBRELLA_MOSS) - //.addFeature(EndFeatures.PEARLBERRY) - .addFeature(EndFeatures.CREEPING_MOSS) - .addFeature(EndFeatures.CHARNIA_CYAN) - .addFeature(EndFeatures.CHARNIA_LIGHT_BLUE) - .addFeature(EndFeatures.CHARNIA_RED_RARE) - .addFeature(EndFeatures.MENGER_SPONGE) - .addMobSpawn(EndEntities.DRAGONFLY, 20, 1, 3) - .addMobSpawn(EndEntities.END_FISH, 20, 3, 8) - .addMobSpawn(EndEntities.CUBOZOA, 50, 3, 8) - .addMobSpawn(EndEntities.END_SLIME, 5, 1, 2) - .addMobSpawn(EntityType.ENDERMAN, 10, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/NeonOasisBiome.java b/src/main/java/ru/betterend/world/biome/land/NeonOasisBiome.java deleted file mode 100644 index 3d2619b1..00000000 --- a/src/main/java/ru/betterend/world/biome/land/NeonOasisBiome.java +++ /dev/null @@ -1,34 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.data.worldgen.StructureFeatures; -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndSounds; -import ru.betterend.world.biome.EndBiome; - -public class NeonOasisBiome extends EndBiome { - public NeonOasisBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("neon_oasis")) - .setGenChance(0.5F) - .setFogColor(226, 239, 168) - .setFogDensity(2) - .setWaterAndFogColor(106, 238, 215) - .setSurface(EndBlocks.ENDSTONE_DUST, EndBlocks.END_MOSS) - .setParticles(ParticleTypes.WHITE_ASH, 0.01F) - .setLoop(EndSounds.AMBIENT_DUST_WASTELANDS) - .setMusic(EndSounds.MUSIC_OPENSPACE) - .addFeature(EndFeatures.DESERT_LAKE) - .addFeature(EndFeatures.NEON_CACTUS) - .addFeature(EndFeatures.UMBRELLA_MOSS) - .addFeature(EndFeatures.CREEPING_MOSS) - .addFeature(EndFeatures.CHARNIA_GREEN) - .addFeature(EndFeatures.CHARNIA_CYAN) - .addFeature(EndFeatures.CHARNIA_RED) - .addStructureFeature(StructureFeatures.END_CITY) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/PaintedMountainsBiome.java b/src/main/java/ru/betterend/world/biome/land/PaintedMountainsBiome.java deleted file mode 100644 index 8bf6fbbc..00000000 --- a/src/main/java/ru/betterend/world/biome/land/PaintedMountainsBiome.java +++ /dev/null @@ -1,25 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndSounds; -import ru.betterend.registry.EndStructures; -import ru.betterend.world.biome.EndBiome; - -public class PaintedMountainsBiome extends EndBiome { - public PaintedMountainsBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("painted_mountains")) - .addStructureFeature(EndStructures.PAINTED_MOUNTAIN.getFeatureConfigured()) - .setFogColor(226, 239, 168) - .setFogDensity(2) - .setWaterAndFogColor(192, 180, 131) - .setMusic(EndSounds.MUSIC_OPENSPACE) - .setLoop(EndSounds.AMBIENT_DUST_WASTELANDS) - .setSurface(EndBlocks.ENDSTONE_DUST) - .setParticles(ParticleTypes.WHITE_ASH, 0.01F) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/ShadowForestBiome.java b/src/main/java/ru/betterend/world/biome/land/ShadowForestBiome.java deleted file mode 100644 index a3bde81b..00000000 --- a/src/main/java/ru/betterend/world/biome/land/ShadowForestBiome.java +++ /dev/null @@ -1,44 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.data.worldgen.StructureFeatures; -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndEntities; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndSounds; -import ru.betterend.world.biome.EndBiome; - -public class ShadowForestBiome extends EndBiome { - public ShadowForestBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("shadow_forest")) - .setFogColor(0, 0, 0) - .setFogDensity(2.5F) - .setPlantsColor(45, 45, 45) - .setWaterAndFogColor(42, 45, 80) - .setSurface(EndBlocks.SHADOW_GRASS) - .setParticles(ParticleTypes.MYCELIUM, 0.01F) - .setLoop(EndSounds.AMBIENT_CHORUS_FOREST) - .setMusic(EndSounds.MUSIC_DARK) - .addFeature(EndFeatures.VIOLECITE_LAYER) - .addFeature(EndFeatures.END_LAKE_RARE) - .addFeature(EndFeatures.DRAGON_TREE) - .addFeature(EndFeatures.DRAGON_TREE_BUSH) - .addFeature(EndFeatures.SHADOW_PLANT) - .addFeature(EndFeatures.MURKWEED) - .addFeature(EndFeatures.NEEDLEGRASS) - .addFeature(EndFeatures.SHADOW_BERRY) - .addFeature(EndFeatures.TWISTED_VINE) - .addFeature(EndFeatures.PURPLE_POLYPORE) - .addFeature(EndFeatures.TAIL_MOSS) - .addFeature(EndFeatures.TAIL_MOSS_WOOD) - .addFeature(EndFeatures.CHARNIA_PURPLE) - .addFeature(EndFeatures.CHARNIA_RED_RARE) - .addStructureFeature(StructureFeatures.END_CITY) - .addMobSpawn(EndEntities.SHADOW_WALKER, 80, 2, 4) - .addMobSpawn(EntityType.ENDERMAN, 40, 1, 4) - .addMobSpawn(EntityType.PHANTOM, 1, 1, 2)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/SulphurSpringsBiome.java b/src/main/java/ru/betterend/world/biome/land/SulphurSpringsBiome.java deleted file mode 100644 index 8caad6f7..00000000 --- a/src/main/java/ru/betterend/world/biome/land/SulphurSpringsBiome.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndEntities; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndSounds; -import ru.betterend.world.biome.EndBiome; -import ru.betterend.world.surface.SurfaceBuilders; - -public class SulphurSpringsBiome extends EndBiome { - public SulphurSpringsBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("sulphur_springs")) - .addCustomData("has_caves", false) - .setSurface(SurfaceBuilders.SULPHURIC_SURFACE.configured(SurfaceBuilders.DEFAULT_END_CONFIG)) - .setMusic(EndSounds.MUSIC_OPENSPACE) - .setLoop(EndSounds.AMBIENT_SULPHUR_SPRINGS) - .setWaterColor(25, 90, 157) - .setWaterFogColor(30, 65, 61) - .setFogColor(207, 194, 62) - .setFogDensity(1.5F) - .setDepth(0F) - .setParticles(EndParticles.SULPHUR_PARTICLE, 0.001F) - .addFeature(EndFeatures.GEYSER) - .addFeature(EndFeatures.SURFACE_VENT) - .addFeature(EndFeatures.SULPHURIC_LAKE) - .addFeature(EndFeatures.SULPHURIC_CAVE) - .addFeature(EndFeatures.HYDRALUX) - .addFeature(EndFeatures.CHARNIA_GREEN) - .addFeature(EndFeatures.CHARNIA_ORANGE) - .addFeature(EndFeatures.CHARNIA_RED_RARE) - .addMobSpawn(EndEntities.END_FISH, 50, 3, 8) - .addMobSpawn(EndEntities.CUBOZOA, 50, 3, 8) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 4)); - } -} diff --git a/src/main/java/ru/betterend/world/biome/land/UmbrellaJungleBiome.java b/src/main/java/ru/betterend/world/biome/land/UmbrellaJungleBiome.java deleted file mode 100644 index dacda618..00000000 --- a/src/main/java/ru/betterend/world/biome/land/UmbrellaJungleBiome.java +++ /dev/null @@ -1,44 +0,0 @@ -package ru.betterend.world.biome.land; - -import net.minecraft.data.worldgen.StructureFeatures; -import net.minecraft.world.entity.EntityType; -import ru.bclib.world.biomes.BCLBiomeDef; -import ru.betterend.BetterEnd; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; -import ru.betterend.registry.EndParticles; -import ru.betterend.registry.EndSounds; -import ru.betterend.world.biome.EndBiome; - -public class UmbrellaJungleBiome extends EndBiome { - public UmbrellaJungleBiome() { - super(new BCLBiomeDef(BetterEnd.makeID("umbrella_jungle")) - .setFogColor(87, 223, 221) - .setWaterAndFogColor(119, 198, 253) - .setFoliageColor(27, 183, 194) - .setFogDensity(2.3F) - .setParticles(EndParticles.JUNGLE_SPORE, 0.001F) - .setMusic(EndSounds.MUSIC_FOREST) - .setLoop(EndSounds.AMBIENT_UMBRELLA_JUNGLE) - .setSurface(EndBlocks.JUNGLE_MOSS) - .addFeature(EndFeatures.END_LAKE) - .addFeature(EndFeatures.UMBRELLA_TREE) - .addFeature(EndFeatures.JELLYSHROOM) - .addFeature(EndFeatures.TWISTED_UMBRELLA_MOSS) - .addFeature(EndFeatures.SMALL_JELLYSHROOM_FLOOR) - .addFeature(EndFeatures.JUNGLE_GRASS) - .addFeature(EndFeatures.CYAN_MOSS) - .addFeature(EndFeatures.CYAN_MOSS_WOOD) - .addFeature(EndFeatures.JUNGLE_FERN_WOOD) - .addFeature(EndFeatures.SMALL_JELLYSHROOM_WALL) - .addFeature(EndFeatures.SMALL_JELLYSHROOM_WOOD) - .addFeature(EndFeatures.SMALL_JELLYSHROOM_CEIL) - .addFeature(EndFeatures.JUNGLE_VINE) - .addFeature(EndFeatures.CHARNIA_CYAN) - .addFeature(EndFeatures.CHARNIA_GREEN) - .addFeature(EndFeatures.CHARNIA_LIGHT_BLUE) - .addFeature(EndFeatures.CHARNIA_RED_RARE) - .addStructureFeature(StructureFeatures.END_CITY) - .addMobSpawn(EntityType.ENDERMAN, 50, 1, 2)); - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/world/features/BiomeIslandFeature.java b/src/main/java/ru/betterend/world/features/BiomeIslandFeature.java deleted file mode 100644 index b58474a3..00000000 --- a/src/main/java/ru/betterend/world/features/BiomeIslandFeature.java +++ /dev/null @@ -1,73 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilderBaseConfiguration; -import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilderConfiguration; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFCappedCone; -import ru.bclib.util.BlocksHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; - -public class BiomeIslandFeature extends DefaultFeature { - private static final MutableBlockPos CENTER = new MutableBlockPos(); - private static final SDF ISLAND; - - private static OpenSimplexNoise simplexNoise = new OpenSimplexNoise(412L); - private static BlockState topBlock = Blocks.GRASS_BLOCK.defaultBlockState(); - private static BlockState underBlock = Blocks.DIRT.defaultBlockState(); - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - Biome biome = world.getBiome(pos); - SurfaceBuilderConfiguration surfaceConfig = biome.getGenerationSettings().getSurfaceBuilderConfig(); - BlockState topMaterial = surfaceConfig.getTopMaterial(); - if (BlocksHelper.isFluid(topMaterial)) { - topBlock = ((SurfaceBuilderBaseConfiguration) surfaceConfig).getUnderwaterMaterial(); - } else { - topBlock = topMaterial; - } - underBlock = surfaceConfig.getUnderMaterial(); - simplexNoise = new OpenSimplexNoise(world.getSeed()); - CENTER.set(pos); - ISLAND.fillRecursive(world, pos.below()); - return true; - } - - private static SDF createSDFIsland() { - SDF sdfCone = new SDFCappedCone().setRadius1(0).setRadius2(6).setHeight(4).setBlock(pos -> { - if (pos.getY() > CENTER.getY()) - return AIR; - if (pos.getY() == CENTER.getY()) - return topBlock; - return underBlock; - }); - sdfCone = new SDFTranslate().setTranslate(0, -2, 0).setSource(sdfCone); - sdfCone = new SDFDisplacement().setFunction(pos -> { - float deltaX = Math.abs(pos.x()); - float deltaY = Math.abs(pos.y()); - float deltaZ = Math.abs(pos.z()); - if (deltaY < 2.0f && (deltaX < 3.0f || deltaZ < 3.0F)) - return 0.0f; - return (float) simplexNoise.eval(CENTER.getX() + pos.x(), CENTER.getY() + pos.y(), CENTER.getZ() + pos.z()); - }).setSource(sdfCone) - .setReplaceFunction(state -> BlocksHelper.isFluid(state) || state.getMaterial().isReplaceable()); - return sdfCone; - } - - static { - ISLAND = createSDFIsland(); - } -} diff --git a/src/main/java/ru/betterend/world/features/BlueVineFeature.java b/src/main/java/ru/betterend/world/features/BlueVineFeature.java deleted file mode 100644 index 568424a5..00000000 --- a/src/main/java/ru/betterend/world/features/BlueVineFeature.java +++ /dev/null @@ -1,36 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.blocks.basis.EndPlantWithAgeBlock; -import ru.betterend.registry.EndBlocks; - -public class BlueVineFeature extends ScatterFeature { - private boolean small; - - public BlueVineFeature() { - super(5); - } - - @Override - public boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, float radius) { - float d = MHelper.length(center.getX() - blockPos.getX(), center.getZ() - blockPos.getZ()) / radius * 0.6F + random.nextFloat() * 0.4F; - small = d > 0.5F; - return EndBlocks.BLUE_VINE_SEED.canSurvive(AIR, world, blockPos); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - if (small) { - BlocksHelper.setWithoutUpdate(world, blockPos, EndBlocks.BLUE_VINE_SEED.defaultBlockState().setValue(EndPlantWithAgeBlock.AGE, random.nextInt(4))); - } - else { - EndPlantWithAgeBlock seed = ((EndPlantWithAgeBlock) EndBlocks.BLUE_VINE_SEED); - seed.growAdult(world, random, blockPos); - } - } -} diff --git a/src/main/java/ru/betterend/world/features/CavePumpkinFeature.java b/src/main/java/ru/betterend/world/features/CavePumpkinFeature.java deleted file mode 100644 index 839f6120..00000000 --- a/src/main/java/ru/betterend/world/features/CavePumpkinFeature.java +++ /dev/null @@ -1,34 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.EndBlockProperties; -import ru.betterend.registry.EndBlocks; - -public class CavePumpkinFeature extends DefaultFeature { - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.above()).is(TagAPI.GEN_TERRAIN) || !world.isEmptyBlock(pos) - || !world.isEmptyBlock(pos.below())) { - return false; - } - - int age = random.nextInt(4); - BlocksHelper.setWithoutUpdate(world, pos, - EndBlocks.CAVE_PUMPKIN_SEED.defaultBlockState().setValue(EndBlockProperties.AGE, age)); - if (age > 1) { - BlocksHelper.setWithoutUpdate(world, pos.below(), - EndBlocks.CAVE_PUMPKIN.defaultBlockState().setValue(EndBlockProperties.SMALL, age < 3)); - } - - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/CharniaFeature.java b/src/main/java/ru/betterend/world/features/CharniaFeature.java deleted file mode 100644 index c8022a39..00000000 --- a/src/main/java/ru/betterend/world/features/CharniaFeature.java +++ /dev/null @@ -1,14 +0,0 @@ -package ru.betterend.world.features; - -import net.minecraft.world.level.block.Block; - -public class CharniaFeature extends UnderwaterPlantFeature { - public CharniaFeature(Block plant) { - super(plant, 6); - } - - @Override - protected int getChance() { - return 3; - } -} diff --git a/src/main/java/ru/betterend/world/features/CrashedShipFeature.java b/src/main/java/ru/betterend/world/features/CrashedShipFeature.java deleted file mode 100644 index 4be8dfdd..00000000 --- a/src/main/java/ru/betterend/world/features/CrashedShipFeature.java +++ /dev/null @@ -1,132 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.templatesystem.BlockIgnoreProcessor; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorType; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.util.MHelper; -import ru.bclib.util.StructureHelper; -import ru.bclib.world.features.NBTStructureFeature; -import ru.betterend.util.BlockFixer; - -public class CrashedShipFeature extends NBTStructureFeature { - private static final StructureProcessor REPLACER; - private static final String STRUCTURE_PATH = "/data/minecraft/structures/end_city/ship.nbt"; - private StructureTemplate structure; - - @Override - protected StructureTemplate getStructure(WorldGenLevel world, BlockPos pos, Random random) { - if (structure == null) { - structure = world.getLevel().getStructureManager().getOrCreate(new ResourceLocation("end_city/ship")); - if (structure == null) { - structure = StructureHelper.readStructure(STRUCTURE_PATH); - } - } - return structure; - } - - @Override - protected boolean canSpawn(WorldGenLevel world, BlockPos pos, Random random) { - long x = pos.getX() >> 4; - long z = pos.getX() >> 4; - if (x * x + z * z < 3600) { - return false; - } - return pos.getY() > 5 && world.getBlockState(pos.below()).is(TagAPI.GEN_TERRAIN); - } - - @Override - protected Rotation getRotation(WorldGenLevel world, BlockPos pos, Random random) { - return Rotation.getRandom(random); - } - - @Override - protected Mirror getMirror(WorldGenLevel world, BlockPos pos, Random random) { - return Mirror.values()[random.nextInt(3)]; - } - - @Override - protected int getYOffset(StructureTemplate structure, WorldGenLevel world, BlockPos pos, Random random) { - int min = structure.getSize().getY() >> 3; - int max = structure.getSize().getY() >> 2; - return -MHelper.randRange(min, max, random); - } - - @Override - protected TerrainMerge getTerrainMerge(WorldGenLevel world, BlockPos pos, Random random) { - return TerrainMerge.NONE; - } - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos center, - NoneFeatureConfiguration featureConfig) { - center = new BlockPos(((center.getX() >> 4) << 4) | 8, 128, ((center.getZ() >> 4) << 4) | 8); - center = getGround(world, center); - BoundingBox bounds = makeBox(center); - - if (!canSpawn(world, center, random)) { - return false; - } - - StructureTemplate structure = getStructure(world, center, random); - Rotation rotation = getRotation(world, center, random); - Mirror mirror = getMirror(world, center, random); - BlockPos offset = StructureTemplate.transform(structure.getSize(), mirror, rotation, BlockPos.ZERO); - center = center.offset(0, getYOffset(structure, world, center, random) + 0.5, 0); - StructurePlaceSettings placementData = new StructurePlaceSettings().setRotation(rotation).setMirror(mirror); - center = center.offset(-offset.getX() * 0.5, 0, -offset.getZ() * 0.5); - - BoundingBox structB = structure.getBoundingBox(placementData, center); - bounds = StructureHelper.intersectBoxes(bounds, structB); - - addStructureData(placementData); - structure.placeInWorldChunk(world, center, placementData.setBoundingBox(bounds), random); - - StructureHelper.erodeIntense(world, bounds, random); - BlockFixer.fixBlocks(world, new BlockPos(bounds.x0, bounds.y0, bounds.z0), new BlockPos(bounds.x1, bounds.y1, bounds.z1)); - - return true; - } - - @Override - protected void addStructureData(StructurePlaceSettings data) { - data.addProcessor(BlockIgnoreProcessor.STRUCTURE_AND_AIR).addProcessor(REPLACER).setIgnoreEntities(true); - } - - static { - REPLACER = new StructureProcessor() { - @Override - public StructureBlockInfo processBlock(LevelReader worldView, BlockPos pos, BlockPos blockPos, - StructureBlockInfo structureBlockInfo, StructureBlockInfo structureBlockInfo2, - StructurePlaceSettings structurePlacementData) { - BlockState state = structureBlockInfo2.state; - if (state.is(Blocks.SPAWNER) || state.getMaterial().equals(Material.WOOL)) { - return new StructureBlockInfo(structureBlockInfo2.pos, AIR, null); - } - return structureBlockInfo2; - } - - @Override - protected StructureProcessorType getType() { - return StructureProcessorType.NOP; - } - }; - } -} diff --git a/src/main/java/ru/betterend/world/features/DoublePlantFeature.java b/src/main/java/ru/betterend/world/features/DoublePlantFeature.java deleted file mode 100644 index f98b1beb..00000000 --- a/src/main/java/ru/betterend/world/features/DoublePlantFeature.java +++ /dev/null @@ -1,43 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BaseDoublePlantBlock; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; - -public class DoublePlantFeature extends ScatterFeature { - private final Block smallPlant; - private final Block largePlant; - private Block plant; - - public DoublePlantFeature(Block smallPlant, Block largePlant, int radius) { - super(radius); - this.smallPlant = smallPlant; - this.largePlant = largePlant; - } - - @Override - public boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, float radius) { - float d = MHelper.length(center.getX() - blockPos.getX(), center.getZ() - blockPos.getZ()) / radius * 0.6F + random.nextFloat() * 0.4F; - plant = d < 0.5F ? largePlant : smallPlant; - return plant.canSurvive(plant.defaultBlockState(), world, blockPos); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - if (plant instanceof BaseDoublePlantBlock) { - int rot = random.nextInt(4); - BlockState state = plant.defaultBlockState().setValue(BaseDoublePlantBlock.ROTATION, rot); - BlocksHelper.setWithoutUpdate(world, blockPos, state); - BlocksHelper.setWithoutUpdate(world, blockPos.above(), state.setValue(BaseDoublePlantBlock.TOP, true)); - } - else { - BlocksHelper.setWithoutUpdate(world, blockPos, plant); - } - } -} diff --git a/src/main/java/ru/betterend/world/features/EndLilyFeature.java b/src/main/java/ru/betterend/world/features/EndLilyFeature.java deleted file mode 100644 index 4ecbd3cf..00000000 --- a/src/main/java/ru/betterend/world/features/EndLilyFeature.java +++ /dev/null @@ -1,25 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import ru.betterend.blocks.EndLilySeedBlock; -import ru.betterend.registry.EndBlocks; - -public class EndLilyFeature extends UnderwaterPlantScatter { - public EndLilyFeature(int radius) { - super(radius); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - EndLilySeedBlock seed = (EndLilySeedBlock) EndBlocks.END_LILY_SEED; - seed.grow(world, random, blockPos); - } - - @Override - protected int getChance() { - return 15; - } -} diff --git a/src/main/java/ru/betterend/world/features/EndLotusFeature.java b/src/main/java/ru/betterend/world/features/EndLotusFeature.java deleted file mode 100644 index dc65d14a..00000000 --- a/src/main/java/ru/betterend/world/features/EndLotusFeature.java +++ /dev/null @@ -1,25 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import ru.betterend.blocks.EndLotusSeedBlock; -import ru.betterend.registry.EndBlocks; - -public class EndLotusFeature extends UnderwaterPlantScatter { - public EndLotusFeature(int radius) { - super(radius); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - EndLotusSeedBlock seed = (EndLotusSeedBlock) EndBlocks.END_LOTUS_SEED; - seed.grow(world, random, blockPos); - } - - @Override - protected int getChance() { - return 15; - } -} diff --git a/src/main/java/ru/betterend/world/features/EndLotusLeafFeature.java b/src/main/java/ru/betterend/world/features/EndLotusLeafFeature.java deleted file mode 100644 index e166e2b2..00000000 --- a/src/main/java/ru/betterend/world/features/EndLotusLeafFeature.java +++ /dev/null @@ -1,71 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.util.BlocksHelper; -import ru.betterend.blocks.EndLotusLeafBlock; -import ru.betterend.registry.EndBlocks; - -public class EndLotusLeafFeature extends ScatterFeature { - public EndLotusLeafFeature(int radius) { - super(radius); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - if (canGenerate(world, blockPos)) { - generateLeaf(world, blockPos); - } - } - - @Override - protected int getChance() { - return 15; - } - - @Override - protected BlockPos getCenterGround(WorldGenLevel world, BlockPos pos) { - return getPosOnSurface(world, pos); - } - - private void generateLeaf(WorldGenLevel world, BlockPos pos) { - MutableBlockPos p = new MutableBlockPos(); - BlockState leaf = EndBlocks.END_LOTUS_LEAF.defaultBlockState(); - BlocksHelper.setWithoutUpdate(world, pos, leaf.setValue(EndLotusLeafBlock.SHAPE, TripleShape.BOTTOM)); - for (Direction move: BlocksHelper.HORIZONTAL) { - BlocksHelper.setWithoutUpdate(world, p.set(pos).move(move), leaf.setValue(EndLotusLeafBlock.HORIZONTAL_FACING, move).setValue(EndLotusLeafBlock.SHAPE, TripleShape.MIDDLE)); - } - for (int i = 0; i < 4; i ++) { - Direction d1 = BlocksHelper.HORIZONTAL[i]; - Direction d2 = BlocksHelper.HORIZONTAL[(i + 1) & 3]; - BlocksHelper.setWithoutUpdate(world, p.set(pos).move(d1).move(d2), leaf.setValue(EndLotusLeafBlock.HORIZONTAL_FACING, d1).setValue(EndLotusLeafBlock.SHAPE, TripleShape.TOP)); - } - } - - private boolean canGenerate(WorldGenLevel world, BlockPos pos) { - MutableBlockPos p = new MutableBlockPos(); - p.setY(pos.getY()); - int count = 0; - for (int x = -1; x < 2; x ++) { - p.setX(pos.getX() + x); - for (int z = -1; z < 2; z ++) { - p.setZ(pos.getZ() + z); - if (world.isEmptyBlock(p) && world.getBlockState(p.below()).is(Blocks.WATER)) - count ++; - } - } - return count == 9; - } - - @Override - public boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, float radius) { - return world.isEmptyBlock(blockPos) && world.getBlockState(blockPos.below()).is(Blocks.WATER); - } -} diff --git a/src/main/java/ru/betterend/world/features/FilaluxFeature.java b/src/main/java/ru/betterend/world/features/FilaluxFeature.java deleted file mode 100644 index 32eee7fe..00000000 --- a/src/main/java/ru/betterend/world/features/FilaluxFeature.java +++ /dev/null @@ -1,39 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.registry.EndBlocks; - -public class FilaluxFeature extends SkyScatterFeature { - public FilaluxFeature() { - super(10); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - BlockState vine = EndBlocks.FILALUX.defaultBlockState(); - BlockState wings = EndBlocks.FILALUX_WINGS.defaultBlockState(); - BlocksHelper.setWithoutUpdate(world, blockPos, EndBlocks.FILALUX_LANTERN); - BlocksHelper.setWithoutUpdate(world, blockPos.above(), wings.setValue(BlockStateProperties.FACING, Direction.UP)); - for (Direction dir: BlocksHelper.HORIZONTAL) { - BlocksHelper.setWithoutUpdate(world, blockPos.relative(dir), wings.setValue(BlockStateProperties.FACING, dir)); - } - int length = MHelper.randRange(1, 3, random); - for (int i = 1; i <= length; i++) { - TripleShape shape = length > 1 ? TripleShape.TOP : TripleShape.BOTTOM; - if (i > 1) { - shape = i == length ? TripleShape.BOTTOM : TripleShape.MIDDLE; - } - BlocksHelper.setWithoutUpdate(world, blockPos.below(i), vine.setValue(BlockProperties.TRIPLE_SHAPE, shape)); - } - } -} diff --git a/src/main/java/ru/betterend/world/features/FullHeightScatterFeature.java b/src/main/java/ru/betterend/world/features/FullHeightScatterFeature.java deleted file mode 100644 index 9912e3be..00000000 --- a/src/main/java/ru/betterend/world/features/FullHeightScatterFeature.java +++ /dev/null @@ -1,58 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; - -public abstract class FullHeightScatterFeature extends DefaultFeature { - private static final MutableBlockPos POS = new MutableBlockPos(); - private final int radius; - - public FullHeightScatterFeature(int radius) { - this.radius = radius; - } - - public abstract boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, - float radius); - - public abstract void generate(WorldGenLevel world, Random random, BlockPos blockPos); - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos center, - NoneFeatureConfiguration featureConfig) { - int maxY = world.getHeight(Heightmap.Types.WORLD_SURFACE_WG, center.getX(), center.getZ()); - int minY = BlocksHelper.upRay(world, new BlockPos(center.getX(), 0, center.getZ()), maxY); - for (int y = maxY; y > minY; y--) { - POS.set(center.getX(), y, center.getZ()); - if (world.getBlockState(POS).isAir() && !world.getBlockState(POS.below()).isAir()) { - float r = MHelper.randRange(radius * 0.5F, radius, random); - int count = MHelper.floor(r * r * MHelper.randRange(1.5F, 3F, random)); - for (int i = 0; i < count; i++) { - float pr = r * (float) Math.sqrt(random.nextFloat()); - float theta = random.nextFloat() * MHelper.PI2; - float x = pr * (float) Math.cos(theta); - float z = pr * (float) Math.sin(theta); - - POS.set(center.getX() + x, y + 5, center.getZ() + z); - int down = BlocksHelper.downRay(world, POS, 16); - if (down > 10) - continue; - POS.setY(POS.getY() - down); - - if (canGenerate(world, random, center, POS, r)) { - generate(world, random, POS); - } - } - } - } - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/GlowPillarFeature.java b/src/main/java/ru/betterend/world/features/GlowPillarFeature.java deleted file mode 100644 index b8a1d6f2..00000000 --- a/src/main/java/ru/betterend/world/features/GlowPillarFeature.java +++ /dev/null @@ -1,30 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import ru.betterend.blocks.basis.EndPlantWithAgeBlock; -import ru.betterend.registry.EndBlocks; - -public class GlowPillarFeature extends ScatterFeature { - public GlowPillarFeature() { - super(9); - } - - @Override - public boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, float radius) { - return EndBlocks.GLOWING_PILLAR_SEED.canSurvive(AIR, world, blockPos); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - EndPlantWithAgeBlock seed = ((EndPlantWithAgeBlock) EndBlocks.GLOWING_PILLAR_SEED); - seed.growAdult(world, random, blockPos); - } - - @Override - protected int getChance() { - return 10; - } -} diff --git a/src/main/java/ru/betterend/world/features/HydraluxFeature.java b/src/main/java/ru/betterend/world/features/HydraluxFeature.java deleted file mode 100644 index 73d6b4ec..00000000 --- a/src/main/java/ru/betterend/world/features/HydraluxFeature.java +++ /dev/null @@ -1,25 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import ru.betterend.blocks.HydraluxSaplingBlock; -import ru.betterend.registry.EndBlocks; - -public class HydraluxFeature extends UnderwaterPlantScatter { - public HydraluxFeature(int radius) { - super(radius); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - HydraluxSaplingBlock seed = (HydraluxSaplingBlock) EndBlocks.HYDRALUX_SAPLING; - seed.grow(world, random, blockPos); - } - - @Override - protected int getChance() { - return 15; - } -} diff --git a/src/main/java/ru/betterend/world/features/InvertedScatterFeature.java b/src/main/java/ru/betterend/world/features/InvertedScatterFeature.java deleted file mode 100644 index c0807972..00000000 --- a/src/main/java/ru/betterend/world/features/InvertedScatterFeature.java +++ /dev/null @@ -1,58 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; - -public abstract class InvertedScatterFeature extends DefaultFeature { - private static final MutableBlockPos POS = new MutableBlockPos(); - private final int radius; - - public InvertedScatterFeature(int radius) { - this.radius = radius; - } - - public abstract boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, - float radius); - - public abstract void generate(WorldGenLevel world, Random random, BlockPos blockPos); - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos center, - NoneFeatureConfiguration featureConfig) { - int maxY = world.getHeight(Heightmap.Types.WORLD_SURFACE, center.getX(), center.getZ()); - int minY = BlocksHelper.upRay(world, new BlockPos(center.getX(), 0, center.getZ()), maxY); - for (int y = maxY; y > minY; y--) { - POS.set(center.getX(), y, center.getZ()); - if (world.getBlockState(POS).isAir() && !world.getBlockState(POS.above()).isAir()) { - float r = MHelper.randRange(radius * 0.5F, radius, random); - int count = MHelper.floor(r * r * MHelper.randRange(0.5F, 1.5F, random)); - for (int i = 0; i < count; i++) { - float pr = r * (float) Math.sqrt(random.nextFloat()); - float theta = random.nextFloat() * MHelper.PI2; - float x = pr * (float) Math.cos(theta); - float z = pr * (float) Math.sin(theta); - - POS.set(center.getX() + x, center.getY() - 7, center.getZ() + z); - int up = BlocksHelper.upRay(world, POS, 16); - if (up > 14) - continue; - POS.setY(POS.getY() + up); - - if (canGenerate(world, random, center, POS, r)) { - generate(world, random, POS); - } - } - } - } - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/LanceleafFeature.java b/src/main/java/ru/betterend/world/features/LanceleafFeature.java deleted file mode 100644 index 5800a71f..00000000 --- a/src/main/java/ru/betterend/world/features/LanceleafFeature.java +++ /dev/null @@ -1,30 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import ru.betterend.blocks.basis.EndPlantWithAgeBlock; -import ru.betterend.registry.EndBlocks; - -public class LanceleafFeature extends ScatterFeature { - public LanceleafFeature() { - super(7); - } - - @Override - public boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, float radius) { - return EndBlocks.LANCELEAF_SEED.canSurvive(AIR, world, blockPos); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - EndPlantWithAgeBlock seed = ((EndPlantWithAgeBlock) EndBlocks.LANCELEAF_SEED); - seed.growAdult(world, random, blockPos); - } - - @Override - protected int getChance() { - return 5; - } -} diff --git a/src/main/java/ru/betterend/world/features/MengerSpongeFeature.java b/src/main/java/ru/betterend/world/features/MengerSpongeFeature.java deleted file mode 100644 index d5f9c5fd..00000000 --- a/src/main/java/ru/betterend/world/features/MengerSpongeFeature.java +++ /dev/null @@ -1,41 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; -import java.util.function.Function; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.util.BlocksHelper; -import ru.betterend.registry.EndBlocks; - -public class MengerSpongeFeature extends UnderwaterPlantScatter { - private static final Function REPLACE; - - public MengerSpongeFeature(int radius) { - super(radius); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - BlocksHelper.setWithoutUpdate(world, blockPos, EndBlocks.MENGER_SPONGE_WET); - if (random.nextBoolean()) { - for (Direction dir: BlocksHelper.DIRECTIONS) { - BlockPos pos = blockPos.relative(dir); - if (REPLACE.apply(world.getBlockState(pos))) { - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.MENGER_SPONGE_WET); - } - } - } - } - - static { - REPLACE = (state) -> { - if (state.is(EndBlocks.END_LOTUS_STEM)) { - return false; - } - return !state.getFluidState().isEmpty() || state.getMaterial().isReplaceable(); - }; - } -} diff --git a/src/main/java/ru/betterend/world/features/NeonCactusFeature.java b/src/main/java/ru/betterend/world/features/NeonCactusFeature.java deleted file mode 100644 index 523e4dac..00000000 --- a/src/main/java/ru/betterend/world/features/NeonCactusFeature.java +++ /dev/null @@ -1,27 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.NeonCactusPlantBlock; -import ru.betterend.registry.EndBlocks; - -public class NeonCactusFeature extends DefaultFeature { - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, NoneFeatureConfiguration config) { - BlockState ground = world.getBlockState(pos.below()); - if (!ground.is(EndBlocks.ENDSTONE_DUST) && !ground.is(EndBlocks.END_MOSS)) { - return false; - } - - NeonCactusPlantBlock cactus = ((NeonCactusPlantBlock) EndBlocks.NEON_CACTUS); - cactus.growPlant(world, pos, random); - - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/ScatterFeature.java b/src/main/java/ru/betterend/world/features/ScatterFeature.java deleted file mode 100644 index 620be106..00000000 --- a/src/main/java/ru/betterend/world/features/ScatterFeature.java +++ /dev/null @@ -1,84 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; - -public abstract class ScatterFeature extends DefaultFeature { - private static final MutableBlockPos POS = new MutableBlockPos(); - private final int radius; - - public ScatterFeature(int radius) { - this.radius = radius; - } - - public abstract boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, - float radius); - - public abstract void generate(WorldGenLevel world, Random random, BlockPos blockPos); - - protected BlockPos getCenterGround(WorldGenLevel world, BlockPos pos) { - return getPosOnSurfaceWG(world, pos); - } - - protected boolean canSpawn(WorldGenLevel world, BlockPos pos) { - if (pos.getY() < 5) { - return false; - } else if (!world.getBlockState(pos.below()).is(TagAPI.END_GROUND)) { - return false; - } - return true; - } - - protected boolean getGroundPlant(WorldGenLevel world, MutableBlockPos pos) { - int down = BlocksHelper.downRay(world, pos, 16); - if (down > Math.abs(getYOffset() * 2)) { - return false; - } - pos.setY(pos.getY() - down); - return true; - } - - protected int getYOffset() { - return 5; - } - - protected int getChance() { - return 1; - } - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos center, - NoneFeatureConfiguration featureConfig) { - center = getCenterGround(world, center); - - if (!canSpawn(world, center)) { - return false; - } - - float r = MHelper.randRange(radius * 0.5F, radius, random); - int count = MHelper.floor(r * r * MHelper.randRange(1.5F, 3F, random)); - for (int i = 0; i < count; i++) { - float pr = r * (float) Math.sqrt(random.nextFloat()); - float theta = random.nextFloat() * MHelper.PI2; - float x = pr * (float) Math.cos(theta); - float z = pr * (float) Math.sin(theta); - - POS.set(center.getX() + x, center.getY() + getYOffset(), center.getZ() + z); - if (getGroundPlant(world, POS) && canGenerate(world, random, center, POS, r) - && (getChance() < 2 || random.nextInt(getChance()) == 0)) { - generate(world, random, POS); - } - } - - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/SilkMothNestFeature.java b/src/main/java/ru/betterend/world/features/SilkMothNestFeature.java deleted file mode 100644 index 25ca6aed..00000000 --- a/src/main/java/ru/betterend/world/features/SilkMothNestFeature.java +++ /dev/null @@ -1,56 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.tags.BlockTags; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.util.BlocksHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.registry.EndBlocks; - -public class SilkMothNestFeature extends DefaultFeature { - private static final MutableBlockPos POS = new MutableBlockPos(); - - private boolean canGenerate(WorldGenLevel world, BlockPos pos) { - BlockState state = world.getBlockState(pos.above()); - if (state.is(BlockTags.LEAVES) || state.is(BlockTags.LOGS)) { - state = world.getBlockState(pos); - if ((state.isAir() || state.is(EndBlocks.TENANEA_OUTER_LEAVES)) && world.isEmptyBlock(pos.below())) { - for (Direction dir : BlocksHelper.HORIZONTAL) { - return !world.getBlockState(pos.below().relative(dir)).getMaterial().blocksMotion(); - } - } - } - return false; - } - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos center, - NoneFeatureConfiguration featureConfig) { - int maxY = world.getHeight(Heightmap.Types.WORLD_SURFACE, center.getX(), center.getZ()); - int minY = BlocksHelper.upRay(world, new BlockPos(center.getX(), 0, center.getZ()), maxY); - POS.set(center); - for (int y = maxY; y > minY; y--) { - POS.setY(y); - if (canGenerate(world, POS)) { - Direction dir = BlocksHelper.randomHorizontal(random); - BlocksHelper.setWithoutUpdate(world, POS, EndBlocks.SILK_MOTH_NEST.defaultBlockState() - .setValue(BlockStateProperties.HORIZONTAL_FACING, dir).setValue(BlockProperties.ACTIVE, false)); - POS.setY(y - 1); - BlocksHelper.setWithoutUpdate(world, POS, EndBlocks.SILK_MOTH_NEST.defaultBlockState() - .setValue(BlockStateProperties.HORIZONTAL_FACING, dir)); - return true; - } - } - return false; - } -} diff --git a/src/main/java/ru/betterend/world/features/SingleInvertedScatterFeature.java b/src/main/java/ru/betterend/world/features/SingleInvertedScatterFeature.java deleted file mode 100644 index 053f33c3..00000000 --- a/src/main/java/ru/betterend/world/features/SingleInvertedScatterFeature.java +++ /dev/null @@ -1,42 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import ru.bclib.blocks.BaseAttachedBlock; -import ru.bclib.util.BlocksHelper; - -public class SingleInvertedScatterFeature extends InvertedScatterFeature { - private final Block block; - - public SingleInvertedScatterFeature(Block block, int radius) { - super(radius); - this.block = block; - } - - @Override - public boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, float radius) { - if (!world.isEmptyBlock(blockPos)) { - return false; - } - BlockState state = block.defaultBlockState(); - if (block instanceof BaseAttachedBlock) { - state = state.setValue(BlockStateProperties.FACING, Direction.DOWN); - } - return state.canSurvive(world, blockPos); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - BlockState state = block.defaultBlockState(); - if (block instanceof BaseAttachedBlock) { - state = state.setValue(BlockStateProperties.FACING, Direction.DOWN); - } - BlocksHelper.setWithoutUpdate(world, blockPos, state); - } -} diff --git a/src/main/java/ru/betterend/world/features/SinglePlantFeature.java b/src/main/java/ru/betterend/world/features/SinglePlantFeature.java deleted file mode 100644 index b663c2dc..00000000 --- a/src/main/java/ru/betterend/world/features/SinglePlantFeature.java +++ /dev/null @@ -1,73 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BaseCropBlock; -import ru.bclib.blocks.BaseDoublePlantBlock; -import ru.bclib.util.BlocksHelper; -import ru.betterend.blocks.basis.EndPlantWithAgeBlock; - -public class SinglePlantFeature extends ScatterFeature { - private final Block plant; - private final boolean rawHeightmap; - private final int chance; - - public SinglePlantFeature(Block plant, int radius) { - this(plant, radius, true, 1); - } - - public SinglePlantFeature(Block plant, int radius, int chance) { - this(plant, radius, true, chance); - } - - public SinglePlantFeature(Block plant, int radius, boolean rawHeightmap) { - this(plant, radius, rawHeightmap, 1); - } - - public SinglePlantFeature(Block plant, int radius, boolean rawHeightmap, int chance) { - super(radius); - this.plant = plant; - this.rawHeightmap = rawHeightmap; - this.chance = chance; - } - - protected int getChance() { - return chance; - } - - @Override - protected BlockPos getCenterGround(WorldGenLevel world, BlockPos pos) { - return rawHeightmap ? getPosOnSurfaceWG(world, pos) : getPosOnSurface(world, pos); - } - - @Override - public boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, float radius) { - return plant.canSurvive(plant.defaultBlockState(), world, blockPos); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - if (plant instanceof BaseDoublePlantBlock) { - int rot = random.nextInt(4); - BlockState state = plant.defaultBlockState().setValue(BaseDoublePlantBlock.ROTATION, rot); - BlocksHelper.setWithoutUpdate(world, blockPos, state); - BlocksHelper.setWithoutUpdate(world, blockPos.above(), state.setValue(BaseDoublePlantBlock.TOP, true)); - } - else if (plant instanceof BaseCropBlock) { - BlockState state = plant.defaultBlockState().setValue(BaseCropBlock.AGE, 3); - BlocksHelper.setWithoutUpdate(world, blockPos, state); - } - else if (plant instanceof EndPlantWithAgeBlock) { - int age = random.nextInt(4); - BlockState state = plant.defaultBlockState().setValue(EndPlantWithAgeBlock.AGE, age); - BlocksHelper.setWithoutUpdate(world, blockPos, state); - } - else { - BlocksHelper.setWithoutUpdate(world, blockPos, plant); - } - } -} diff --git a/src/main/java/ru/betterend/world/features/SkyScatterFeature.java b/src/main/java/ru/betterend/world/features/SkyScatterFeature.java deleted file mode 100644 index d14dbd3a..00000000 --- a/src/main/java/ru/betterend/world/features/SkyScatterFeature.java +++ /dev/null @@ -1,54 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; - -public abstract class SkyScatterFeature extends ScatterFeature { - public SkyScatterFeature(int radius) { - super(radius); - } - - @Override - protected int getChance() { - return 10; - } - - @Override - public boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, float radius) { - if (!world.isEmptyBlock(blockPos)) { - return false; - } - - for (Direction dir: BlocksHelper.HORIZONTAL) { - if (!world.isEmptyBlock(blockPos.relative(dir))) { - return false; - } - } - - int maxD = getYOffset() + 2; - int maxV = getYOffset() - 2; - - return BlocksHelper.upRay(world, blockPos, maxD) > maxV && BlocksHelper.downRay(world, blockPos, maxD) > maxV; - } - - @Override - protected boolean canSpawn(WorldGenLevel world, BlockPos pos) { - return true; - } - - @Override - protected BlockPos getCenterGround(WorldGenLevel world, BlockPos pos) { - return new BlockPos(pos.getX(), MHelper.randRange(32, 192, world.getRandom()), pos.getZ()); - } - - protected boolean getGroundPlant(WorldGenLevel world, MutableBlockPos pos) { - pos.setY(pos.getY() + MHelper.randRange(-getYOffset(), getYOffset(), world.getRandom())); - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/UnderwaterPlantFeature.java b/src/main/java/ru/betterend/world/features/UnderwaterPlantFeature.java deleted file mode 100644 index a31a36dd..00000000 --- a/src/main/java/ru/betterend/world/features/UnderwaterPlantFeature.java +++ /dev/null @@ -1,37 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BaseDoublePlantBlock; -import ru.bclib.util.BlocksHelper; - -public class UnderwaterPlantFeature extends UnderwaterPlantScatter { - private final Block plant; - - public UnderwaterPlantFeature(Block plant, int radius) { - super(radius); - this.plant = plant; - } - - @Override - public boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, float radius) { - return super.canSpawn(world, blockPos) && plant.canSurvive(plant.defaultBlockState(), world, blockPos); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - if (plant instanceof BaseDoublePlantBlock) { - int rot = random.nextInt(4); - BlockState state = plant.defaultBlockState().setValue(BaseDoublePlantBlock.ROTATION, rot); - BlocksHelper.setWithoutUpdate(world, blockPos, state); - BlocksHelper.setWithoutUpdate(world, blockPos.above(), state.setValue(BaseDoublePlantBlock.TOP, true)); - } - else { - BlocksHelper.setWithoutUpdate(world, blockPos, plant); - } - } -} diff --git a/src/main/java/ru/betterend/world/features/UnderwaterPlantScatter.java b/src/main/java/ru/betterend/world/features/UnderwaterPlantScatter.java deleted file mode 100644 index c97f15df..00000000 --- a/src/main/java/ru/betterend/world/features/UnderwaterPlantScatter.java +++ /dev/null @@ -1,56 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; - -public abstract class UnderwaterPlantScatter extends ScatterFeature { - private static final MutableBlockPos POS = new MutableBlockPos(); - - public UnderwaterPlantScatter(int radius) { - super(radius); - } - - @Override - protected BlockPos getCenterGround(WorldGenLevel world, BlockPos pos) { - POS.setX(pos.getX()); - POS.setZ(pos.getZ()); - POS.setY(0); - return getGround(world, POS).immutable(); - } - - @Override - public boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, float radius) { - return world.getBlockState(blockPos).is(Blocks.WATER); - } - - @Override - protected boolean canSpawn(WorldGenLevel world, BlockPos pos) { - return world.getBlockState(pos).is(Blocks.WATER); - } - - @Override - protected boolean getGroundPlant(WorldGenLevel world, MutableBlockPos pos) { - return getGround(world, pos).getY() < 128; - } - - @Override - protected int getYOffset() { - return -5; - } - - @Override - protected int getChance() { - return 5; - } - - private BlockPos getGround(WorldGenLevel world, MutableBlockPos pos) { - while (pos.getY() < 128 && world.getFluidState(pos).isEmpty()) { - pos.setY(pos.getY() + 1); - } - return pos; - } -} diff --git a/src/main/java/ru/betterend/world/features/VineFeature.java b/src/main/java/ru/betterend/world/features/VineFeature.java deleted file mode 100644 index 1d2d083f..00000000 --- a/src/main/java/ru/betterend/world/features/VineFeature.java +++ /dev/null @@ -1,70 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import ru.bclib.blocks.BaseVineBlock; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.util.BlocksHelper; - -public class VineFeature extends InvertedScatterFeature { - private final Block vineBlock; - private final int maxLength; - private final boolean vine; - - public VineFeature(Block vineBlock, int maxLength) { - super(6); - this.vineBlock = vineBlock; - this.maxLength = maxLength; - this.vine = vineBlock instanceof BaseVineBlock; - } - - @Override - public boolean canGenerate(WorldGenLevel world, Random random, BlockPos center, BlockPos blockPos, float radius) { - BlockState state = world.getBlockState(blockPos); - return state.getMaterial().isReplaceable() && canPlaceBlock(state, world, blockPos); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos blockPos) { - int h = BlocksHelper.downRay(world, blockPos, random.nextInt(maxLength)) - 1; - if (h > 2) { - BlockState top = getTopState(); - BlockState middle = getMiggleState(); - BlockState bottom = getBottomState(); - BlocksHelper.setWithoutUpdate(world, blockPos, top); - for (int i = 1; i < h; i++) { - BlocksHelper.setWithoutUpdate(world, blockPos.below(i), middle); - } - BlocksHelper.setWithoutUpdate(world, blockPos.below(h), bottom); - } - } - - private boolean canPlaceBlock(BlockState state, WorldGenLevel world, BlockPos blockPos) { - if (vine) { - return ((BaseVineBlock) vineBlock).canGenerate(state, world, blockPos); - } - else { - return vineBlock.canSurvive(state, world, blockPos); - } - } - - private BlockState getTopState() { - BlockState state = vineBlock.defaultBlockState(); - return vine ? state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP) : state; - } - - private BlockState getMiggleState() { - BlockState state = vineBlock.defaultBlockState(); - return vine ? state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE) : state; - } - - private BlockState getBottomState() { - BlockState state = vineBlock.defaultBlockState(); - return vine ? state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM) : state; - } -} diff --git a/src/main/java/ru/betterend/world/features/WallPlantFeature.java b/src/main/java/ru/betterend/world/features/WallPlantFeature.java deleted file mode 100644 index b218a663..00000000 --- a/src/main/java/ru/betterend/world/features/WallPlantFeature.java +++ /dev/null @@ -1,47 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import ru.bclib.blocks.BaseAttachedBlock; -import ru.bclib.blocks.BaseWallPlantBlock; -import ru.bclib.util.BlocksHelper; - -public class WallPlantFeature extends WallScatterFeature { - private final Block block; - - public WallPlantFeature(Block block, int radius) { - super(radius); - this.block = block; - } - - @Override - public boolean canGenerate(WorldGenLevel world, Random random, BlockPos pos, Direction dir) { - if (block instanceof BaseWallPlantBlock) { - BlockState state = block.defaultBlockState().setValue(BaseWallPlantBlock.FACING, dir); - return block.canSurvive(state, world, pos); - } - else if (block instanceof BaseAttachedBlock) { - BlockState state = block.defaultBlockState().setValue(BlockStateProperties.FACING, dir); - return block.canSurvive(state, world, pos); - } - return block.canSurvive(block.defaultBlockState(), world, pos); - } - - @Override - public void generate(WorldGenLevel world, Random random, BlockPos pos, Direction dir) { - BlockState state = block.defaultBlockState(); - if (block instanceof BaseWallPlantBlock) { - state = state.setValue(BaseWallPlantBlock.FACING, dir); - } - else if (block instanceof BaseAttachedBlock) { - state = state.setValue(BlockStateProperties.FACING, dir); - } - BlocksHelper.setWithoutUpdate(world, pos, state); - } -} diff --git a/src/main/java/ru/betterend/world/features/WallPlantOnLogFeature.java b/src/main/java/ru/betterend/world/features/WallPlantOnLogFeature.java deleted file mode 100644 index 7ca5cb1e..00000000 --- a/src/main/java/ru/betterend/world/features/WallPlantOnLogFeature.java +++ /dev/null @@ -1,23 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.tags.BlockTags; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; - -public class WallPlantOnLogFeature extends WallPlantFeature { - public WallPlantOnLogFeature(Block block, int radius) { - super(block, radius); - } - - @Override - public boolean canGenerate(WorldGenLevel world, Random random, BlockPos pos, Direction dir) { - BlockPos blockPos = pos.relative(dir.getOpposite()); - BlockState blockState = world.getBlockState(blockPos); - return blockState.is(BlockTags.LOGS); - } -} diff --git a/src/main/java/ru/betterend/world/features/WallScatterFeature.java b/src/main/java/ru/betterend/world/features/WallScatterFeature.java deleted file mode 100644 index d9dee786..00000000 --- a/src/main/java/ru/betterend/world/features/WallScatterFeature.java +++ /dev/null @@ -1,68 +0,0 @@ -package ru.betterend.world.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; - -public abstract class WallScatterFeature extends DefaultFeature { - private static final Direction[] DIR = BlocksHelper.makeHorizontal(); - private final int radius; - - public WallScatterFeature(int radius) { - this.radius = radius; - } - - public abstract boolean canGenerate(WorldGenLevel world, Random random, BlockPos pos, Direction dir); - - public abstract void generate(WorldGenLevel world, Random random, BlockPos pos, Direction dir); - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos center, NoneFeatureConfiguration featureConfig) { - int maxY = world.getHeight(Heightmap.Types.WORLD_SURFACE, center.getX(), center.getZ()); - int minY = BlocksHelper.upRay(world, new BlockPos(center.getX(), 0, center.getZ()), maxY); - if (maxY < 10 || maxY < minY) { - return false; - } - int py = MHelper.randRange(minY, maxY, random); - - MutableBlockPos mut = new MutableBlockPos(); - for (int x = -radius; x <= radius; x++) { - mut.setX(center.getX() + x); - for (int y = -radius; y <= radius; y++) { - mut.setY(py + y); - for (int z = -radius; z <= radius; z++) { - mut.setZ(center.getZ() + z); - if (random.nextInt(4) == 0 && world.isEmptyBlock(mut)) { - shuffle(random); - for (Direction dir : DIR) { - if (canGenerate(world, random, mut, dir)) { - generate(world, random, mut, dir); - break; - } - } - } - } - } - } - - return true; - } - - private void shuffle(Random random) { - for (int i = 0; i < 4; i++) { - int j = random.nextInt(4); - Direction d = DIR[i]; - DIR[i] = DIR[j]; - DIR[j] = d; - } - } -} diff --git a/src/main/java/ru/betterend/world/features/bushes/BushFeature.java b/src/main/java/ru/betterend/world/features/bushes/BushFeature.java deleted file mode 100644 index d3a78ecc..00000000 --- a/src/main/java/ru/betterend/world/features/bushes/BushFeature.java +++ /dev/null @@ -1,93 +0,0 @@ -package ru.betterend.world.features.bushes; - -import java.util.Random; -import java.util.function.Function; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.LeavesBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; - -public class BushFeature extends DefaultFeature { - private static final Function REPLACE; - private final Block leaves; - private final Block stem; - - public BushFeature(Block leaves, Block stem) { - this.leaves = leaves; - this.stem = stem; - } - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND) - && !world.getBlockState(pos.above()).getBlock().is(TagAPI.END_GROUND)) - return false; - - float radius = MHelper.randRange(1.8F, 3.5F, random); - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextInt()); - SDF sphere = new SDFSphere().setRadius(radius).setBlock(this.leaves); - sphere = new SDFScale3D().setScale(1, 0.5F, 1).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> { - return (float) noise.eval(vec.x() * 0.2, vec.y() * 0.2, vec.z() * 0.2) * 3; - }).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> { - return MHelper.randRange(-2F, 2F, random); - }).setSource(sphere); - sphere = new SDFSubtraction().setSourceA(sphere) - .setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere)); - sphere.setReplaceFunction(REPLACE); - sphere.addPostProcess((info) -> { - if (info.getState().getBlock() instanceof LeavesBlock) { - int distance = info.getPos().distManhattan(pos); - if (distance < 7) { - return info.getState().setValue(LeavesBlock.DISTANCE, distance); - } else { - return AIR; - } - } - return info.getState(); - }); - sphere.fillRecursive(world, pos); - BlocksHelper.setWithoutUpdate(world, pos, stem); - for (Direction d : Direction.values()) { - BlockPos p = pos.relative(d); - if (world.isEmptyBlock(p)) { - if (leaves instanceof LeavesBlock) { - BlocksHelper.setWithoutUpdate(world, p, - leaves.defaultBlockState().setValue(LeavesBlock.DISTANCE, 1)); - } else { - BlocksHelper.setWithoutUpdate(world, p, leaves.defaultBlockState()); - } - } - } - - return true; - } - - static { - REPLACE = (state) -> { - if (state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - } -} diff --git a/src/main/java/ru/betterend/world/features/bushes/BushWithOuterFeature.java b/src/main/java/ru/betterend/world/features/bushes/BushWithOuterFeature.java deleted file mode 100644 index 67daa795..00000000 --- a/src/main/java/ru/betterend/world/features/bushes/BushWithOuterFeature.java +++ /dev/null @@ -1,108 +0,0 @@ -package ru.betterend.world.features.bushes; - -import java.util.Random; -import java.util.function.Function; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.LeavesBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; - -public class BushWithOuterFeature extends DefaultFeature { - private static final Direction[] DIRECTIONS = Direction.values(); - private static final Function REPLACE; - private final Block outer_leaves; - private final Block leaves; - private final Block stem; - - public BushWithOuterFeature(Block leaves, Block outer_leaves, Block stem) { - this.outer_leaves = outer_leaves; - this.leaves = leaves; - this.stem = stem; - } - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND) - && !world.getBlockState(pos.above()).getBlock().is(TagAPI.END_GROUND)) - return false; - - float radius = MHelper.randRange(1.8F, 3.5F, random); - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextInt()); - SDF sphere = new SDFSphere().setRadius(radius).setBlock(this.leaves); - sphere = new SDFScale3D().setScale(1, 0.5F, 1).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> { - return (float) noise.eval(vec.x() * 0.2, vec.y() * 0.2, vec.z() * 0.2) * 3; - }).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> { - return MHelper.randRange(-2F, 2F, random); - }).setSource(sphere); - sphere = new SDFSubtraction().setSourceA(sphere) - .setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere)); - sphere.setReplaceFunction(REPLACE); - sphere.addPostProcess((info) -> { - if (info.getState().getBlock() instanceof LeavesBlock) { - int distance = info.getPos().distManhattan(pos); - if (distance < 7) { - return info.getState().setValue(LeavesBlock.DISTANCE, distance); - } else { - return AIR; - } - } - return info.getState(); - }).addPostProcess((info) -> { - if (info.getState().getBlock() instanceof LeavesBlock) { - MHelper.shuffle(DIRECTIONS, random); - for (Direction dir : DIRECTIONS) { - if (info.getState(dir).isAir()) { - info.setBlockPos(info.getPos().relative(dir), - outer_leaves.defaultBlockState().setValue(BlockStateProperties.FACING, dir)); - } - } - } - return info.getState(); - }); - sphere.fillRecursive(world, pos); - BlocksHelper.setWithoutUpdate(world, pos, stem); - for (Direction d : Direction.values()) { - BlockPos p = pos.relative(d); - if (world.isEmptyBlock(p)) { - if (leaves instanceof LeavesBlock) { - BlocksHelper.setWithoutUpdate(world, p, - leaves.defaultBlockState().setValue(LeavesBlock.DISTANCE, 1)); - } else { - BlocksHelper.setWithoutUpdate(world, p, leaves.defaultBlockState()); - } - } - } - - return true; - } - - static { - REPLACE = (state) -> { - if (state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - } -} diff --git a/src/main/java/ru/betterend/world/features/bushes/LargeAmaranitaFeature.java b/src/main/java/ru/betterend/world/features/bushes/LargeAmaranitaFeature.java deleted file mode 100644 index a3c8018a..00000000 --- a/src/main/java/ru/betterend/world/features/bushes/LargeAmaranitaFeature.java +++ /dev/null @@ -1,48 +0,0 @@ -package ru.betterend.world.features.bushes; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.registry.EndBlocks; - -public class LargeAmaranitaFeature extends DefaultFeature { - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND)) - return false; - - MutableBlockPos mut = new MutableBlockPos().set(pos); - int height = MHelper.randRange(2, 3, random); - for (int i = 1; i < height; i++) { - mut.setY(mut.getY() + 1); - if (!world.isEmptyBlock(mut)) { - return false; - } - } - mut.set(pos); - - BlockState state = EndBlocks.LARGE_AMARANITA_MUSHROOM.defaultBlockState(); - BlocksHelper.setWithUpdate(world, mut, state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM)); - if (height > 2) { - BlocksHelper.setWithUpdate(world, mut.move(Direction.UP), - state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE)); - } - BlocksHelper.setWithUpdate(world, mut.move(Direction.UP), - state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP)); - - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/bushes/Lumecorn.java b/src/main/java/ru/betterend/world/features/bushes/Lumecorn.java deleted file mode 100644 index ec9b0682..00000000 --- a/src/main/java/ru/betterend/world/features/bushes/Lumecorn.java +++ /dev/null @@ -1,69 +0,0 @@ -package ru.betterend.world.features.bushes; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.EndBlockProperties.LumecornShape; -import ru.betterend.blocks.LumecornBlock; -import ru.betterend.registry.EndBlocks; - -public class Lumecorn extends DefaultFeature { - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND)) - return false; - - int height = MHelper.randRange(4, 7, random); - MutableBlockPos mut = new MutableBlockPos().set(pos); - for (int i = 1; i < height; i++) { - mut.move(Direction.UP); - if (!world.isEmptyBlock(mut)) { - return false; - } - } - mut.set(pos); - BlockState topMiddle = EndBlocks.LUMECORN.defaultBlockState().setValue(LumecornBlock.SHAPE, - LumecornShape.LIGHT_TOP_MIDDLE); - BlockState middle = EndBlocks.LUMECORN.defaultBlockState().setValue(LumecornBlock.SHAPE, - LumecornShape.LIGHT_MIDDLE); - BlockState bottom = EndBlocks.LUMECORN.defaultBlockState().setValue(LumecornBlock.SHAPE, - LumecornShape.LIGHT_BOTTOM); - BlockState top = EndBlocks.LUMECORN.defaultBlockState().setValue(LumecornBlock.SHAPE, LumecornShape.LIGHT_TOP); - if (height == 4) { - BlocksHelper.setWithoutUpdate(world, mut, - EndBlocks.LUMECORN.defaultBlockState().setValue(LumecornBlock.SHAPE, LumecornShape.BOTTOM_SMALL)); - BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), bottom); - BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), topMiddle); - BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), top); - return true; - } - if (random.nextBoolean()) { - BlocksHelper.setWithoutUpdate(world, mut, - EndBlocks.LUMECORN.defaultBlockState().setValue(LumecornBlock.SHAPE, LumecornShape.BOTTOM_SMALL)); - } else { - BlocksHelper.setWithoutUpdate(world, mut, - EndBlocks.LUMECORN.defaultBlockState().setValue(LumecornBlock.SHAPE, LumecornShape.BOTTOM_BIG)); - BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), - EndBlocks.LUMECORN.defaultBlockState().setValue(LumecornBlock.SHAPE, LumecornShape.MIDDLE)); - height--; - } - BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), bottom); - for (int i = 4; i < height; i++) { - BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), middle); - } - BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), topMiddle); - BlocksHelper.setWithoutUpdate(world, mut.move(Direction.UP), top); - return false; - } -} diff --git a/src/main/java/ru/betterend/world/features/bushes/TenaneaBushFeature.java b/src/main/java/ru/betterend/world/features/bushes/TenaneaBushFeature.java deleted file mode 100644 index 21e7d95e..00000000 --- a/src/main/java/ru/betterend/world/features/bushes/TenaneaBushFeature.java +++ /dev/null @@ -1,132 +0,0 @@ -package ru.betterend.world.features.bushes; - -import java.util.List; -import java.util.Random; -import java.util.function.Function; - -import com.google.common.collect.Lists; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.LeavesBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.basis.FurBlock; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class TenaneaBushFeature extends DefaultFeature { - private static final Function REPLACE; - private static final Direction[] DIRECTIONS = Direction.values(); - - public TenaneaBushFeature() { - } - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND)) - return false; - - float radius = MHelper.randRange(1.8F, 3.5F, random); - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextInt()); - BlockState leaves = EndBlocks.TENANEA_LEAVES.defaultBlockState(); - SDF sphere = new SDFSphere().setRadius(radius).setBlock(leaves); - sphere = new SDFScale3D().setScale(1, 0.75F, 1).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> - (float) noise.eval(vec.x() * 0.2, vec.y() * 0.2, vec.z() * 0.2) * 3).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> - MHelper.randRange(-2F, 2F, random)).setSource(sphere); - sphere = new SDFSubtraction().setSourceA(sphere) - .setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere)); - sphere.setReplaceFunction(REPLACE); - List support = Lists.newArrayList(); - sphere.addPostProcess((info) -> { - if (info.getState().getBlock() instanceof LeavesBlock) { - int distance = info.getPos().distManhattan(pos); - if (distance < 7) { - if (random.nextInt(4) == 0 && info.getStateDown().isAir()) { - BlockPos d = info.getPos().below(); - support.add(d); - } - - MHelper.shuffle(DIRECTIONS, random); - for (Direction d : DIRECTIONS) { - if (info.getState(d).isAir()) { - info.setBlockPos(info.getPos().relative(d), - EndBlocks.TENANEA_OUTER_LEAVES.defaultBlockState().setValue(FurBlock.FACING, d)); - } - } - - return info.getState().setValue(LeavesBlock.DISTANCE, distance); - } else { - return AIR; - } - } - return info.getState(); - }); - sphere.fillRecursive(world, pos); - BlockState stem = EndBlocks.TENANEA.bark.defaultBlockState(); - BlocksHelper.setWithoutUpdate(world, pos, stem); - for (Direction d : Direction.values()) { - BlockPos p = pos.relative(d); - if (world.isEmptyBlock(p)) { - BlocksHelper.setWithoutUpdate(world, p, leaves.setValue(LeavesBlock.DISTANCE, 1)); - } - } - - MutableBlockPos mut = new MutableBlockPos(); - BlockState top = EndBlocks.TENANEA_FLOWERS.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, - TripleShape.TOP); - BlockState middle = EndBlocks.TENANEA_FLOWERS.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, - TripleShape.MIDDLE); - BlockState bottom = EndBlocks.TENANEA_FLOWERS.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, - TripleShape.BOTTOM); - support.forEach((bpos) -> { - BlockState state = world.getBlockState(bpos); - if (state.isAir() || state.is(EndBlocks.TENANEA_OUTER_LEAVES)) { - int count = MHelper.randRange(3, 8, random); - mut.set(bpos); - if (world.getBlockState(mut.above()).is(EndBlocks.TENANEA_LEAVES)) { - BlocksHelper.setWithoutUpdate(world, mut, top); - for (int i = 1; i < count; i++) { - mut.setY(mut.getY() - 1); - if (world.isEmptyBlock(mut.below())) { - BlocksHelper.setWithoutUpdate(world, mut, middle); - } else { - break; - } - } - BlocksHelper.setWithoutUpdate(world, mut, bottom); - } - } - }); - - return true; - } - - static { - REPLACE = (state) -> { - if (state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/BigAuroraCrystalFeature.java b/src/main/java/ru/betterend/world/features/terrain/BigAuroraCrystalFeature.java deleted file mode 100644 index 5ccdefe2..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/BigAuroraCrystalFeature.java +++ /dev/null @@ -1,49 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; - -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFRotation; -import ru.bclib.sdf.primitive.SDFHexPrism; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.registry.EndBlocks; - -public class BigAuroraCrystalFeature extends DefaultFeature { - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - int maxY = pos.getY() + BlocksHelper.upRay(world, pos, 16); - int minY = pos.getY() - BlocksHelper.downRay(world, pos, 16); - - if (maxY - minY < 10) { - return false; - } - - int y = MHelper.randRange(minY, maxY, random); - pos = new BlockPos(pos.getX(), y, pos.getZ()); - - int height = MHelper.randRange(5, 25, random); - SDF prism = new SDFHexPrism().setHeight(height).setRadius(MHelper.randRange(1.7F, 3F, random)) - .setBlock(EndBlocks.AURORA_CRYSTAL); - Vector3f vec = MHelper.randomHorizontal(random); - prism = new SDFRotation().setRotation(vec, random.nextFloat()).setSource(prism); - prism.setReplaceFunction((bState) -> { - return bState.getMaterial().isReplaceable() || bState.is(TagAPI.GEN_TERRAIN) - || bState.getMaterial().equals(Material.PLANT) || bState.getMaterial().equals(Material.LEAVES); - }); - prism.fillRecursive(world, pos); - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.AURORA_CRYSTAL); - - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/DesertLakeFeature.java b/src/main/java/ru/betterend/world/features/terrain/DesertLakeFeature.java deleted file mode 100644 index 7724bae3..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/DesertLakeFeature.java +++ /dev/null @@ -1,211 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; -import ru.betterend.util.BlockFixer; - -public class DesertLakeFeature extends DefaultFeature { - private static final BlockState END_STONE = Blocks.END_STONE.defaultBlockState(); - private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(15152); - private static final MutableBlockPos POS = new MutableBlockPos(); - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, NoneFeatureConfiguration featureConfig) { - double radius = MHelper.randRange(8.0, 15.0, random); - double depth = radius * 0.5 * MHelper.randRange(0.8, 1.2, random); - int dist = MHelper.floor(radius); - int dist2 = MHelper.floor(radius * 1.5); - int bott = MHelper.floor(depth); - blockPos = getPosOnSurfaceWG(world, blockPos); - - if (blockPos.getY() < 10) return false; - - int waterLevel = blockPos.getY(); - - BlockPos pos = getPosOnSurfaceRaycast(world, blockPos.north(dist).above(10), 20); - if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; - waterLevel = MHelper.min(pos.getY(), waterLevel); - - pos = getPosOnSurfaceRaycast(world, blockPos.south(dist).above(10), 20); - if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; - waterLevel = MHelper.min(pos.getY(), waterLevel); - - pos = getPosOnSurfaceRaycast(world, blockPos.east(dist).above(10), 20); - if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; - waterLevel = MHelper.min(pos.getY(), waterLevel); - - pos = getPosOnSurfaceRaycast(world, blockPos.west(dist).above(10), 20); - if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; - waterLevel = MHelper.min(pos.getY(), waterLevel); - BlockState state; - - int minX = blockPos.getX() - dist2; - int maxX = blockPos.getX() + dist2; - int minZ = blockPos.getZ() - dist2; - int maxZ = blockPos.getZ() + dist2; - int maskMinX = minX - 1; - int maskMinZ = minZ - 1; - - boolean[][] mask = new boolean[maxX - minX + 3][maxZ - minZ + 3]; - for (int x = minX; x <= maxX; x++) { - POS.setX(x); - int mx = x - maskMinX; - for (int z = minZ; z <= maxZ; z++) { - POS.setZ(z); - int mz = z - maskMinZ; - if (!mask[mx][mz]) { - for (int y = waterLevel + 1; y <= waterLevel + 20; y++) { - POS.setY(y); - FluidState fluid = world.getFluidState(POS); - if (!fluid.isEmpty()) { - for (int i = -1; i < 2; i++) { - int px = mx + i; - for (int j = -1; j < 2; j++) { - int pz = mz + j; - mask[px][pz] = true; - } - } - break; - } - } - } - } - } - - for (int x = minX; x <= maxX; x++) { - POS.setX(x); - int x2 = x - blockPos.getX(); - x2 *= x2; - int mx = x - maskMinX; - for (int z = minZ; z <= maxZ; z++) { - POS.setZ(z); - int z2 = z - blockPos.getZ(); - z2 *= z2; - int mz = z - maskMinZ; - if (!mask[mx][mz]) { - double size = 1; - for (int y = blockPos.getY(); y <= blockPos.getY() + 20; y++) { - POS.setY(y); - double add = y - blockPos.getY(); - if (add > 5) { - size *= 0.8; - add = 5; - } - double r = (add * 1.8 + radius * (NOISE.eval(x * 0.2, y * 0.2, z * 0.2) * 0.25 + 0.75)) - 1.0 / size; - if (r > 0) { - r *= r; - if (x2 + z2 <= r) { - state = world.getBlockState(POS); - if (state.is(TagAPI.GEN_TERRAIN)) { - BlocksHelper.setWithoutUpdate(world, POS, AIR); - } - pos = POS.below(); - if (world.getBlockState(pos).is(TagAPI.GEN_TERRAIN)) { - state = world.getBiome(pos).getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - if (y > waterLevel + 1) - BlocksHelper.setWithoutUpdate(world, pos, state); - else if (y > waterLevel) - BlocksHelper.setWithoutUpdate(world, pos, random.nextBoolean() ? state : EndBlocks.ENDSTONE_DUST.defaultBlockState()); - else - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.ENDSTONE_DUST.defaultBlockState()); - } - } - } - else { - break; - } - } - } - } - } - - double aspect = ((double) radius / (double) depth); - - for (int x = blockPos.getX() - dist; x <= blockPos.getX() + dist; x++) { - POS.setX(x); - int x2 = x - blockPos.getX(); - x2 *= x2; - int mx = x - maskMinX; - for (int z = blockPos.getZ() - dist; z <= blockPos.getZ() + dist; z++) { - POS.setZ(z); - int z2 = z - blockPos.getZ(); - z2 *= z2; - int mz = z - maskMinZ; - if (!mask[mx][mz]) { - for (int y = blockPos.getY() - bott; y < blockPos.getY(); y++) { - POS.setY(y); - double y2 = (double) (y - blockPos.getY()) * aspect; - y2 *= y2; - double r = radius * (NOISE.eval(x * 0.2, y * 0.2, z * 0.2) * 0.25 + 0.75); - double rb = r * 1.2; - r *= r; - rb *= rb; - if (y2 + x2 + z2 <= r) { - state = world.getBlockState(POS); - if (canReplace(state)) { - state = world.getBlockState(POS.above()); - state = canReplace(state) ? (y < waterLevel ? WATER : AIR) : state; - BlocksHelper.setWithoutUpdate(world, POS, state); - } - pos = POS.below(); - if (world.getBlockState(pos).getBlock().is(TagAPI.GEN_TERRAIN)) { - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.ENDSTONE_DUST.defaultBlockState()); - } - pos = POS.above(); - while (canReplace(state = world.getBlockState(pos)) && !state.isAir() && state.getFluidState().isEmpty()) { - BlocksHelper.setWithoutUpdate(world, pos, pos.getY() < waterLevel ? WATER : AIR); - pos = pos.above(); - } - } - // Make border - else if (y2 + x2 + z2 <= rb) { - state = world.getBlockState(POS); - if (state.is(TagAPI.GEN_TERRAIN) && world.isEmptyBlock(POS.above())) { - BlocksHelper.setWithoutUpdate(world, POS, EndBlocks.END_MOSS); - } - else if (y < waterLevel) { - if (world.isEmptyBlock(POS.above())) { - state = world.getBiome(POS).getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - BlocksHelper.setWithoutUpdate(world, POS, random.nextBoolean() ? state : EndBlocks.ENDSTONE_DUST.defaultBlockState()); - BlocksHelper.setWithoutUpdate(world, POS.below(), END_STONE); - } - else { - BlocksHelper.setWithoutUpdate(world, POS, EndBlocks.ENDSTONE_DUST.defaultBlockState()); - BlocksHelper.setWithoutUpdate(world, POS.below(), END_STONE); - } - } - } - } - } - } - } - - BlockFixer.fixBlocks(world, new BlockPos(minX - 2, waterLevel - 2, minZ - 2), new BlockPos(maxX + 2, blockPos.getY() + 20, maxZ + 2)); - - return true; - } - - private boolean canReplace(BlockState state) { - return state.getMaterial().isReplaceable() - || state.is(TagAPI.GEN_TERRAIN) - || state.is(EndBlocks.ENDSTONE_DUST) - || state.getMaterial().equals(Material.PLANT) - || state.getMaterial().equals(Material.WATER_PLANT) - || state.getMaterial().equals(Material.CORAL); - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/EndLakeFeature.java b/src/main/java/ru/betterend/world/features/terrain/EndLakeFeature.java deleted file mode 100644 index 55075fcb..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/EndLakeFeature.java +++ /dev/null @@ -1,205 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; -import ru.betterend.util.BlockFixer; - -public class EndLakeFeature extends DefaultFeature { - private static final BlockState END_STONE = Blocks.END_STONE.defaultBlockState(); - private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(15152); - private static final MutableBlockPos POS = new MutableBlockPos(); - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, NoneFeatureConfiguration featureConfig) { - double radius = MHelper.randRange(10.0, 20.0, random); - double depth = radius * 0.5 * MHelper.randRange(0.8, 1.2, random); - int dist = MHelper.floor(radius); - int dist2 = MHelper.floor(radius * 1.5); - int bott = MHelper.floor(depth); - blockPos = getPosOnSurfaceWG(world, blockPos); - - if (blockPos.getY() < 10) return false; - - int waterLevel = blockPos.getY(); - - BlockPos pos = getPosOnSurfaceRaycast(world, blockPos.north(dist).above(10), 20); - if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; - waterLevel = MHelper.min(pos.getY(), waterLevel); - - pos = getPosOnSurfaceRaycast(world, blockPos.south(dist).above(10), 20); - if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; - waterLevel = MHelper.min(pos.getY(), waterLevel); - - pos = getPosOnSurfaceRaycast(world, blockPos.east(dist).above(10), 20); - if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; - waterLevel = MHelper.min(pos.getY(), waterLevel); - - pos = getPosOnSurfaceRaycast(world, blockPos.west(dist).above(10), 20); - if (Math.abs(blockPos.getY() - pos.getY()) > 5) return false; - waterLevel = MHelper.min(pos.getY(), waterLevel); - BlockState state; - - int minX = blockPos.getX() - dist2; - int maxX = blockPos.getX() + dist2; - int minZ = blockPos.getZ() - dist2; - int maxZ = blockPos.getZ() + dist2; - int maskMinX = minX - 1; - int maskMinZ = minZ - 1; - - boolean[][] mask = new boolean[maxX - minX + 3][maxZ - minZ + 3]; - for (int x = minX; x <= maxX; x++) { - POS.setX(x); - int mx = x - maskMinX; - for (int z = minZ; z <= maxZ; z++) { - POS.setZ(z); - int mz = z - maskMinZ; - if (!mask[mx][mz]) { - for (int y = waterLevel + 1; y <= waterLevel + 20; y++) { - POS.setY(y); - FluidState fluid = world.getFluidState(POS); - if (!fluid.isEmpty()) { - for (int i = -1; i < 2; i++) { - int px = mx + i; - for (int j = -1; j < 2; j++) { - int pz = mz + j; - mask[px][pz] = true; - } - } - break; - } - } - } - } - } - - for (int x = minX; x <= maxX; x++) { - POS.setX(x); - int x2 = x - blockPos.getX(); - x2 *= x2; - int mx = x - maskMinX; - for (int z = minZ; z <= maxZ; z++) { - POS.setZ(z); - int z2 = z - blockPos.getZ(); - z2 *= z2; - int mz = z - maskMinZ; - if (!mask[mx][mz]) { - double size = 1; - for (int y = blockPos.getY(); y <= blockPos.getY() + 20; y++) { - POS.setY(y); - double add = y - blockPos.getY(); - if (add > 5) { - size *= 0.8; - add = 5; - } - double r = (add * 1.8 + radius * (NOISE.eval(x * 0.2, y * 0.2, z * 0.2) * 0.25 + 0.75)) - 1.0 / size; - if (r > 0) { - r *= r; - if (x2 + z2 <= r) { - state = world.getBlockState(POS); - if (state.is(TagAPI.GEN_TERRAIN)) { - BlocksHelper.setWithoutUpdate(world, POS, AIR); - } - pos = POS.below(); - if (world.getBlockState(pos).is(TagAPI.GEN_TERRAIN)) { - state = world.getBiome(pos).getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - if (y > waterLevel + 1) - BlocksHelper.setWithoutUpdate(world, pos, state); - else if (y > waterLevel) - BlocksHelper.setWithoutUpdate(world, pos, random.nextBoolean() ? state : EndBlocks.ENDSTONE_DUST.defaultBlockState()); - else - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.ENDSTONE_DUST.defaultBlockState()); - } - } - } - else { - break; - } - } - } - } - } - - double aspect = ((double) radius / (double) depth); - - for (int x = blockPos.getX() - dist; x <= blockPos.getX() + dist; x++) { - POS.setX(x); - int x2 = x - blockPos.getX(); - x2 *= x2; - int mx = x - maskMinX; - for (int z = blockPos.getZ() - dist; z <= blockPos.getZ() + dist; z++) { - POS.setZ(z); - int z2 = z - blockPos.getZ(); - z2 *= z2; - int mz = z - maskMinZ; - if (!mask[mx][mz]) { - for (int y = blockPos.getY() - bott; y < blockPos.getY(); y++) { - POS.setY(y); - double y2 = (double) (y - blockPos.getY()) * aspect; - y2 *= y2; - double r = radius * (NOISE.eval(x * 0.2, y * 0.2, z * 0.2) * 0.25 + 0.75); - double rb = r * 1.2; - r *= r; - rb *= rb; - if (y2 + x2 + z2 <= r) { - state = world.getBlockState(POS); - if (canReplace(state)) { - state = world.getBlockState(POS.above()); - state = canReplace(state) ? (y < waterLevel ? WATER : AIR) : state; - BlocksHelper.setWithoutUpdate(world, POS, state); - } - pos = POS.below(); - if (world.getBlockState(pos).getBlock().is(TagAPI.GEN_TERRAIN)) { - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.ENDSTONE_DUST.defaultBlockState()); - } - pos = POS.above(); - while (canReplace(state = world.getBlockState(pos)) && !state.isAir() && state.getFluidState().isEmpty()) { - BlocksHelper.setWithoutUpdate(world, pos, pos.getY() < waterLevel ? WATER : AIR); - pos = pos.above(); - } - } - // Make border - else if (y < waterLevel && y2 + x2 + z2 <= rb) { - if (world.isEmptyBlock(POS.above())) { - state = world.getBiome(POS).getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - BlocksHelper.setWithoutUpdate(world, POS, random.nextBoolean() ? state : EndBlocks.ENDSTONE_DUST.defaultBlockState()); - BlocksHelper.setWithoutUpdate(world, POS.below(), END_STONE); - } - else { - BlocksHelper.setWithoutUpdate(world, POS, EndBlocks.ENDSTONE_DUST.defaultBlockState()); - BlocksHelper.setWithoutUpdate(world, POS.below(), END_STONE); - } - } - } - } - } - } - - BlockFixer.fixBlocks(world, new BlockPos(minX - 2, waterLevel - 2, minZ - 2), new BlockPos(maxX + 2, blockPos.getY() + 20, maxZ + 2)); - - return true; - } - - private boolean canReplace(BlockState state) { - return state.getMaterial().isReplaceable() - || state.is(TagAPI.GEN_TERRAIN) - || state.is(EndBlocks.ENDSTONE_DUST) - || state.getMaterial().equals(Material.PLANT) - || state.getMaterial().equals(Material.WATER_PLANT) - || state.getMaterial().equals(Material.CORAL); - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/FallenPillarFeature.java b/src/main/java/ru/betterend/world/features/terrain/FallenPillarFeature.java deleted file mode 100644 index f0b9e545..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/FallenPillarFeature.java +++ /dev/null @@ -1,60 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; - -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFRotation; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFCappedCone; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class FallenPillarFeature extends DefaultFeature { - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, NoneFeatureConfiguration config) { - pos = getPosOnSurface(world, - new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16))); - if (!world.getBlockState(pos.below(5)).is(TagAPI.GEN_TERRAIN)) { - return false; - } - - float height = MHelper.randRange(20F, 40F, random); - float radius = MHelper.randRange(2F, 4F, random); - SDF pillar = new SDFCappedCone().setRadius1(radius).setRadius2(radius).setHeight(height * 0.5F) - .setBlock(Blocks.OBSIDIAN); - pillar = new SDFTranslate().setTranslate(0, radius * 0.5F - 2, 0).setSource(pillar); - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); - pillar = new SDFDisplacement().setFunction((vec) -> { - return (float) (noise.eval(vec.x() * 0.3, vec.y() * 0.3, vec.z() * 0.3) * 0.5F); - }).setSource(pillar); - Vector3f vec = MHelper.randomHorizontal(random); - float angle = (float) random.nextGaussian() * 0.05F + (float) Math.PI; - pillar = new SDFRotation().setRotation(vec, angle).setSource(pillar); - - BlockState mossy = EndBlocks.MOSSY_OBSIDIAN.defaultBlockState(); - pillar.addPostProcess((info) -> { - if (info.getStateUp().isAir() && random.nextFloat() > 0.1F) { - return mossy; - } - return info.getState(); - }).setReplaceFunction((state) -> { - return state.getMaterial().isReplaceable() || state.is(TagAPI.GEN_TERRAIN) - || state.getMaterial().equals(Material.PLANT); - }).fillRecursive(world, pos); - - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/FloatingSpireFeature.java b/src/main/java/ru/betterend/world/features/terrain/FloatingSpireFeature.java deleted file mode 100644 index af955ffe..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/FloatingSpireFeature.java +++ /dev/null @@ -1,73 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.List; -import java.util.Random; - -import com.google.common.collect.Lists; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.api.BiomeAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.MHelper; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBiomes; -import ru.betterend.registry.EndFeatures; - -public class FloatingSpireFeature extends SpireFeature { - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - int minY = getYOnSurface(world, pos.getX(), pos.getZ()); - int y = minY > 57 ? MHelper.floor(MHelper.randRange(minY, minY * 2, random) * 0.5F + 32) - : MHelper.randRange(64, 192, random); - pos = new BlockPos(pos.getX(), y, pos.getZ()); - - SDF sdf = new SDFSphere().setRadius(MHelper.randRange(2, 3, random)).setBlock(Blocks.END_STONE); - int count = MHelper.randRange(3, 5, random); - - for (int i = 0; i < count; i++) { - float rMin = (i * 1.3F) + 2.5F; - sdf = addSegment(sdf, MHelper.randRange(rMin, rMin + 1.5F, random), random); - } - for (int i = count - 1; i > 0; i--) { - float rMin = (i * 1.3F) + 2.5F; - sdf = addSegment(sdf, MHelper.randRange(rMin, rMin + 1.5F, random), random); - } - - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); - sdf = new SDFDisplacement().setFunction((vec) -> { - return (float) (Math.abs(noise.eval(vec.x() * 0.1, vec.y() * 0.1, vec.z() * 0.1)) * 3F - + Math.abs(noise.eval(vec.x() * 0.3, vec.y() * 0.3 + 100, vec.z() * 0.3)) * 1.3F); - }).setSource(sdf); - final BlockPos center = pos; - List support = Lists.newArrayList(); - sdf.setReplaceFunction(REPLACE).addPostProcess((info) -> { - if (info.getStateUp().isAir()) { - if (random.nextInt(16) == 0) { - support.add(info.getPos().above()); - } - return world.getBiome(info.getPos()).getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - } else if (info.getState(Direction.UP, 3).isAir()) { - return world.getBiome(info.getPos()).getGenerationSettings().getSurfaceBuilderConfig() - .getUnderMaterial(); - } - return info.getState(); - }); - sdf.fillRecursive(world, center); - - support.forEach((bpos) -> { - if (BiomeAPI.getFromBiome(world.getBiome(bpos)) == EndBiomes.BLOSSOMING_SPIRES) { - EndFeatures.TENANEA_BUSH.getFeature().place(world, chunkGenerator, random, bpos, null); - } - }); - - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/GeyserFeature.java b/src/main/java/ru/betterend/world/features/terrain/GeyserFeature.java deleted file mode 100644 index 61da80ad..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/GeyserFeature.java +++ /dev/null @@ -1,273 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; -import java.util.function.Function; - -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.util.Mth; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.HorizontalDirectionalBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFCoordModify; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFInvert; -import ru.bclib.sdf.operator.SDFRotation; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.operator.SDFSmoothUnion; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.operator.SDFUnion; -import ru.bclib.sdf.primitive.SDFCappedCone; -import ru.bclib.sdf.primitive.SDFFlatland; -import ru.bclib.sdf.primitive.SDFPrimitive; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.HydrothermalVentBlock; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndFeatures; -import ru.betterend.util.BlockFixer; - -public class GeyserFeature extends DefaultFeature { - protected static final Function REPLACE1; - protected static final Function REPLACE2; - private static final Function IGNORE; - private static final Direction[] HORIZONTAL = BlocksHelper.makeHorizontal(); - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - pos = getPosOnSurfaceWG(world, pos); - - if (pos.getY() < 10) { - return false; - } - - MutableBlockPos bpos = new MutableBlockPos().set(pos); - bpos.setY(bpos.getY() - 1); - BlockState state = world.getBlockState(bpos); - while (state.is(TagAPI.GEN_TERRAIN) || !state.getFluidState().isEmpty() && bpos.getY() > 5) { - bpos.setY(bpos.getY() - 1); - state = world.getBlockState(bpos); - } - - if (pos.getY() - bpos.getY() < 25) { - return false; - } - - int halfHeight = MHelper.randRange(10, 20, random); - float radius1 = halfHeight * 0.5F; - float radius2 = halfHeight * 0.1F + 0.5F; - SDF sdf = new SDFCappedCone().setHeight(halfHeight).setRadius1(radius1).setRadius2(radius2) - .setBlock(EndBlocks.SULPHURIC_ROCK.stone); - sdf = new SDFTranslate().setTranslate(0, halfHeight - 3, 0).setSource(sdf); - - int count = halfHeight; - for (int i = 0; i < count; i++) { - int py = i << 1; - float delta = (float) i / (float) (count - 1); - float radius = Mth.lerp(delta, radius1, radius2) * 1.3F; - - SDF bowl = new SDFCappedCone().setHeight(radius).setRadius1(0).setRadius2(radius) - .setBlock(EndBlocks.SULPHURIC_ROCK.stone); - - SDF brimstone = new SDFCappedCone().setHeight(radius).setRadius1(0).setRadius2(radius) - .setBlock(EndBlocks.BRIMSTONE); - brimstone = new SDFTranslate().setTranslate(0, 2F, 0).setSource(brimstone); - bowl = new SDFSubtraction().setSourceA(bowl).setSourceB(brimstone); - bowl = new SDFUnion().setSourceA(brimstone).setSourceB(bowl); - - SDF water = new SDFCappedCone().setHeight(radius).setRadius1(0).setRadius2(radius).setBlock(Blocks.WATER); - water = new SDFTranslate().setTranslate(0, 4, 0).setSource(water); - bowl = new SDFSubtraction().setSourceA(bowl).setSourceB(water); - bowl = new SDFUnion().setSourceA(water).setSourceB(bowl); - - final OpenSimplexNoise noise1 = new OpenSimplexNoise(random.nextLong()); - final OpenSimplexNoise noise2 = new OpenSimplexNoise(random.nextLong()); - - bowl = new SDFCoordModify().setFunction((vec) -> { - float dx = (float) noise1.eval(vec.x() * 0.1, vec.y() * 0.1, vec.z() * 0.1); - float dz = (float) noise2.eval(vec.x() * 0.1, vec.y() * 0.1, vec.z() * 0.1); - vec.set(vec.x() + dx, vec.y(), vec.z() + dz); - }).setSource(bowl); - - SDF cut = new SDFFlatland().setBlock(Blocks.AIR); - cut = new SDFInvert().setSource(cut); - cut = new SDFTranslate().setTranslate(0, radius - 2, 0).setSource(cut); - bowl = new SDFSubtraction().setSourceA(bowl).setSourceB(cut); - - bowl = new SDFTranslate().setTranslate(radius, py - radius, 0).setSource(bowl); - bowl = new SDFRotation().setRotation(Vector3f.YP, i * 4F).setSource(bowl); - sdf = new SDFUnion().setSourceA(sdf).setSourceB(bowl); - } - sdf.setReplaceFunction(REPLACE2).fillRecursive(world, pos); - - radius2 = radius2 * 0.5F; - if (radius2 < 0.7F) { - radius2 = 0.7F; - } - final OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); - - SDFPrimitive obj1; - SDFPrimitive obj2; - - obj1 = new SDFCappedCone().setHeight(halfHeight + 5).setRadius1(radius1 * 0.5F).setRadius2(radius2); - sdf = new SDFTranslate().setTranslate(0, halfHeight - 13, 0).setSource(obj1); - sdf = new SDFDisplacement().setFunction((vec) -> { - return (float) noise.eval(vec.x() * 0.3F, vec.y() * 0.3F, vec.z() * 0.3F) * 0.5F; - }).setSource(sdf); - - obj2 = new SDFSphere().setRadius(radius1); - SDF cave = new SDFScale3D().setScale(1.5F, 1, 1.5F).setSource(obj2); - cave = new SDFDisplacement().setFunction((vec) -> { - return (float) noise.eval(vec.x() * 0.1F, vec.y() * 0.1F, vec.z() * 0.1F) * 2F; - }).setSource(cave); - cave = new SDFTranslate().setTranslate(0, -halfHeight - 10, 0).setSource(cave); - - sdf = new SDFSmoothUnion().setRadius(5).setSourceA(cave).setSourceB(sdf); - - obj1.setBlock(WATER); - obj2.setBlock(WATER); - sdf.setReplaceFunction(REPLACE2); - sdf.fillRecursive(world, pos); - - obj1.setBlock(EndBlocks.BRIMSTONE); - obj2.setBlock(EndBlocks.BRIMSTONE); - new SDFDisplacement().setFunction((vec) -> { - return -2F; - }).setSource(sdf).setReplaceFunction(REPLACE1).fillRecursiveIgnore(world, pos, IGNORE); - - obj1.setBlock(EndBlocks.SULPHURIC_ROCK.stone); - obj2.setBlock(EndBlocks.SULPHURIC_ROCK.stone); - new SDFDisplacement().setFunction((vec) -> { - return -4F; - }).setSource(cave).setReplaceFunction(REPLACE1).fillRecursiveIgnore(world, pos, IGNORE); - - obj1.setBlock(Blocks.END_STONE); - obj2.setBlock(Blocks.END_STONE); - new SDFDisplacement().setFunction((vec) -> { - return -6F; - }).setSource(cave).setReplaceFunction(REPLACE1).fillRecursiveIgnore(world, pos, IGNORE); - - BlocksHelper.setWithoutUpdate(world, pos, WATER); - MutableBlockPos mut = new MutableBlockPos().set(pos); - count = getYOnSurface(world, pos.getX(), pos.getZ()) - pos.getY(); - for (int i = 0; i < count; i++) { - BlocksHelper.setWithoutUpdate(world, mut, WATER); - for (Direction dir : BlocksHelper.HORIZONTAL) { - BlocksHelper.setWithoutUpdate(world, mut.relative(dir), WATER); - } - mut.setY(mut.getY() + 1); - } - - for (int i = 0; i < 150; i++) { - mut.set(pos).move(MHelper.floor(random.nextGaussian() * 4 + 0.5), -halfHeight - 10, - MHelper.floor(random.nextGaussian() * 4 + 0.5)); - float distRaw = MHelper.length(mut.getX() - pos.getX(), mut.getZ() - pos.getZ()); - int dist = MHelper.floor(6 - distRaw) + random.nextInt(2); - if (dist >= 0) { - state = world.getBlockState(mut); - while (!state.getFluidState().isEmpty() || state.getMaterial().equals(Material.WATER_PLANT)) { - mut.setY(mut.getY() - 1); - state = world.getBlockState(mut); - } - if (state.is(TagAPI.GEN_TERRAIN) - && !world.getBlockState(mut.above()).is(EndBlocks.HYDROTHERMAL_VENT)) { - for (int j = 0; j <= dist; j++) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.SULPHURIC_ROCK.stone); - MHelper.shuffle(HORIZONTAL, random); - for (Direction dir : HORIZONTAL) { - BlockPos p = mut.relative(dir); - if (random.nextBoolean() && world.getBlockState(p).is(Blocks.WATER)) { - BlocksHelper.setWithoutUpdate(world, p, EndBlocks.TUBE_WORM.defaultBlockState() - .setValue(HorizontalDirectionalBlock.FACING, dir)); - } - } - mut.setY(mut.getY() + 1); - } - state = EndBlocks.HYDROTHERMAL_VENT.defaultBlockState().setValue(HydrothermalVentBlock.ACTIVATED, - distRaw < 2); - BlocksHelper.setWithoutUpdate(world, mut, state); - mut.setY(mut.getY() + 1); - state = world.getBlockState(mut); - while (state.is(Blocks.WATER)) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.VENT_BUBBLE_COLUMN.defaultBlockState()); - mut.setY(mut.getY() + 1); - state = world.getBlockState(mut); - } - } - } - } - - for (int i = 0; i < 10; i++) { - mut.set(pos).move(MHelper.floor(random.nextGaussian() * 0.7 + 0.5), -halfHeight - 10, - MHelper.floor(random.nextGaussian() * 0.7 + 0.5)); - float distRaw = MHelper.length(mut.getX() - pos.getX(), mut.getZ() - pos.getZ()); - int dist = MHelper.floor(6 - distRaw) + random.nextInt(2); - if (dist >= 0) { - state = world.getBlockState(mut); - while (state.is(Blocks.WATER)) { - mut.setY(mut.getY() - 1); - state = world.getBlockState(mut); - } - if (state.is(TagAPI.GEN_TERRAIN)) { - for (int j = 0; j <= dist; j++) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.SULPHURIC_ROCK.stone); - mut.setY(mut.getY() + 1); - } - state = EndBlocks.HYDROTHERMAL_VENT.defaultBlockState().setValue(HydrothermalVentBlock.ACTIVATED, - distRaw < 2); - BlocksHelper.setWithoutUpdate(world, mut, state); - mut.setY(mut.getY() + 1); - state = world.getBlockState(mut); - while (state.is(Blocks.WATER)) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.VENT_BUBBLE_COLUMN.defaultBlockState()); - mut.setY(mut.getY() + 1); - state = world.getBlockState(mut); - } - } - } - } - - EndFeatures.SULPHURIC_LAKE.getFeature().place(world, chunkGenerator, random, pos, null); - - double distance = radius1 * 1.7; - BlockPos start = pos.offset(-distance, -halfHeight - 15 - distance, -distance); - BlockPos end = pos.offset(distance, -halfHeight - 5 + distance, distance); - BlockFixer.fixBlocks(world, start, end); - - return true; - } - - static { - REPLACE1 = (state) -> { - return state.isAir() || (state.is(TagAPI.GEN_TERRAIN)); - }; - - REPLACE2 = (state) -> { - if (state.is(TagAPI.GEN_TERRAIN) || state.is(EndBlocks.HYDROTHERMAL_VENT) || state.is(EndBlocks.SULPHUR_CRYSTAL)) { - return true; - } - if (state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - - IGNORE = (state) -> { - return state.is(Blocks.WATER) || state.is(Blocks.CAVE_AIR) || state.is(EndBlocks.SULPHURIC_ROCK.stone) || state.is(EndBlocks.BRIMSTONE); - }; - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/IceStarFeature.java b/src/main/java/ru/betterend/world/features/terrain/IceStarFeature.java deleted file mode 100644 index c76424ff..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/IceStarFeature.java +++ /dev/null @@ -1,107 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFRotation; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.operator.SDFUnion; -import ru.bclib.sdf.primitive.SDFCappedCone; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.registry.EndBlocks; - -public class IceStarFeature extends DefaultFeature { - private final float minSize; - private final float maxSize; - private final int minCount; - private final int maxCount; - - public IceStarFeature(float minSize, float maxSize, int minCount, int maxCount) { - this.minSize = minSize; - this.maxSize = maxSize; - this.minCount = minCount; - this.maxCount = maxCount; - } - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - float size = MHelper.randRange(minSize, maxSize, random); - int count = MHelper.randRange(minCount, maxCount, random); - List points = getFibonacciPoints(count); - SDF sdf = null; - SDF spike = new SDFCappedCone().setRadius1(3 + (size - 5) * 0.2F).setRadius2(0).setHeight(size) - .setBlock(EndBlocks.DENSE_SNOW); - spike = new SDFTranslate().setTranslate(0, size - 0.5F, 0).setSource(spike); - for (Vector3f point : points) { - SDF rotated = spike; - point = MHelper.normalize(point); - float angle = MHelper.angle(Vector3f.YP, point); - if (angle > 0.01F && angle < 3.14F) { - Vector3f axis = MHelper.normalize(MHelper.cross(Vector3f.YP, point)); - rotated = new SDFRotation().setRotation(axis, angle).setSource(spike); - } else if (angle > 1) { - rotated = new SDFRotation().setRotation(Vector3f.YP, (float) Math.PI).setSource(spike); - } - sdf = (sdf == null) ? rotated : new SDFUnion().setSourceA(sdf).setSourceB(rotated); - } - - int x1 = (pos.getX() >> 4) << 4; - int z1 = (pos.getZ() >> 4) << 4; - pos = new BlockPos(x1 + random.nextInt(16), MHelper.randRange(32, 128, random), z1 + random.nextInt(16)); - - final float ancientRadius = size * 0.7F; - final float denseRadius = size * 0.9F; - final float iceRadius = size < 7 ? size * 5 : size * 1.3F; - final float randScale = size * 0.3F; - - final BlockPos center = pos; - final BlockState ice = EndBlocks.EMERALD_ICE.defaultBlockState(); - final BlockState dense = EndBlocks.DENSE_EMERALD_ICE.defaultBlockState(); - final BlockState ancient = EndBlocks.ANCIENT_EMERALD_ICE.defaultBlockState(); - final SDF sdfCopy = sdf; - - sdf.addPostProcess((info) -> { - BlockPos bpos = info.getPos(); - float px = bpos.getX() - center.getX(); - float py = bpos.getY() - center.getY(); - float pz = bpos.getZ() - center.getZ(); - float distance = MHelper.length(px, py, pz) + sdfCopy.getDistance(px, py, pz) * 0.4F - + random.nextFloat() * randScale; - if (distance < ancientRadius) { - return ancient; - } else if (distance < denseRadius) { - return dense; - } else if (distance < iceRadius) { - return ice; - } - return info.getState(); - }).fillRecursive(world, pos); - - return true; - } - - private List getFibonacciPoints(int count) { - float max = count - 1; - List result = new ArrayList(count); - for (int i = 0; i < count; i++) { - float y = 1F - (i / max) * 2F; - float radius = (float) Math.sqrt(1F - y * y); - float theta = MHelper.PHI * i; - float x = (float) Math.cos(theta) * radius; - float z = (float) Math.sin(theta) * radius; - result.add(new Vector3f(x, y, z)); - } - return result; - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/ObsidianBoulderFeature.java b/src/main/java/ru/betterend/world/features/terrain/ObsidianBoulderFeature.java deleted file mode 100644 index 840f53f1..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/ObsidianBoulderFeature.java +++ /dev/null @@ -1,69 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class ObsidianBoulderFeature extends DefaultFeature { - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - pos = getPosOnSurface(world, - new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16))); - if (!world.getBlockState(pos.below()).is(TagAPI.END_GROUND)) { - return false; - } - - int count = MHelper.randRange(1, 5, random); - for (int i = 0; i < count; i++) { - BlockPos p = getPosOnSurface(world, - new BlockPos(pos.getX() + random.nextInt(16) - 8, pos.getY(), pos.getZ() + random.nextInt(16) - 8)); - makeBoulder(world, p, random); - } - - return true; - } - - private void makeBoulder(WorldGenLevel world, BlockPos pos, Random random) { - if (!world.getBlockState(pos.below()).is(TagAPI.END_GROUND)) { - return; - } - - float radius = MHelper.randRange(1F, 5F, random); - SDF sphere = new SDFSphere().setRadius(radius).setBlock(Blocks.OBSIDIAN); - float sx = MHelper.randRange(0.7F, 1.3F, random); - float sy = MHelper.randRange(0.7F, 1.3F, random); - float sz = MHelper.randRange(0.7F, 1.3F, random); - sphere = new SDFScale3D().setScale(sx, sy, sz).setSource(sphere); - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); - sphere = new SDFDisplacement().setFunction((vec) -> { - return (float) (noise.eval(vec.x() * 0.2, vec.y() * 0.2, vec.z() * 0.2) * 1.5F); - }).setSource(sphere); - - BlockState mossy = EndBlocks.MOSSY_OBSIDIAN.defaultBlockState(); - sphere.addPostProcess((info) -> { - if (info.getStateUp().isAir() && random.nextFloat() > 0.1F) { - return mossy; - } - return info.getState(); - }).setReplaceFunction((state) -> { - return state.getMaterial().isReplaceable() || state.is(TagAPI.GEN_TERRAIN) - || state.getMaterial().equals(Material.PLANT); - }).fillRecursive(world, pos); - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/ObsidianPillarBasementFeature.java b/src/main/java/ru/betterend/world/features/terrain/ObsidianPillarBasementFeature.java deleted file mode 100644 index 3106db14..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/ObsidianPillarBasementFeature.java +++ /dev/null @@ -1,64 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; - -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFRotation; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFCappedCone; -import ru.bclib.sdf.primitive.SDFFlatland; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class ObsidianPillarBasementFeature extends DefaultFeature { - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, NoneFeatureConfiguration config) { - pos = getPosOnSurface(world, new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16))); - if (!world.getBlockState(pos.below(5)).is(TagAPI.GEN_TERRAIN)) { - return false; - } - - float height = MHelper.randRange(10F, 35F, random); - float radius = MHelper.randRange(2F, 5F, random); - SDF pillar = new SDFCappedCone().setRadius1(radius).setRadius2(radius).setHeight(height * 0.5F).setBlock(Blocks.OBSIDIAN); - pillar = new SDFTranslate().setTranslate(0, height * 0.5F - 3, 0).setSource(pillar); - SDF cut = new SDFFlatland().setBlock(Blocks.OBSIDIAN); - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); - cut = new SDFDisplacement().setFunction((vec) -> { - return (float) (noise.eval(vec.x() * 0.2, vec.z() * 0.2) * 3); - }).setSource(cut); - Vector3f vec = MHelper.randomHorizontal(random); - float angle = random.nextFloat() * 0.5F + (float) Math.PI; - cut = new SDFRotation().setRotation(vec, angle).setSource(cut); - cut = new SDFTranslate().setTranslate(0, height * 0.7F - 3, 0).setSource(cut); - pillar = new SDFSubtraction().setSourceA(pillar).setSourceB(cut); - vec = MHelper.randomHorizontal(random); - angle = random.nextFloat() * 0.2F; - pillar = new SDFRotation().setRotation(vec, angle).setSource(pillar); - BlockState mossy = EndBlocks.MOSSY_OBSIDIAN.defaultBlockState(); - pillar.addPostProcess((info) -> { - if (info.getStateUp().isAir() && random.nextFloat() > 0.1F) { - return mossy; - } - return info.getState(); - }).setReplaceFunction((state) -> { - return state.getMaterial().isReplaceable() || state.is(TagAPI.GEN_TERRAIN) || state.getMaterial().equals(Material.PLANT); - }).fillRecursive(world, pos); - - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/OreLayerFeature.java b/src/main/java/ru/betterend/world/features/terrain/OreLayerFeature.java deleted file mode 100644 index 0bbb70ea..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/OreLayerFeature.java +++ /dev/null @@ -1,74 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFCoordModify; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; - -public class OreLayerFeature extends DefaultFeature { - private static final SDFSphere SPHERE; - private static final SDFCoordModify NOISE; - private static final SDF FUNCTION; - - private final BlockState state; - private final float radius; - private final int minY; - private final int maxY; - private OpenSimplexNoise noise; - - public OreLayerFeature(BlockState state, float radius, int minY, int maxY) { - this.state = state; - this.radius = radius; - this.minY = minY; - this.maxY = maxY; - } - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - float radius = this.radius * 0.5F; - int r = MHelper.floor(radius + 1); - int posX = MHelper.randRange(Math.max(r - 16, 0), Math.min(31 - r, 15), random) + pos.getX(); - int posZ = MHelper.randRange(Math.max(r - 16, 0), Math.min(31 - r, 15), random) + pos.getZ(); - int posY = MHelper.randRange(minY, maxY, random); - - if (noise == null) { - noise = new OpenSimplexNoise(world.getSeed()); - } - - SPHERE.setRadius(radius).setBlock(state); - NOISE.setFunction((vec) -> { - double x = (vec.x() + pos.getX()) * 0.1; - double z = (vec.z() + pos.getZ()) * 0.1; - double offset = noise.eval(x, z); - vec.set(vec.x(), vec.y() + (float) offset * 8, vec.z()); - }); - FUNCTION.fillRecursive(world, new BlockPos(posX, posY, posZ)); - return true; - } - - static { - SPHERE = new SDFSphere(); - NOISE = new SDFCoordModify(); - - SDF body = SPHERE; - body = new SDFScale3D().setScale(1, 0.2F, 1).setSource(body); - body = NOISE.setSource(body); - body.setReplaceFunction((state) -> { - return state.is(Blocks.END_STONE); - }); - - FUNCTION = body; - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/SingleBlockFeature.java b/src/main/java/ru/betterend/world/features/terrain/SingleBlockFeature.java deleted file mode 100644 index 8fceba8d..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/SingleBlockFeature.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.world.features.DefaultFeature; - -public class SingleBlockFeature extends DefaultFeature { - private final Block block; - - public SingleBlockFeature(Block block) { - this.block = block; - } - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).is(TagAPI.GEN_TERRAIN)) { - return false; - } - - BlockState state = block.defaultBlockState(); - if (block.getStateDefinition().getProperty("waterlogged") != null) { - boolean waterlogged = !world.getFluidState(pos).isEmpty(); - state = state.setValue(BlockStateProperties.WATERLOGGED, waterlogged); - } - BlocksHelper.setWithoutUpdate(world, pos, state); - - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/SmaragdantCrystalFeature.java b/src/main/java/ru/betterend/world/features/terrain/SmaragdantCrystalFeature.java deleted file mode 100644 index 447138b1..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/SmaragdantCrystalFeature.java +++ /dev/null @@ -1,55 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.registry.EndBlocks; - -public class SmaragdantCrystalFeature extends DefaultFeature { - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).is(TagAPI.GEN_TERRAIN)) { - return false; - } - - MutableBlockPos mut = new MutableBlockPos(); - int count = MHelper.randRange(15, 30, random); - BlockState crystal = EndBlocks.SMARAGDANT_CRYSTAL.defaultBlockState(); - BlockState shard = EndBlocks.SMARAGDANT_CRYSTAL_SHARD.defaultBlockState(); - for (int i = 0; i < count; i++) { - mut.set(pos).move(MHelper.floor(random.nextGaussian() * 2 + 0.5), 5, - MHelper.floor(random.nextGaussian() * 2 + 0.5)); - int dist = MHelper.floor(1.5F - MHelper.length(mut.getX() - pos.getX(), mut.getZ() - pos.getZ())) - + random.nextInt(3); - if (dist > 0) { - BlockState state = world.getBlockState(mut); - for (int n = 0; n < 10 && state.isAir(); n++) { - mut.setY(mut.getY() - 1); - state = world.getBlockState(mut); - } - if (state.is(TagAPI.GEN_TERRAIN) && !world.getBlockState(mut.above()).is(crystal.getBlock())) { - for (int j = 0; j <= dist; j++) { - BlocksHelper.setWithoutUpdate(world, mut, crystal); - mut.setY(mut.getY() + 1); - } - boolean waterlogged = !world.getFluidState(mut).isEmpty(); - BlocksHelper.setWithoutUpdate(world, mut, - shard.setValue(BlockStateProperties.WATERLOGGED, waterlogged)); - } - } - } - - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/SpireFeature.java b/src/main/java/ru/betterend/world/features/terrain/SpireFeature.java deleted file mode 100644 index bf14a674..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/SpireFeature.java +++ /dev/null @@ -1,99 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.List; -import java.util.Random; -import java.util.function.Function; - -import com.google.common.collect.Lists; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.LeavesBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.BiomeAPI; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFSmoothUnion; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBiomes; -import ru.betterend.registry.EndFeatures; - -public class SpireFeature extends DefaultFeature { - protected static final Function REPLACE; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - pos = getPosOnSurfaceWG(world, pos); - if (pos.getY() < 10 || !world.getBlockState(pos.below(3)).is(TagAPI.GEN_TERRAIN) - || !world.getBlockState(pos.below(6)).is(TagAPI.GEN_TERRAIN)) { - return false; - } - - SDF sdf = new SDFSphere().setRadius(MHelper.randRange(2, 3, random)).setBlock(Blocks.END_STONE); - int count = MHelper.randRange(3, 7, random); - for (int i = 0; i < count; i++) { - float rMin = (i * 1.3F) + 2.5F; - sdf = addSegment(sdf, MHelper.randRange(rMin, rMin + 1.5F, random), random); - } - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); - sdf = new SDFDisplacement().setFunction((vec) -> { - return (float) (Math.abs(noise.eval(vec.x() * 0.1, vec.y() * 0.1, vec.z() * 0.1)) * 3F - + Math.abs(noise.eval(vec.x() * 0.3, vec.y() * 0.3 + 100, vec.z() * 0.3)) * 1.3F); - }).setSource(sdf); - final BlockPos center = pos; - List support = Lists.newArrayList(); - sdf.setReplaceFunction(REPLACE).addPostProcess((info) -> { - if (info.getStateUp().isAir()) { - if (random.nextInt(16) == 0) { - support.add(info.getPos().above()); - } - return world.getBiome(info.getPos()).getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - } else if (info.getState(Direction.UP, 3).isAir()) { - return world.getBiome(info.getPos()).getGenerationSettings().getSurfaceBuilderConfig() - .getUnderMaterial(); - } - return info.getState(); - }).fillRecursive(world, center); - - support.forEach((bpos) -> { - if (BiomeAPI.getFromBiome(world.getBiome(bpos)) == EndBiomes.BLOSSOMING_SPIRES) { - EndFeatures.TENANEA_BUSH.getFeature().place(world, chunkGenerator, random, bpos, null); - } - }); - - return true; - } - - protected SDF addSegment(SDF sdf, float radius, Random random) { - SDF sphere = new SDFSphere().setRadius(radius).setBlock(Blocks.END_STONE); - SDF offseted = new SDFTranslate().setTranslate(0, radius + random.nextFloat() * 0.25F * radius, 0) - .setSource(sdf); - return new SDFSmoothUnion().setRadius(radius * 0.5F).setSourceA(sphere).setSourceB(offseted); - } - - static { - REPLACE = (state) -> { - if (state.is(TagAPI.END_GROUND)) { - return true; - } - if (state.getBlock() instanceof LeavesBlock) { - return true; - } - if (state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/StalactiteFeature.java b/src/main/java/ru/betterend/world/features/terrain/StalactiteFeature.java deleted file mode 100644 index 06e5bcfb..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/StalactiteFeature.java +++ /dev/null @@ -1,79 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.util.Mth; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.StalactiteBlock; -import ru.bclib.util.BlocksHelper; -import ru.bclib.world.features.DefaultFeature; - -public class StalactiteFeature extends DefaultFeature { - private final boolean ceiling; - private final Block[] ground; - private final Block block; - - public StalactiteFeature(boolean ceiling, Block block, Block... ground) { - this.ceiling = ceiling; - this.ground = ground; - this.block = block; - } - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!isGround(world.getBlockState(ceiling ? pos.above() : pos.below()).getBlock())) { - return false; - } - - MutableBlockPos mut = new MutableBlockPos().set(pos); - int height = random.nextInt(16); - int dir = ceiling ? -1 : 1; - boolean stalagnate = false; - - for (int i = 1; i <= height; i++) { - mut.setY(pos.getY() + i * dir); - BlockState state = world.getBlockState(mut); - if (!state.getMaterial().isReplaceable()) { - stalagnate = state.is(TagAPI.GEN_TERRAIN); - height = i; - break; - } - } - - if (!stalagnate && height > 7) { - height = random.nextInt(8); - } - - float center = height * 0.5F; - for (int i = 0; i < height; i++) { - mut.setY(pos.getY() + i * dir); - int size = stalagnate ? Mth.clamp((int) (Mth.abs(i - center) + 1), 1, 7) : height - i - 1; - boolean waterlogged = !world.getFluidState(mut).isEmpty(); - BlockState base = block.defaultBlockState().setValue(StalactiteBlock.SIZE, size) - .setValue(BlockStateProperties.WATERLOGGED, waterlogged); - BlockState state = stalagnate ? base.setValue(StalactiteBlock.IS_FLOOR, dir > 0 ? i < center : i > center) - : base.setValue(StalactiteBlock.IS_FLOOR, dir > 0); - BlocksHelper.setWithoutUpdate(world, mut, state); - } - - return true; - } - - private boolean isGround(Block block) { - for (Block b : ground) { - if (b == block) { - return true; - } - } - return false; - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/SulphurHillFeature.java b/src/main/java/ru/betterend/world/features/terrain/SulphurHillFeature.java deleted file mode 100644 index eefaf3e7..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/SulphurHillFeature.java +++ /dev/null @@ -1,94 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class SulphurHillFeature extends DefaultFeature { - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - pos = getPosOnSurfaceWG(world, pos); - if (pos.getY() < 57 || pos.getY() > 70) { - return false; - } - - int count = MHelper.randRange(5, 13, random); - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); - for (int i = 0; i < count; i++) { - int dist = count - i; - int px = pos.getX() + MHelper.floor(random.nextGaussian() * dist * 0.6 + 0.5); - int pz = pos.getZ() + MHelper.floor(random.nextGaussian() * dist * 0.6 + 0.5); - int py = getYOnSurface(world, px, pz); - if (py > 56 && py - pos.getY() <= count) { - makeCircle(world, new BlockPos(px, py, pz), noise, random); - } - } - return true; - } - - private void makeCircle(WorldGenLevel world, BlockPos pos, OpenSimplexNoise noise, Random random) { - int radius = MHelper.randRange(5, 9, random); - int min = -radius - 3; - int max = radius + 4; - MutableBlockPos mut = new MutableBlockPos(); - BlockState rock = EndBlocks.SULPHURIC_ROCK.stone.defaultBlockState(); - BlockState brimstone = EndBlocks.BRIMSTONE.defaultBlockState().setValue(BlockProperties.ACTIVE, true); - for (int x = min; x < max; x++) { - int x2 = x * x; - int px = pos.getX() + x; - mut.setX(px); - for (int z = min; z < max; z++) { - int z2 = z * z; - int pz = pos.getZ() + z; - mut.setZ(pz); - double r1 = radius * (noise.eval(px * 0.1, pz * 0.1) * 0.2 + 0.8); - double r2 = r1 - 1.5; - double r3 = r1 - 3; - int d = x2 + z2; - mut.setY(pos.getY()); - BlockState state = world.getBlockState(mut); - if (state.getMaterial().isReplaceable() || state.is(EndBlocks.HYDROTHERMAL_VENT)) { - if (d < r2 * r2) { - BlocksHelper.setWithoutUpdate(world, mut, Blocks.WATER); - mut.move(Direction.DOWN); - if (d < r3 * r3) { - BlocksHelper.setWithoutUpdate(world, mut, Blocks.WATER); - mut.move(Direction.DOWN); - } - BlocksHelper.setWithoutUpdate(world, mut, brimstone); - mut.move(Direction.DOWN); - state = world.getBlockState(mut); - int maxIt = MHelper.floor(10 - Math.sqrt(d)) + random.nextInt(1); - for (int i = 0; i < maxIt && state.getMaterial().isReplaceable(); i++) { - BlocksHelper.setWithoutUpdate(world, mut, rock); - mut.move(Direction.DOWN); - } - } else if (d < r1 * r1) { - BlocksHelper.setWithoutUpdate(world, mut, brimstone); - mut.move(Direction.DOWN); - state = world.getBlockState(mut); - int maxIt = MHelper.floor(10 - Math.sqrt(d)) + random.nextInt(1); - for (int i = 0; i < maxIt && state.getMaterial().isReplaceable(); i++) { - BlocksHelper.setWithoutUpdate(world, mut, rock); - mut.move(Direction.DOWN); - } - } - } - } - } - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/SulphuricCaveFeature.java b/src/main/java/ru/betterend/world/features/terrain/SulphuricCaveFeature.java deleted file mode 100644 index a314095b..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/SulphuricCaveFeature.java +++ /dev/null @@ -1,205 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; -import java.util.Set; - -import com.google.common.collect.Sets; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.HorizontalDirectionalBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.EndBlockProperties; -import ru.betterend.blocks.SulphurCrystalBlock; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; -import ru.betterend.util.BlockFixer; - -public class SulphuricCaveFeature extends DefaultFeature { - private static final BlockState CAVE_AIR = Blocks.CAVE_AIR.defaultBlockState(); - private static final BlockState WATER = Blocks.WATER.defaultBlockState(); - private static final Direction[] HORIZONTAL = BlocksHelper.makeHorizontal(); - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - int radius = MHelper.randRange(10, 30, random); - - int top = world.getHeight(Heightmap.Types.WORLD_SURFACE_WG, pos.getX(), pos.getZ()); - MutableBlockPos bpos = new MutableBlockPos(); - bpos.setX(pos.getX()); - bpos.setZ(pos.getZ()); - bpos.setY(top - 1); - - BlockState state = world.getBlockState(bpos); - while (!state.is(TagAPI.GEN_TERRAIN) && bpos.getY() > 5) { - bpos.setY(bpos.getY() - 1); - state = world.getBlockState(bpos); - } - if (bpos.getY() < 10) { - return false; - } - top = (int) (bpos.getY() - (radius * 1.3F + 5)); - - while (state.is(TagAPI.GEN_TERRAIN) || !state.getFluidState().isEmpty() && bpos.getY() > 5) { - bpos.setY(bpos.getY() - 1); - state = world.getBlockState(bpos); - } - int bottom = (int) (bpos.getY() + radius * 1.3F + 5); - - if (top <= bottom) { - return false; - } - - MutableBlockPos mut = new MutableBlockPos(); - pos = new BlockPos(pos.getX(), MHelper.randRange(bottom, top, random), pos.getZ()); - - OpenSimplexNoise noise = new OpenSimplexNoise(MHelper.getSeed(534, pos.getX(), pos.getZ())); - - int x1 = pos.getX() - radius - 5; - int z1 = pos.getZ() - radius - 5; - int x2 = pos.getX() + radius + 5; - int z2 = pos.getZ() + radius + 5; - int y1 = MHelper.floor(pos.getY() - (radius + 5) / 1.6); - int y2 = MHelper.floor(pos.getY() + (radius + 5) / 1.6); - - double hr = radius * 0.75; - double nr = radius * 0.25; - - Set brimstone = Sets.newHashSet(); - BlockState rock = EndBlocks.SULPHURIC_ROCK.stone.defaultBlockState(); - int waterLevel = pos.getY() + MHelper.randRange(MHelper.floor(radius * 0.8), radius, random); - for (int x = x1; x <= x2; x++) { - int xsq = x - pos.getX(); - xsq *= xsq; - mut.setX(x); - for (int z = z1; z <= z2; z++) { - int zsq = z - pos.getZ(); - zsq *= zsq; - mut.setZ(z); - for (int y = y1; y <= y2; y++) { - int ysq = y - pos.getY(); - ysq *= 1.6; - ysq *= ysq; - mut.setY(y); - double r = noise.eval(x * 0.1, y * 0.1, z * 0.1) * nr + hr; - double r2 = r + 5; - double dist = xsq + ysq + zsq; - if (dist < r * r) { - state = world.getBlockState(mut); - if (isReplaceable(state)) { - BlocksHelper.setWithoutUpdate(world, mut, y < waterLevel ? WATER : CAVE_AIR); - } - } else if (dist < r2 * r2) { - state = world.getBlockState(mut); - if (state.is(TagAPI.GEN_TERRAIN) || state.is(Blocks.AIR)) { - double v = noise.eval(x * 0.1, y * 0.1, z * 0.1) - + noise.eval(x * 0.03, y * 0.03, z * 0.03) * 0.5; - if (v > 0.4) { - brimstone.add(mut.immutable()); - } else { - BlocksHelper.setWithoutUpdate(world, mut, rock); - } - } - } - } - } - } - brimstone.forEach((blockPos) -> { - placeBrimstone(world, blockPos, random); - }); - - if (random.nextInt(4) == 0) { - int count = MHelper.randRange(5, 20, random); - for (int i = 0; i < count; i++) { - mut.set(pos).move(MHelper.floor(random.nextGaussian() * 2 + 0.5), 0, - MHelper.floor(random.nextGaussian() * 2 + 0.5)); - int dist = MHelper.floor(3 - MHelper.length(mut.getX() - pos.getX(), mut.getZ() - pos.getZ())) - + random.nextInt(2); - if (dist > 0) { - state = world.getBlockState(mut); - while (!state.getFluidState().isEmpty() || state.getMaterial().equals(Material.WATER_PLANT)) { - mut.setY(mut.getY() - 1); - state = world.getBlockState(mut); - } - if (state.is(TagAPI.GEN_TERRAIN) - && !world.getBlockState(mut.above()).is(EndBlocks.HYDROTHERMAL_VENT)) { - for (int j = 0; j <= dist; j++) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.SULPHURIC_ROCK.stone); - MHelper.shuffle(HORIZONTAL, random); - for (Direction dir : HORIZONTAL) { - BlockPos p = mut.relative(dir); - if (random.nextBoolean() && world.getBlockState(p).is(Blocks.WATER)) { - BlocksHelper.setWithoutUpdate(world, p, EndBlocks.TUBE_WORM.defaultBlockState() - .setValue(HorizontalDirectionalBlock.FACING, dir)); - } - } - mut.setY(mut.getY() + 1); - } - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.HYDROTHERMAL_VENT); - mut.setY(mut.getY() + 1); - state = world.getBlockState(mut); - while (state.is(Blocks.WATER)) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.VENT_BUBBLE_COLUMN.defaultBlockState()); - world.getBlockTicks().scheduleTick(mut, EndBlocks.VENT_BUBBLE_COLUMN, - MHelper.randRange(8, 32, random)); - mut.setY(mut.getY() + 1); - state = world.getBlockState(mut); - } - } - } - } - } - - BlockFixer.fixBlocks(world, new BlockPos(x1, y1, z1), new BlockPos(x2, y2, z2)); - - return true; - } - - private boolean isReplaceable(BlockState state) { - return state.is(TagAPI.GEN_TERRAIN) || state.is(EndBlocks.HYDROTHERMAL_VENT) - || state.is(EndBlocks.VENT_BUBBLE_COLUMN) || state.is(EndBlocks.SULPHUR_CRYSTAL) - || state.getMaterial().isReplaceable() || state.getMaterial().equals(Material.PLANT) - || state.getMaterial().equals(Material.WATER_PLANT) || state.getMaterial().equals(Material.LEAVES); - } - - private void placeBrimstone(WorldGenLevel world, BlockPos pos, Random random) { - BlockState state = getBrimstone(world, pos); - BlocksHelper.setWithoutUpdate(world, pos, state); - if (state.getValue(EndBlockProperties.ACTIVE)) { - makeShards(world, pos, random); - } - } - - private BlockState getBrimstone(WorldGenLevel world, BlockPos pos) { - for (Direction dir : BlocksHelper.DIRECTIONS) { - if (world.getBlockState(pos.relative(dir)).is(Blocks.WATER)) { - return EndBlocks.BRIMSTONE.defaultBlockState().setValue(EndBlockProperties.ACTIVE, true); - } - } - return EndBlocks.BRIMSTONE.defaultBlockState(); - } - - private void makeShards(WorldGenLevel world, BlockPos pos, Random random) { - for (Direction dir : BlocksHelper.DIRECTIONS) { - BlockPos side; - if (random.nextInt(16) == 0 && world.getBlockState((side = pos.relative(dir))).is(Blocks.WATER)) { - BlockState state = EndBlocks.SULPHUR_CRYSTAL.defaultBlockState() - .setValue(SulphurCrystalBlock.WATERLOGGED, true).setValue(SulphurCrystalBlock.FACING, dir) - .setValue(SulphurCrystalBlock.AGE, random.nextInt(3)); - BlocksHelper.setWithoutUpdate(world, side, state); - } - } - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/SulphuricLakeFeature.java b/src/main/java/ru/betterend/world/features/terrain/SulphuricLakeFeature.java deleted file mode 100644 index 07d49e00..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/SulphuricLakeFeature.java +++ /dev/null @@ -1,201 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; -import java.util.Set; - -import com.google.common.collect.Sets; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Fluids; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.EndBlockProperties; -import ru.betterend.blocks.SulphurCrystalBlock; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class SulphuricLakeFeature extends DefaultFeature { - private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(15152); - private static final MutableBlockPos POS = new MutableBlockPos(); - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, - NoneFeatureConfiguration featureConfig) { - blockPos = getPosOnSurfaceWG(world, blockPos); - - if (blockPos.getY() < 57) { - return false; - } - - double radius = MHelper.randRange(10.0, 20.0, random); - int dist2 = MHelper.floor(radius * 1.5); - - int minX = blockPos.getX() - dist2; - int maxX = blockPos.getX() + dist2; - int minZ = blockPos.getZ() - dist2; - int maxZ = blockPos.getZ() + dist2; - - Set brimstone = Sets.newHashSet(); - for (int x = minX; x <= maxX; x++) { - POS.setX(x); - int x2 = x - blockPos.getX(); - x2 *= x2; - for (int z = minZ; z <= maxZ; z++) { - POS.setZ(z); - int z2 = z - blockPos.getZ(); - z2 *= z2; - double r = radius * (NOISE.eval(x * 0.2, z * 0.2) * 0.25 + 0.75); - double r2 = r * 1.5; - r *= r; - r2 *= r2; - int dist = x2 + z2; - if (dist <= r) { - POS.setY(getYOnSurface(world, x, z) - 1); - if (world.getBlockState(POS).is(TagAPI.GEN_TERRAIN)) { - if (isBorder(world, POS)) { - if (random.nextInt(8) > 0) { - brimstone.add(POS.immutable()); - if (random.nextBoolean()) { - brimstone.add(POS.below()); - if (random.nextBoolean()) { - brimstone.add(POS.below(2)); - } - } - } else { - if (!isAbsoluteBorder(world, POS)) { - BlocksHelper.setWithoutUpdate(world, POS, Blocks.WATER); - world.getLiquidTicks().scheduleTick(POS, Fluids.WATER, 0); - brimstone.add(POS.below()); - if (random.nextBoolean()) { - brimstone.add(POS.below(2)); - if (random.nextBoolean()) { - brimstone.add(POS.below(3)); - } - } - } else { - brimstone.add(POS.immutable()); - if (random.nextBoolean()) { - brimstone.add(POS.below()); - } - } - } - } else { - BlocksHelper.setWithoutUpdate(world, POS, Blocks.WATER); - brimstone.remove(POS); - for (Direction dir : BlocksHelper.HORIZONTAL) { - BlockPos offseted = POS.relative(dir); - if (world.getBlockState(offseted).is(TagAPI.GEN_TERRAIN)) { - brimstone.add(offseted); - } - } - if (isDeepWater(world, POS)) { - BlocksHelper.setWithoutUpdate(world, POS.move(Direction.DOWN), Blocks.WATER); - brimstone.remove(POS); - for (Direction dir : BlocksHelper.HORIZONTAL) { - BlockPos offseted = POS.relative(dir); - if (world.getBlockState(offseted).is(TagAPI.GEN_TERRAIN)) { - brimstone.add(offseted); - } - } - } - brimstone.add(POS.below()); - if (random.nextBoolean()) { - brimstone.add(POS.below(2)); - if (random.nextBoolean()) { - brimstone.add(POS.below(3)); - } - } - } - } - } else if (dist < r2) { - POS.setY(getYOnSurface(world, x, z) - 1); - if (world.getBlockState(POS).is(TagAPI.GEN_TERRAIN)) { - brimstone.add(POS.immutable()); - if (random.nextBoolean()) { - brimstone.add(POS.below()); - if (random.nextBoolean()) { - brimstone.add(POS.below(2)); - } - } - } - } - } - } - - brimstone.forEach((bpos) -> { - placeBrimstone(world, bpos, random); - }); - - return true; - } - - private boolean isBorder(WorldGenLevel world, BlockPos pos) { - int y = pos.getY() + 1; - for (Direction dir : BlocksHelper.DIRECTIONS) { - if (getYOnSurface(world, pos.getX() + dir.getStepX(), pos.getZ() + dir.getStepZ()) < y) { - return true; - } - } - return false; - } - - private boolean isAbsoluteBorder(WorldGenLevel world, BlockPos pos) { - int y = pos.getY() - 2; - for (Direction dir : BlocksHelper.DIRECTIONS) { - if (getYOnSurface(world, pos.getX() + dir.getStepX() * 3, pos.getZ() + dir.getStepZ() * 3) < y) { - return true; - } - } - return false; - } - - private boolean isDeepWater(WorldGenLevel world, BlockPos pos) { - int y = pos.getY() + 1; - for (Direction dir : BlocksHelper.DIRECTIONS) { - if (getYOnSurface(world, pos.getX() + dir.getStepX(), pos.getZ() + dir.getStepZ()) < y - || getYOnSurface(world, pos.getX() + dir.getStepX() * 2, pos.getZ() + dir.getStepZ() * 2) < y - || getYOnSurface(world, pos.getX() + dir.getStepX() * 3, pos.getZ() + dir.getStepZ() * 3) < y) { - return false; - } - } - return true; - } - - private void placeBrimstone(WorldGenLevel world, BlockPos pos, Random random) { - BlockState state = getBrimstone(world, pos); - BlocksHelper.setWithoutUpdate(world, pos, state); - if (state.getValue(EndBlockProperties.ACTIVE)) { - makeShards(world, pos, random); - } - } - - private BlockState getBrimstone(WorldGenLevel world, BlockPos pos) { - for (Direction dir : BlocksHelper.DIRECTIONS) { - if (world.getBlockState(pos.relative(dir)).is(Blocks.WATER)) { - return EndBlocks.BRIMSTONE.defaultBlockState().setValue(EndBlockProperties.ACTIVE, true); - } - } - return EndBlocks.BRIMSTONE.defaultBlockState(); - } - - private void makeShards(WorldGenLevel world, BlockPos pos, Random random) { - for (Direction dir : BlocksHelper.DIRECTIONS) { - BlockPos side; - if (random.nextInt(16) == 0 && world.getBlockState((side = pos.relative(dir))).is(Blocks.WATER)) { - BlockState state = EndBlocks.SULPHUR_CRYSTAL.defaultBlockState() - .setValue(SulphurCrystalBlock.WATERLOGGED, true).setValue(SulphurCrystalBlock.FACING, dir) - .setValue(SulphurCrystalBlock.AGE, random.nextInt(3)); - BlocksHelper.setWithoutUpdate(world, side, state); - } - } - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/SurfaceVentFeature.java b/src/main/java/ru/betterend/world/features/terrain/SurfaceVentFeature.java deleted file mode 100644 index 61bdc174..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/SurfaceVentFeature.java +++ /dev/null @@ -1,53 +0,0 @@ -package ru.betterend.world.features.terrain; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.HydrothermalVentBlock; -import ru.betterend.registry.EndBlocks; - -public class SurfaceVentFeature extends DefaultFeature { - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - pos = getPosOnSurface(world, - new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16))); - if (!world.getBlockState(pos.below(3)).is(TagAPI.GEN_TERRAIN)) { - return false; - } - - MutableBlockPos mut = new MutableBlockPos(); - int count = MHelper.randRange(15, 30, random); - BlockState vent = EndBlocks.HYDROTHERMAL_VENT.defaultBlockState().setValue(HydrothermalVentBlock.WATERLOGGED, false); - for (int i = 0; i < count; i++) { - mut.set(pos).move(MHelper.floor(random.nextGaussian() * 2 + 0.5), 5, MHelper.floor(random.nextGaussian() * 2 + 0.5)); - int dist = MHelper.floor(2 - MHelper.length(mut.getX() - pos.getX(), mut.getZ() - pos.getZ())) + random.nextInt(2); - if (dist > 0) { - BlockState state = world.getBlockState(mut); - for (int n = 0; n < 10 && state.isAir(); n++) { - mut.setY(mut.getY() - 1); - state = world.getBlockState(mut); - } - if (state.is(TagAPI.GEN_TERRAIN) - && !world.getBlockState(mut.above()).is(EndBlocks.HYDROTHERMAL_VENT)) { - for (int j = 0; j <= dist; j++) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.SULPHURIC_ROCK.stone); - mut.setY(mut.getY() + 1); - } - BlocksHelper.setWithoutUpdate(world, mut, vent); - } - } - } - - return true; - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java b/src/main/java/ru/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java deleted file mode 100644 index 00d5f28a..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java +++ /dev/null @@ -1,135 +0,0 @@ -package ru.betterend.world.features.terrain.caves; - -import java.util.Random; -import java.util.Set; -import java.util.function.Supplier; - -import com.google.common.collect.Sets; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.Feature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.util.BlockFixer; -import ru.betterend.world.biome.cave.EndCaveBiome; - -public class CaveChunkPopulatorFeature extends DefaultFeature { - private Supplier supplier; - - public CaveChunkPopulatorFeature(Supplier biome) { - this.supplier = biome; - } - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, NoneFeatureConfiguration config) { - Set floorPositions = Sets.newHashSet(); - Set ceilPositions = Sets.newHashSet(); - int sx = (pos.getX() >> 4) << 4; - int sz = (pos.getZ() >> 4) << 4; - MutableBlockPos min = new MutableBlockPos().set(pos); - MutableBlockPos max = new MutableBlockPos().set(pos); - fillSets(sx, sz, world.getChunk(pos), floorPositions, ceilPositions, min, max); - EndCaveBiome biome = supplier.get(); - BlockState surfaceBlock = biome.getBiome().getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - placeFloor(world, biome, floorPositions, random, surfaceBlock); - placeCeil(world, biome, ceilPositions, random); - BlockFixer.fixBlocks(world, min, max); - return true; - } - - protected void fillSets(int sx, int sz, ChunkAccess chunk, Set floorPositions, - Set ceilPositions, MutableBlockPos min, MutableBlockPos max) { - MutableBlockPos mut = new MutableBlockPos(); - MutableBlockPos mut2 = new MutableBlockPos(); - MutableBlockPos mut3 = new MutableBlockPos(); - for (int x = 0; x < 16; x++) { - mut.setX(x); - mut2.setX(x); - for (int z = 0; z < 16; z++) { - mut.setZ(z); - mut2.setZ(z); - mut2.setY(0); - for (int y = 1; y < chunk.getMaxBuildHeight(); y++) { - mut.setY(y); - BlockState top = chunk.getBlockState(mut); - BlockState bottom = chunk.getBlockState(mut2); - if (top.isAir() && (bottom.is(TagAPI.GEN_TERRAIN) || bottom.is(Blocks.STONE))) { - mut3.set(mut2).move(sx, 0, sz); - floorPositions.add(mut3.immutable()); - updateMin(mut3, min); - updateMax(mut3, max); - } - else if (bottom.isAir() && (top.is(TagAPI.GEN_TERRAIN) || top.is(Blocks.STONE))) { - mut3.set(mut).move(sx, 0, sz); - ceilPositions.add(mut3.immutable()); - updateMin(mut3, min); - updateMax(mut3, max); - } - mut2.setY(y); - } - } - } - } - - private void updateMin(BlockPos pos, MutableBlockPos min) { - if (pos.getX() < min.getX()) { - min.setX(pos.getX()); - } - if (pos.getY() < min.getY()) { - min.setY(pos.getY()); - } - if (pos.getZ() < min.getZ()) { - min.setZ(pos.getZ()); - } - } - - private void updateMax(BlockPos pos, MutableBlockPos max) { - if (pos.getX() > max.getX()) { - max.setX(pos.getX()); - } - if (pos.getY() > max.getY()) { - max.setY(pos.getY()); - } - if (pos.getZ() > max.getZ()) { - max.setZ(pos.getZ()); - } - } - - protected void placeFloor(WorldGenLevel world, EndCaveBiome biome, Set floorPositions, Random random, - BlockState surfaceBlock) { - float density = biome.getFloorDensity(); - floorPositions.forEach((pos) -> { - BlocksHelper.setWithoutUpdate(world, pos, surfaceBlock); - if (density > 0 && random.nextFloat() <= density) { - Feature feature = biome.getFloorFeature(random); - if (feature != null) { - feature.place(world, null, random, pos.above(), null); - } - } - }); - } - - protected void placeCeil(WorldGenLevel world, EndCaveBiome biome, Set ceilPositions, Random random) { - float density = biome.getCeilDensity(); - ceilPositions.forEach((pos) -> { - BlockState ceilBlock = biome.getCeil(pos); - if (ceilBlock != null) { - BlocksHelper.setWithoutUpdate(world, pos, ceilBlock); - } - if (density > 0 && random.nextFloat() <= density) { - Feature feature = biome.getCeilFeature(random); - if (feature != null) { - feature.place(world, null, random, pos.below(), null); - } - } - }); - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/caves/EndCaveFeature.java b/src/main/java/ru/betterend/world/features/terrain/caves/EndCaveFeature.java deleted file mode 100644 index 964fa6b3..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/caves/EndCaveFeature.java +++ /dev/null @@ -1,261 +0,0 @@ -package ru.betterend.world.features.terrain.caves; - -import java.util.List; -import java.util.Random; -import java.util.Set; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Vec3i; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.feature.Feature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.api.BiomeAPI; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.world.biomes.BCLBiome; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.interfaces.IBiomeArray; -import ru.betterend.registry.EndBiomes; -import ru.betterend.util.BlockFixer; -import ru.betterend.world.biome.cave.EndCaveBiome; - -public abstract class EndCaveFeature extends DefaultFeature { - protected static final BlockState CAVE_AIR = Blocks.CAVE_AIR.defaultBlockState(); - protected static final BlockState END_STONE = Blocks.END_STONE.defaultBlockState(); - protected static final BlockState WATER = Blocks.WATER.defaultBlockState(); - private static final Vec3i[] SPHERE; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, NoneFeatureConfiguration config) { - if (pos.getX() * pos.getX() + pos.getZ() * pos.getZ() <= 2500) { - return false; - } - - if (biomeMissingCaves(world, pos)) { - return false; - } - - int radius = MHelper.randRange(10, 30, random); - BlockPos center = findPos(world, pos, radius, random); - - if (center == null) { - return false; - } - - EndCaveBiome biome = EndBiomes.getCaveBiome(pos.getX(), pos.getZ()); - Set caveBlocks = generate(world, center, radius, random); - if (!caveBlocks.isEmpty()) { - if (biome != null) { - setBiomes(world, biome, caveBlocks); - Set floorPositions = Sets.newHashSet(); - Set ceilPositions = Sets.newHashSet(); - MutableBlockPos mut = new MutableBlockPos(); - caveBlocks.forEach((bpos) -> { - mut.set(bpos); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - mut.setY(bpos.getY() - 1); - if (world.getBlockState(mut).is(TagAPI.GEN_TERRAIN)) { - floorPositions.add(mut.immutable()); - } - mut.setY(bpos.getY() + 1); - if (world.getBlockState(mut).is(TagAPI.GEN_TERRAIN)) { - ceilPositions.add(mut.immutable()); - } - } - }); - BlockState surfaceBlock = biome.getBiome().getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - placeFloor(world, biome, floorPositions, random, surfaceBlock); - placeCeil(world, biome, ceilPositions, random); - placeWalls(world, biome, caveBlocks, random); - } - fixBlocks(world, caveBlocks); - } - - return true; - } - - protected abstract Set generate(WorldGenLevel world, BlockPos center, int radius, Random random); - - protected void placeFloor(WorldGenLevel world, EndCaveBiome biome, Set floorPositions, Random random, BlockState surfaceBlock) { - float density = biome.getFloorDensity(); - floorPositions.forEach((pos) -> { - if (!surfaceBlock.is(Blocks.END_STONE)) { - BlocksHelper.setWithoutUpdate(world, pos, surfaceBlock); - } - if (density > 0 && random.nextFloat() <= density) { - Feature feature = biome.getFloorFeature(random); - if (feature != null) { - feature.place(world, null, random, pos.above(), null); - } - } - }); - } - - protected void placeCeil(WorldGenLevel world, EndCaveBiome biome, Set ceilPositions, Random random) { - float density = biome.getCeilDensity(); - ceilPositions.forEach((pos) -> { - BlockState ceilBlock = biome.getCeil(pos); - if (ceilBlock != null) { - BlocksHelper.setWithoutUpdate(world, pos, ceilBlock); - } - if (density > 0 && random.nextFloat() <= density) { - Feature feature = biome.getCeilFeature(random); - if (feature != null) { - feature.place(world, null, random, pos.below(), null); - } - } - }); - } - - protected void placeWalls(WorldGenLevel world, EndCaveBiome biome, Set positions, Random random) { - Set placed = Sets.newHashSet(); - positions.forEach(pos -> { - if (random.nextInt(4) == 0 && hasOpenSide(pos, positions)) { - BlockState wallBlock = biome.getWall(pos); - if (wallBlock != null) { - for (Vec3i offset: SPHERE) { - BlockPos wallPos = pos.offset(offset); - if (!positions.contains(wallPos) && !placed.contains(wallPos) && world.getBlockState(wallPos).is(TagAPI.GEN_TERRAIN)) { - wallBlock = biome.getWall(wallPos); - BlocksHelper.setWithoutUpdate(world, wallPos, wallBlock); - placed.add(wallPos); - } - } - } - } - }); - } - - private boolean hasOpenSide(BlockPos pos, Set positions) { - for (Direction dir: BlocksHelper.DIRECTIONS) { - if (!positions.contains(pos.relative(dir))) { - return true; - } - } - return false; - } - - protected void setBiomes(WorldGenLevel world, EndCaveBiome biome, Set blocks) { - blocks.forEach((pos) -> setBiome(world, pos, biome)); - } - - protected void setBiome(WorldGenLevel world, BlockPos pos, EndCaveBiome biome) { - IBiomeArray array = (IBiomeArray) world.getChunk(pos).getBiomes(); - if (array != null) { - Biome bio = BiomeAPI.getActualBiome(biome); - array.be_setBiome(bio, pos); - } - } - - private BlockPos findPos(WorldGenLevel world, BlockPos pos, int radius, Random random) { - int top = world.getHeight(Heightmap.Types.WORLD_SURFACE_WG, pos.getX(), pos.getZ()); - MutableBlockPos bpos = new MutableBlockPos(); - bpos.setX(pos.getX()); - bpos.setZ(pos.getZ()); - bpos.setY(top - 1); - - BlockState state = world.getBlockState(bpos); - while (!state.is(TagAPI.GEN_TERRAIN) && bpos.getY() > 5) { - bpos.setY(bpos.getY() - 1); - state = world.getBlockState(bpos); - } - if (bpos.getY() < 10) { - return null; - } - top = (int) (bpos.getY() - (radius * 1.3F + 5)); - - while (state.is(TagAPI.GEN_TERRAIN) || !state.getFluidState().isEmpty() && bpos.getY() > 5) { - bpos.setY(bpos.getY() - 1); - state = world.getBlockState(bpos); - } - int bottom = (int) (bpos.getY() + radius * 1.3F + 5); - - if (top <= bottom) { - return null; - } - - return new BlockPos(pos.getX(), MHelper.randRange(bottom, top, random), pos.getZ()); - } - - protected void fixBlocks(WorldGenLevel world, Set caveBlocks) { - BlockPos pos = caveBlocks.iterator().next(); - MutableBlockPos start = new MutableBlockPos().set(pos); - MutableBlockPos end = new MutableBlockPos().set(pos); - caveBlocks.forEach((bpos) -> { - if (bpos.getX() < start.getX()) { - start.setX(bpos.getX()); - } - if (bpos.getX() > end.getX()) { - end.setX(bpos.getX()); - } - - if (bpos.getY() < start.getY()) { - start.setY(bpos.getY()); - } - if (bpos.getY() > end.getY()) { - end.setY(bpos.getY()); - } - - if (bpos.getZ() < start.getZ()) { - start.setZ(bpos.getZ()); - } - if (bpos.getZ() > end.getZ()) { - end.setZ(bpos.getZ()); - } - }); - BlockFixer.fixBlocks(world, start.offset(-2, -2, -2), end.offset(2, 2, 2)); - } - - protected boolean isWaterNear(WorldGenLevel world, BlockPos pos) { - for (Direction dir : BlocksHelper.DIRECTIONS) { - if (!world.getFluidState(pos.relative(dir, 5)).isEmpty()) { - return true; - } - } - return false; - } - - protected boolean biomeMissingCaves(WorldGenLevel world, BlockPos pos) { - for (int x = -2; x < 3; x++) { - for (int z = -2; z < 3; z++) { - Biome biome = world.getBiome(pos.offset(x << 4, 0, z << 4)); - BCLBiome endBiome = BiomeAPI.getFromBiome(biome); - boolean hasCaves = endBiome.getCustomData("has_caves", true); - if (!hasCaves && EndBiomes.LAND_BIOMES.containsImmutable(endBiome.getID())) { - return true; - } - } - } - return false; - } - - static { - List prePos = Lists.newArrayList(); - int radius = 5; - int r2 = radius * radius; - for (int x = -radius; x <= radius; x++) { - int x2 = x * x; - for (int y = -radius; y <= radius; y++) { - int y2 = y * y; - for (int z = -radius; z <= radius; z++) { - int z2 = z * z; - if (x2 + y2 + z2 < r2) { - prePos.add(new Vec3i(x, y, z)); - } - } - } - } - SPHERE = prePos.toArray(new Vec3i[] {}); - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/caves/RoundCaveFeature.java b/src/main/java/ru/betterend/world/features/terrain/caves/RoundCaveFeature.java deleted file mode 100644 index 58364bd6..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/caves/RoundCaveFeature.java +++ /dev/null @@ -1,84 +0,0 @@ -package ru.betterend.world.features.terrain.caves; - -import java.util.Random; -import java.util.Set; - -import com.google.common.collect.Sets; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.noise.OpenSimplexNoise; - -public class RoundCaveFeature extends EndCaveFeature { - @Override - protected Set generate(WorldGenLevel world, BlockPos center, int radius, Random random) { - OpenSimplexNoise noise = new OpenSimplexNoise(MHelper.getSeed(534, center.getX(), center.getZ())); - - int x1 = center.getX() - radius - 5; - int z1 = center.getZ() - radius - 5; - int x2 = center.getX() + radius + 5; - int z2 = center.getZ() + radius + 5; - int y1 = MHelper.floor(center.getY() - (radius + 5) / 1.6); - int y2 = MHelper.floor(center.getY() + (radius + 5) / 1.6); - - double hr = radius * 0.75; - double nr = radius * 0.25; - - BlockState state; - MutableBlockPos bpos = new MutableBlockPos(); - Set blocks = Sets.newHashSet(); - for (int x = x1; x <= x2; x++) { - int xsq = x - center.getX(); - xsq *= xsq; - bpos.setX(x); - for (int z = z1; z <= z2; z++) { - int zsq = z - center.getZ(); - zsq *= zsq; - bpos.setZ(z); - for (int y = y1; y <= y2; y++) { - int ysq = y - center.getY(); - ysq *= 1.6; - ysq *= ysq; - bpos.setY(y); - double r = noise.eval(x * 0.1, y * 0.1, z * 0.1) * nr + hr; - double dist = xsq + ysq + zsq; - if (dist < r * r) { - state = world.getBlockState(bpos); - if (isReplaceable(state) && !isWaterNear(world, bpos)) { - BlocksHelper.setWithoutUpdate(world, bpos, CAVE_AIR); - blocks.add(bpos.immutable()); - - while (state.getMaterial().equals(Material.LEAVES)) { - BlocksHelper.setWithoutUpdate(world, bpos, CAVE_AIR); - bpos.setY(bpos.getY() + 1); - state = world.getBlockState(bpos); - } - - bpos.setY(y - 1); - while (state.getMaterial().equals(Material.LEAVES)) { - BlocksHelper.setWithoutUpdate(world, bpos, CAVE_AIR); - bpos.setY(bpos.getY() - 1); - state = world.getBlockState(bpos); - } - } - } - } - } - } - - return blocks; - } - - private boolean isReplaceable(BlockState state) { - return state.is(TagAPI.GEN_TERRAIN) - || state.getMaterial().isReplaceable() - || state.getMaterial().equals(Material.PLANT) - || state.getMaterial().equals(Material.LEAVES); - } -} diff --git a/src/main/java/ru/betterend/world/features/terrain/caves/TunelCaveFeature.java b/src/main/java/ru/betterend/world/features/terrain/caves/TunelCaveFeature.java deleted file mode 100644 index ed518538..00000000 --- a/src/main/java/ru/betterend/world/features/terrain/caves/TunelCaveFeature.java +++ /dev/null @@ -1,195 +0,0 @@ -package ru.betterend.world.features.terrain.caves; - -import java.util.Map; -import java.util.Random; -import java.util.Set; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.util.Mth; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.feature.Feature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBiomes; -import ru.betterend.world.biome.cave.EndCaveBiome; - -public class TunelCaveFeature extends EndCaveFeature { - private Set generate(WorldGenLevel world, BlockPos center, Random random) { - int cx = center.getX() >> 4; - int cz = center.getZ() >> 4; - if ((long) cx * (long) cx + (long) cz + (long) cz < 256) { - return Sets.newHashSet(); - } - int x1 = cx << 4; - int z1 = cz << 4; - int x2 = x1 + 16; - int z2 = z1 + 16; - int y2 = world.getHeight(); - Random rand = new Random(world.getSeed()); - OpenSimplexNoise noiseH = new OpenSimplexNoise(rand.nextInt()); - OpenSimplexNoise noiseV = new OpenSimplexNoise(rand.nextInt()); - OpenSimplexNoise noiseD = new OpenSimplexNoise(rand.nextInt()); - - Set positions = Sets.newHashSet(); - MutableBlockPos pos = new MutableBlockPos(); - for (int x = x1; x < x2; x++) { - pos.setX(x); - for (int z = z1; z < z2; z++) { - pos.setZ(z); - for (int y = 0; y < y2; y++) { - pos.setY(y); - float val = Mth.abs((float) noiseH.eval(x * 0.02, y * 0.01, z * 0.02)); - float vert = Mth.sin((y + (float) noiseV.eval(x * 0.01, z * 0.01) * 20) * 0.1F) * 0.9F; - float dist = (float) noiseD.eval(x * 0.1, y * 0.1, z * 0.1) * 0.12F; - vert *= vert; - if (val + vert + dist < 0.15 && world.getBlockState(pos).is(TagAPI.GEN_TERRAIN) && noWaterNear(world, pos)) { - BlocksHelper.setWithoutUpdate(world, pos, AIR); - positions.add(pos.immutable()); - int height = world.getHeight(Types.WORLD_SURFACE_WG, pos.getX(), pos.getZ()); - if (height < pos.getY() + 4) { - while (pos.getY() < height && noWaterNear(world, pos)) { - pos.setY(pos.getY() + 1); - BlocksHelper.setWithoutUpdate(world, pos, AIR); - } - } - } - } - } - } - return positions; - } - - private boolean noWaterNear(WorldGenLevel world, BlockPos pos) { - BlockPos above1 = pos.above(); - BlockPos above2 = pos.above(2); - if (!world.getFluidState(above1).isEmpty() || !world.getFluidState(above2).isEmpty()) { - return false; - } - for (Direction dir: BlocksHelper.HORIZONTAL) { - if (!world.getFluidState(above1.relative(dir)).isEmpty()) { - return false; - } - if (!world.getFluidState(above2.relative(dir)).isEmpty()) { - return false; - } - } - return true; - } - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, NoneFeatureConfiguration config) { - if (pos.getX() * pos.getX() + pos.getZ() * pos.getZ() <= 2500) { - return false; - } - - if (biomeMissingCaves(world, pos)) { - return false; - } - - Set caveBlocks = generate(world, pos, random); - if (caveBlocks.isEmpty()) { - return false; - } - - Map> floorSets = Maps.newHashMap(); - Map> ceilSets = Maps.newHashMap(); - MutableBlockPos mut = new MutableBlockPos(); - Set remove = Sets.newHashSet(); - caveBlocks.forEach((bpos) -> { - mut.set(bpos); - EndCaveBiome bio = EndBiomes.getCaveBiome(bpos.getX(), bpos.getZ()); - int height = world.getHeight(Types.WORLD_SURFACE, bpos.getX(), bpos.getZ()); - if (mut.getY() >= height) { - remove.add(bpos); - } - else if (world.getBlockState(mut).getMaterial().isReplaceable()) { - mut.setY(bpos.getY() - 1); - if (world.getBlockState(mut).is(TagAPI.GEN_TERRAIN)) { - Set floorPositions = floorSets.get(bio); - if (floorPositions == null) { - floorPositions = Sets.newHashSet(); - floorSets.put(bio, floorPositions); - } - floorPositions.add(mut.immutable()); - } - mut.setY(bpos.getY() + 1); - if (world.getBlockState(mut).is(TagAPI.GEN_TERRAIN)) { - Set ceilPositions = ceilSets.get(bio); - if (ceilPositions == null) { - ceilPositions = Sets.newHashSet(); - ceilSets.put(bio, ceilPositions); - } - ceilPositions.add(mut.immutable()); - } - setBiome(world, bpos, bio); - } - }); - caveBlocks.removeAll(remove); - - if (caveBlocks.isEmpty()) { - return true; - } - - floorSets.forEach((biome, floorPositions) -> { - BlockState surfaceBlock = biome.getBiome().getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - placeFloor(world, biome, floorPositions, random, surfaceBlock); - }); - ceilSets.forEach((biome, ceilPositions) -> { - placeCeil(world, biome, ceilPositions, random); - }); - EndCaveBiome biome = EndBiomes.getCaveBiome(pos.getX(), pos.getZ()); - placeWalls(world, biome, caveBlocks, random); - fixBlocks(world, caveBlocks); - - return true; - } - - @Override - protected Set generate(WorldGenLevel world, BlockPos center, int radius, Random random) { - return null; - } - - @Override - protected void placeFloor(WorldGenLevel world, EndCaveBiome biome, Set floorPositions, Random random, BlockState surfaceBlock) { - float density = biome.getFloorDensity() * 0.2F; - floorPositions.forEach((pos) -> { - if (!surfaceBlock.is(Blocks.END_STONE)) { - BlocksHelper.setWithoutUpdate(world, pos, surfaceBlock); - } - if (density > 0 && random.nextFloat() <= density) { - Feature feature = biome.getFloorFeature(random); - if (feature != null) { - feature.place(world, null, random, pos.above(), null); - } - } - }); - } - - @Override - protected void placeCeil(WorldGenLevel world, EndCaveBiome biome, Set ceilPositions, Random random) { - float density = biome.getCeilDensity() * 0.2F; - ceilPositions.forEach((pos) -> { - BlockState ceilBlock = biome.getCeil(pos); - if (ceilBlock != null) { - BlocksHelper.setWithoutUpdate(world, pos, ceilBlock); - } - if (density > 0 && random.nextFloat() <= density) { - Feature feature = biome.getCeilFeature(random); - if (feature != null) { - feature.place(world, null, random, pos.below(), null); - } - } - }); - } -} diff --git a/src/main/java/ru/betterend/world/features/trees/DragonTreeFeature.java b/src/main/java/ru/betterend/world/features/trees/DragonTreeFeature.java deleted file mode 100644 index b03576fe..00000000 --- a/src/main/java/ru/betterend/world/features/trees/DragonTreeFeature.java +++ /dev/null @@ -1,237 +0,0 @@ -package ru.betterend.world.features.trees; - -import java.util.List; -import java.util.Random; -import java.util.function.Function; - -import com.google.common.collect.Lists; -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.LeavesBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.PosInfo; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFScale; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class DragonTreeFeature extends DefaultFeature { - private static final Function REPLACE; - private static final Function IGNORE; - private static final Function POST; - private static final List BRANCH; - private static final List SIDE1; - private static final List SIDE2; - private static final List ROOT; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND)) - return false; - - float size = MHelper.randRange(10, 25, random); - List spline = SplineHelper.makeSpline(0, 0, 0, 0, size, 0, 6); - SplineHelper.offsetParts(spline, random, 1F, 0, 1F); - - if (!SplineHelper.canGenerate(spline, pos, world, REPLACE)) { - return false; - } - BlocksHelper.setWithoutUpdate(world, pos, AIR); - - Vector3f last = SplineHelper.getPos(spline, 3.5F); - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); - float radius = size * MHelper.randRange(0.5F, 0.7F, random); - makeCap(world, pos.offset(last.x(), last.y(), last.z()), radius, random, noise); - - last = spline.get(0); - makeRoots(world, pos.offset(last.x(), last.y(), last.z()), radius, random); - - radius = MHelper.randRange(1.2F, 2.3F, random); - SDF function = SplineHelper.buildSDF(spline, radius, 1.2F, (bpos) -> { - return EndBlocks.DRAGON_TREE.bark.defaultBlockState(); - }); - - function.setReplaceFunction(REPLACE); - function.addPostProcess(POST); - function.fillRecursiveIgnore(world, pos, IGNORE); - - return true; - } - - private void makeCap(WorldGenLevel world, BlockPos pos, float radius, Random random, OpenSimplexNoise noise) { - int count = (int) radius; - int offset = (int) (BRANCH.get(BRANCH.size() - 1).y() * radius); - for (int i = 0; i < count; i++) { - float angle = (float) i / (float) count * MHelper.PI2; - float scale = radius * MHelper.randRange(0.85F, 1.15F, random); - - List branch = SplineHelper.copySpline(BRANCH); - SplineHelper.rotateSpline(branch, angle); - SplineHelper.scale(branch, scale); - SplineHelper.fillSpline(branch, world, EndBlocks.DRAGON_TREE.bark.defaultBlockState(), pos, REPLACE); - - branch = SplineHelper.copySpline(SIDE1); - SplineHelper.rotateSpline(branch, angle); - SplineHelper.scale(branch, scale); - SplineHelper.fillSpline(branch, world, EndBlocks.DRAGON_TREE.bark.defaultBlockState(), pos, REPLACE); - - branch = SplineHelper.copySpline(SIDE2); - SplineHelper.rotateSpline(branch, angle); - SplineHelper.scale(branch, scale); - SplineHelper.fillSpline(branch, world, EndBlocks.DRAGON_TREE.bark.defaultBlockState(), pos, REPLACE); - } - leavesBall(world, pos.above(offset), radius * 1.15F + 2, random, noise); - } - - private void makeRoots(WorldGenLevel world, BlockPos pos, float radius, Random random) { - int count = (int) (radius * 1.5F); - for (int i = 0; i < count; i++) { - float angle = (float) i / (float) count * MHelper.PI2; - float scale = radius * MHelper.randRange(0.85F, 1.15F, random); - - List branch = SplineHelper.copySpline(ROOT); - SplineHelper.rotateSpline(branch, angle); - SplineHelper.scale(branch, scale); - Vector3f last = branch.get(branch.size() - 1); - if (world.getBlockState(pos.offset(last.x(), last.y(), last.z())).is(TagAPI.GEN_TERRAIN)) { - SplineHelper.fillSpline(branch, world, EndBlocks.DRAGON_TREE.bark.defaultBlockState(), pos, REPLACE); - } - } - } - - private void leavesBall(WorldGenLevel world, BlockPos pos, float radius, Random random, OpenSimplexNoise noise) { - SDF sphere = new SDFSphere().setRadius(radius) - .setBlock(EndBlocks.DRAGON_TREE_LEAVES.defaultBlockState().setValue(LeavesBlock.DISTANCE, 6)); - SDF sub = new SDFScale().setScale(5).setSource(sphere); - sub = new SDFTranslate().setTranslate(0, -radius * 5, 0).setSource(sub); - sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sub); - sphere = new SDFScale3D().setScale(1, 0.5F, 1).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> { - return (float) noise.eval(vec.x() * 0.2, vec.y() * 0.2, vec.z() * 0.2) * 1.5F; - }).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> { - return random.nextFloat() * 3F - 1.5F; - }).setSource(sphere); - MutableBlockPos mut = new MutableBlockPos(); - sphere.addPostProcess((info) -> { - if (random.nextInt(5) == 0) { - for (Direction dir : Direction.values()) { - BlockState state = info.getState(dir, 2); - if (state.isAir()) { - return info.getState(); - } - } - info.setState(EndBlocks.DRAGON_TREE.bark.defaultBlockState()); - for (int x = -6; x < 7; x++) { - int ax = Math.abs(x); - mut.setX(x + info.getPos().getX()); - for (int z = -6; z < 7; z++) { - int az = Math.abs(z); - mut.setZ(z + info.getPos().getZ()); - for (int y = -6; y < 7; y++) { - int ay = Math.abs(y); - int d = ax + ay + az; - if (d < 7) { - mut.setY(y + info.getPos().getY()); - BlockState state = info.getState(mut); - if (state.getBlock() instanceof LeavesBlock) { - int distance = state.getValue(LeavesBlock.DISTANCE); - if (d < distance) { - info.setState(mut, state.setValue(LeavesBlock.DISTANCE, d)); - } - } - } - } - } - } - } - return info.getState(); - }); - sphere.fillRecursiveIgnore(world, pos, IGNORE); - - if (radius > 5) { - int count = (int) (radius * 2.5F); - for (int i = 0; i < count; i++) { - BlockPos p = pos.offset(random.nextGaussian() * 1, random.nextGaussian() * 1, - random.nextGaussian() * 1); - boolean place = true; - for (Direction d : Direction.values()) { - BlockState state = world.getBlockState(p.relative(d)); - if (!EndBlocks.DRAGON_TREE.isTreeLog(state) && !state.is(EndBlocks.DRAGON_TREE_LEAVES)) { - place = false; - break; - } - } - if (place) { - BlocksHelper.setWithoutUpdate(world, p, EndBlocks.DRAGON_TREE.bark); - } - } - } - - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.DRAGON_TREE.bark); - } - - static { - REPLACE = (state) -> { - if (state.is(TagAPI.END_GROUND)) { - return true; - } - if (state.getBlock() == EndBlocks.DRAGON_TREE_LEAVES) { - return true; - } - if (state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - - IGNORE = (state) -> { - return EndBlocks.DRAGON_TREE.isTreeLog(state); - }; - - POST = (info) -> { - if (EndBlocks.DRAGON_TREE.isTreeLog(info.getStateUp()) - && EndBlocks.DRAGON_TREE.isTreeLog(info.getStateDown())) { - return EndBlocks.DRAGON_TREE.log.defaultBlockState(); - } - return info.getState(); - }; - - BRANCH = Lists.newArrayList(new Vector3f(0, 0, 0), new Vector3f(0.1F, 0.3F, 0), new Vector3f(0.4F, 0.6F, 0), - new Vector3f(0.8F, 0.8F, 0), new Vector3f(1, 1, 0)); - SIDE1 = Lists.newArrayList(new Vector3f(0.4F, 0.6F, 0), new Vector3f(0.8F, 0.8F, 0), new Vector3f(1, 1, 0)); - SIDE2 = SplineHelper.copySpline(SIDE1); - - Vector3f offset1 = new Vector3f(-0.4F, -0.6F, 0); - Vector3f offset2 = new Vector3f(0.4F, 0.6F, 0); - - SplineHelper.offset(SIDE1, offset1); - SplineHelper.offset(SIDE2, offset1); - SplineHelper.rotateSpline(SIDE1, 0.5F); - SplineHelper.rotateSpline(SIDE2, -0.5F); - SplineHelper.offset(SIDE1, offset2); - SplineHelper.offset(SIDE2, offset2); - - ROOT = Lists.newArrayList(new Vector3f(0F, 1F, 0), new Vector3f(0.1F, 0.7F, 0), new Vector3f(0.3F, 0.3F, 0), - new Vector3f(0.7F, 0.05F, 0), new Vector3f(0.8F, -0.2F, 0)); - SplineHelper.offset(ROOT, new Vector3f(0, -0.45F, 0)); - } -} diff --git a/src/main/java/ru/betterend/world/features/trees/GiganticAmaranitaFeature.java b/src/main/java/ru/betterend/world/features/trees/GiganticAmaranitaFeature.java deleted file mode 100644 index 849cb05e..00000000 --- a/src/main/java/ru/betterend/world/features/trees/GiganticAmaranitaFeature.java +++ /dev/null @@ -1,345 +0,0 @@ -package ru.betterend.world.features.trees; - -import java.util.List; -import java.util.Random; -import java.util.function.Function; - -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Direction.Axis; -import net.minecraft.core.Direction.AxisDirection; -import net.minecraft.util.Mth; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BaseAttachedBlock; -import ru.bclib.sdf.PosInfo; -import ru.bclib.sdf.SDF; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.registry.EndBlocks; - -public class GiganticAmaranitaFeature extends DefaultFeature { - private static final Function REPLACE; - private static final Function IGNORE; - private static final Function POST; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND)) - return false; - - float size = MHelper.randRange(5, 10, random); - List spline = SplineHelper.makeSpline(0, 0, 0, 0, size, 0, 5); - SplineHelper.offsetParts(spline, random, 0.7F, 0, 0.7F); - - if (!SplineHelper.canGenerate(spline, pos, world, REPLACE)) { - return false; - } - BlocksHelper.setWithoutUpdate(world, pos, AIR); - - float radius = size * 0.17F;// MHelper.randRange(0.8F, 1.2F, random); - SDF function = SplineHelper.buildSDF(spline, radius, 0.2F, (bpos) -> EndBlocks.AMARANITA_STEM.defaultBlockState()); - - Vector3f capPos = spline.get(spline.size() - 1); - makeHead(world, pos.offset(capPos.x() + 0.5F, capPos.y() + 1.5F, capPos.z() + 0.5F), Mth.floor(size / 1.6F)); - - function.setReplaceFunction(REPLACE); - function.addPostProcess(POST); - function.fillRecursiveIgnore(world, pos, IGNORE); - - for (int i = 0; i < 3; i++) { - List copy = SplineHelper.copySpline(spline); - SplineHelper.offsetParts(copy, random, 0.2F, 0, 0.2F); - SplineHelper.fillSplineForce(copy, world, EndBlocks.AMARANITA_HYPHAE.defaultBlockState(), pos, REPLACE); - } - - return true; - } - - private void makeHead(WorldGenLevel world, BlockPos pos, int radius) { - MutableBlockPos mut = new MutableBlockPos(); - if (radius < 2) { - for (int i = -1; i < 2; i++) { - mut.set(pos).move(Direction.NORTH, 2).move(Direction.EAST, i); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.set(pos).move(Direction.SOUTH, 2).move(Direction.EAST, i); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.set(pos).move(Direction.EAST, 2).move(Direction.NORTH, i); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.set(pos).move(Direction.WEST, 2).move(Direction.NORTH, i); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - } - for (int x = -1; x < 2; x++) { - for (int z = -1; z < 2; z++) { - mut.set(pos).move(x, 0, z); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN); - mut.move(Direction.DOWN); - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN); - mut.move(Direction.DOWN); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_FUR.defaultBlockState() - .setValue(BaseAttachedBlock.FACING, Direction.DOWN)); - } - } - } - } - - int h = radius + 1; - for (int y = 0; y < h; y++) { - mut.setY(pos.getY() + y + 1); - for (int x = -1; x < 2; x++) { - mut.setX(pos.getX() + x); - for (int z = -1; z < 2; z++) { - mut.setZ(pos.getZ() + z); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); - } - } - } - } - - mut.setY(pos.getY() + h + 1); - for (int x = -1; x < 2; x++) { - mut.setX(pos.getX() + x); - for (int z = -1; z < 2; z++) { - mut.setZ(pos.getZ() + z); - if ((x == 0 || z == 0) && world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); - } - } - } - } else if (radius < 4) { - pos = pos.offset(-1, 0, -1); - for (int i = -2; i < 2; i++) { - mut.set(pos).move(Direction.NORTH, 2).move(Direction.WEST, i); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.set(pos).move(Direction.SOUTH, 3).move(Direction.WEST, i); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.set(pos).move(Direction.EAST, 3).move(Direction.NORTH, i); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.set(pos).move(Direction.WEST, 2).move(Direction.NORTH, i); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - } - for (int x = -1; x < 3; x++) { - for (int z = -1; z < 3; z++) { - mut.set(pos).move(x, 0, z); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN); - mut.move(Direction.DOWN); - if ((x >> 1) == 0 || (z >> 1) == 0) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN); - Axis axis = x < 0 || x > 1 ? Axis.X : Axis.Z; - int distance = axis == Axis.X ? x < 0 ? -1 : 1 : z < 0 ? -1 : 1; - BlockPos offseted = mut.relative(axis, distance); - if (world.getBlockState(offseted).getMaterial().isReplaceable()) { - Direction dir = Direction.fromAxisAndDirection(axis, - distance < 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE); - BlocksHelper.setWithoutUpdate(world, offseted, EndBlocks.AMARANITA_FUR - .defaultBlockState().setValue(BaseAttachedBlock.FACING, dir)); - } - mut.move(Direction.DOWN); - } - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_FUR.defaultBlockState() - .setValue(BaseAttachedBlock.FACING, Direction.DOWN)); - } - } - } - } - - int h = radius - 1; - for (int y = 0; y < h; y++) { - mut.setY(pos.getY() + y + 1); - for (int x = -1; x < 3; x++) { - mut.setX(pos.getX() + x); - for (int z = -1; z < 3; z++) { - mut.setZ(pos.getZ() + z); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); - } - } - } - } - - mut.setY(pos.getY() + h + 1); - for (int x = -1; x < 3; x++) { - mut.setX(pos.getX() + x); - for (int z = -1; z < 3; z++) { - mut.setZ(pos.getZ() + z); - if (((x >> 1) == 0 || (z >> 1) == 0) && world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); - } - } - } - } else { - for (int i = -2; i < 3; i++) { - mut.set(pos).move(Direction.NORTH, 3).move(Direction.EAST, i); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.move(Direction.UP); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.move(Direction.NORTH); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - - mut.set(pos).move(Direction.SOUTH, 3).move(Direction.EAST, i); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.move(Direction.UP); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.move(Direction.SOUTH); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - - mut.set(pos).move(Direction.EAST, 3).move(Direction.NORTH, i); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.move(Direction.UP); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.move(Direction.EAST); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - - mut.set(pos).move(Direction.WEST, 3).move(Direction.NORTH, i); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.move(Direction.UP); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - mut.move(Direction.WEST); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - } - - for (int i = 0; i < 4; i++) { - mut.set(pos).move(Direction.UP).move(BlocksHelper.HORIZONTAL[i], 3) - .move(BlocksHelper.HORIZONTAL[(i + 1) & 3], 3); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE); - } - } - - for (int x = -2; x < 3; x++) { - for (int z = -2; z < 3; z++) { - mut.set(pos).move(x, 0, z); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN); - mut.move(Direction.DOWN); - if ((x / 2) == 0 || (z / 2) == 0) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN); - Axis axis = x < 0 || x > 1 ? Axis.X : Axis.Z; - int distance = axis == Axis.X ? x < 0 ? -1 : 1 : z < 0 ? -1 : 1; - BlockPos offseted = mut.relative(axis, distance); - if (world.getBlockState(offseted).getMaterial().isReplaceable()) { - Direction dir = Direction.fromAxisAndDirection(axis, - distance < 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE); - BlocksHelper.setWithoutUpdate(world, offseted, EndBlocks.AMARANITA_FUR - .defaultBlockState().setValue(BaseAttachedBlock.FACING, dir)); - } - mut.move(Direction.DOWN); - } - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_FUR.defaultBlockState() - .setValue(BaseAttachedBlock.FACING, Direction.DOWN)); - } - } - } - } - - for (int y = 0; y < 3; y++) { - mut.setY(pos.getY() + y + 1); - for (int x = -2; x < 3; x++) { - mut.setX(pos.getX() + x); - for (int z = -2; z < 3; z++) { - mut.setZ(pos.getZ() + z); - if (world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); - } - } - } - } - - int h = radius + 1; - for (int y = 4; y < h; y++) { - mut.setY(pos.getY() + y); - for (int x = -2; x < 3; x++) { - mut.setX(pos.getX() + x); - for (int z = -2; z < 3; z++) { - mut.setZ(pos.getZ() + z); - if (y < 6) { - if (((x / 2) == 0 || (z / 2) == 0) - && world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); - } - } else { - if ((x == 0 || z == 0) && (Math.abs(x) < 2 && Math.abs(z) < 2) - && world.getBlockState(mut).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP); - } - } - } - } - } - } - } - - static { - REPLACE = (state) -> { - if (state.is(TagAPI.END_GROUND) || state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - - IGNORE = EndBlocks.DRAGON_TREE::isTreeLog; - - POST = (info) -> { - if (!info.getStateUp().is(EndBlocks.AMARANITA_STEM) || !info.getStateDown().is(EndBlocks.AMARANITA_STEM)) { - return EndBlocks.AMARANITA_HYPHAE.defaultBlockState(); - } - return info.getState(); - }; - } -} diff --git a/src/main/java/ru/betterend/world/features/trees/HelixTreeFeature.java b/src/main/java/ru/betterend/world/features/trees/HelixTreeFeature.java deleted file mode 100644 index 038ae0fc..00000000 --- a/src/main/java/ru/betterend/world/features/trees/HelixTreeFeature.java +++ /dev/null @@ -1,193 +0,0 @@ -package ru.betterend.world.features.trees; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import java.util.function.Function; - -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.util.Mth; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.phys.AABB; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.PosInfo; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFRotation; -import ru.bclib.sdf.operator.SDFScale; -import ru.bclib.sdf.operator.SDFSmoothUnion; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.operator.SDFUnion; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.HelixTreeLeavesBlock; -import ru.betterend.registry.EndBlocks; - -public class HelixTreeFeature extends DefaultFeature { - private static final Function POST; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND)) - return false; - BlocksHelper.setWithoutUpdate(world, pos, AIR); - - float angle = random.nextFloat() * MHelper.PI2; - float radiusRange = MHelper.randRange(4.5F, 6F, random); - float scale = MHelper.randRange(0.5F, 1F, random); - - float dx; - float dz; - List spline = new ArrayList(10); - for (int i = 0; i < 10; i++) { - float radius = (0.9F - i * 0.1F) * radiusRange; - dx = (float) Math.sin(i + angle) * radius; - dz = (float) Math.cos(i + angle) * radius; - spline.add(new Vector3f(dx, i * 2, dz)); - } - SDF sdf = SplineHelper.buildSDF(spline, 1.7F, 0.5F, (p) -> { - return EndBlocks.HELIX_TREE.bark.defaultBlockState(); - }); - SDF rotated = new SDFRotation().setRotation(Vector3f.YP, (float) Math.PI).setSource(sdf); - sdf = new SDFUnion().setSourceA(rotated).setSourceB(sdf); - - Vector3f lastPoint = spline.get(spline.size() - 1); - List spline2 = SplineHelper.makeSpline(0, 0, 0, 0, 20, 0, 5); - SDF stem = SplineHelper.buildSDF(spline2, 1.0F, 0.5F, (p) -> { - return EndBlocks.HELIX_TREE.bark.defaultBlockState(); - }); - stem = new SDFTranslate().setTranslate(lastPoint.x(), lastPoint.y(), lastPoint.z()).setSource(stem); - sdf = new SDFSmoothUnion().setRadius(3).setSourceA(sdf).setSourceB(stem); - - sdf = new SDFScale().setScale(scale).setSource(sdf); - dx = 30 * scale; - float dy1 = -20 * scale; - float dy2 = 100 * scale; - sdf.addPostProcess(POST).fillArea(world, pos, new AABB(pos.offset(-dx, dy1, -dx), pos.offset(dx, dy2, dx))); - SplineHelper.scale(spline, scale); - SplineHelper.fillSplineForce(spline, world, EndBlocks.HELIX_TREE.bark.defaultBlockState(), pos, (state) -> { - return state.getMaterial().isReplaceable(); - }); - SplineHelper.rotateSpline(spline, (float) Math.PI); - SplineHelper.fillSplineForce(spline, world, EndBlocks.HELIX_TREE.bark.defaultBlockState(), pos, (state) -> { - return state.getMaterial().isReplaceable(); - }); - SplineHelper.scale(spline2, scale); - BlockPos leafStart = pos.offset(lastPoint.x() + 0.5, lastPoint.y() + 0.5, lastPoint.z() + 0.5); - SplineHelper.fillSplineForce(spline2, world, EndBlocks.HELIX_TREE.log.defaultBlockState(), leafStart, - (state) -> { - return state.getMaterial().isReplaceable(); - }); - - spline.clear(); - float rad = MHelper.randRange(8F, 11F, random); - int count = MHelper.randRange(20, 30, random); - float scaleM = 20F / (float) count * scale * 1.75F; - float hscale = 20F / (float) count * 0.05F; - for (int i = 0; i <= count; i++) { - float radius = 1 - i * hscale; - radius = radius * radius * 2 - 1; - radius *= radius; - radius = (1 - radius) * rad * scale; - dx = (float) Math.sin(i * 0.45F + angle) * radius; - dz = (float) Math.cos(i * 0.45F + angle) * radius; - spline.add(new Vector3f(dx, i * scaleM, dz)); - } - - Vector3f start = new Vector3f(); - Vector3f end = new Vector3f(); - lastPoint = spline.get(0); - BlockState leaf = EndBlocks.HELIX_TREE_LEAVES.defaultBlockState(); - for (int i = 1; i < spline.size(); i++) { - Vector3f point = spline.get(i); - int minY = MHelper.floor(lastPoint.y()); - int maxY = MHelper.floor(point.y()); - float div = point.y() - lastPoint.y(); - for (float py = minY; py <= maxY; py += 0.2F) { - start.set(0, py, 0); - float delta = (float) (py - minY) / div; - float px = Mth.lerp(delta, lastPoint.x(), point.x()); - float pz = Mth.lerp(delta, lastPoint.z(), point.z()); - end.set(px, py, pz); - fillLine(start, end, world, leaf, leafStart, i / 2 - 1); - float ax = Math.abs(px); - float az = Math.abs(pz); - if (ax > az) { - start.set(start.x(), start.y(), start.z() + az > 0 ? 1 : -1); - end.set(end.x(), end.y(), end.z() + az > 0 ? 1 : -1); - } else { - start.set(start.x() + ax > 0 ? 1 : -1, start.y(), start.z()); - end.set(end.x() + ax > 0 ? 1 : -1, end.y(), end.z()); - } - fillLine(start, end, world, leaf, leafStart, i / 2 - 1); - } - lastPoint = point; - } - - leaf = leaf.setValue(HelixTreeLeavesBlock.COLOR, 7); - leafStart = leafStart.offset(0, lastPoint.y(), 0); - if (world.getBlockState(leafStart).isAir()) { - BlocksHelper.setWithoutUpdate(world, leafStart, leaf); - leafStart = leafStart.above(); - if (world.getBlockState(leafStart).isAir()) { - BlocksHelper.setWithoutUpdate(world, leafStart, leaf); - leafStart = leafStart.above(); - if (world.getBlockState(leafStart).isAir()) { - BlocksHelper.setWithoutUpdate(world, leafStart, leaf); - } - } - } - - return true; - } - - private void fillLine(Vector3f start, Vector3f end, WorldGenLevel world, BlockState state, BlockPos pos, - int offset) { - float dx = end.x() - start.x(); - float dy = end.y() - start.y(); - float dz = end.z() - start.z(); - float max = MHelper.max(Math.abs(dx), Math.abs(dy), Math.abs(dz)); - int count = MHelper.floor(max + 1); - dx /= max; - dy /= max; - dz /= max; - float x = start.x(); - float y = start.y(); - float z = start.z(); - - MutableBlockPos bPos = new MutableBlockPos(); - for (int i = 0; i < count; i++) { - bPos.set(x + pos.getX(), y + pos.getY(), z + pos.getZ()); - int color = MHelper.floor((float) i / (float) count * 7F + 0.5F) + offset; - color = Mth.clamp(color, 0, 7); - if (world.getBlockState(bPos).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, bPos, state.setValue(HelixTreeLeavesBlock.COLOR, color)); - } - x += dx; - y += dy; - z += dz; - } - bPos.set(end.x() + pos.getX(), end.y() + pos.getY(), end.z() + pos.getZ()); - if (world.getBlockState(bPos).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, bPos, state.setValue(HelixTreeLeavesBlock.COLOR, 7)); - } - } - - static { - POST = (info) -> { - if (EndBlocks.HELIX_TREE.isTreeLog(info.getStateUp()) - && EndBlocks.HELIX_TREE.isTreeLog(info.getStateDown())) { - return EndBlocks.HELIX_TREE.log.defaultBlockState(); - } - return info.getState(); - }; - } -} diff --git a/src/main/java/ru/betterend/world/features/trees/JellyshroomFeature.java b/src/main/java/ru/betterend/world/features/trees/JellyshroomFeature.java deleted file mode 100644 index 3680e707..00000000 --- a/src/main/java/ru/betterend/world/features/trees/JellyshroomFeature.java +++ /dev/null @@ -1,127 +0,0 @@ -package ru.betterend.world.features.trees; - -import java.util.List; -import java.util.Random; -import java.util.function.Function; - -import com.google.common.collect.Lists; -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.util.Mth; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFFlatWave; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.operator.SDFSmoothUnion; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.JellyshroomCapBlock; -import ru.betterend.registry.EndBlocks; - -public class JellyshroomFeature extends DefaultFeature { - private static final Function REPLACE; - private static final List ROOT; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND)) - return false; - - BlockState bark = EndBlocks.JELLYSHROOM.bark.defaultBlockState(); - BlockState membrane = EndBlocks.JELLYSHROOM_CAP_PURPLE.defaultBlockState(); - - int height = MHelper.randRange(5, 8, random); - float radius = height * MHelper.randRange(0.15F, 0.25F, random); - List spline = SplineHelper.makeSpline(0, -1, 0, 0, height, 0, 3); - SplineHelper.offsetParts(spline, random, 0.5F, 0, 0.5F); - SDF sdf = SplineHelper.buildSDF(spline, radius, 0.8F, (bpos) -> { - return bark; - }); - - radius = height * MHelper.randRange(0.7F, 0.9F, random); - if (radius < 1.5F) { - radius = 1.5F; - } - final float membraneRadius = radius; - SDF cap = makeCap(membraneRadius, random, membrane); - final Vector3f last = spline.get(spline.size() - 1); - cap = new SDFTranslate().setTranslate(last.x(), last.y(), last.z()).setSource(cap); - sdf = new SDFSmoothUnion().setRadius(3F).setSourceA(sdf).setSourceB(cap); - sdf.setReplaceFunction(REPLACE).addPostProcess((info) -> { - if (EndBlocks.JELLYSHROOM.isTreeLog(info.getState())) { - if (EndBlocks.JELLYSHROOM.isTreeLog(info.getStateUp()) - && EndBlocks.JELLYSHROOM.isTreeLog(info.getStateDown())) { - return EndBlocks.JELLYSHROOM.log.defaultBlockState(); - } - } else if (info.getState().is(EndBlocks.JELLYSHROOM_CAP_PURPLE)) { - float dx = info.getPos().getX() - pos.getX() - last.x(); - float dz = info.getPos().getZ() - pos.getZ() - last.z(); - float distance = MHelper.length(dx, dz) / membraneRadius * 7F; - int color = Mth.clamp(MHelper.floor(distance), 0, 7); - return info.getState().setValue(JellyshroomCapBlock.COLOR, color); - } - return info.getState(); - }).fillRecursive(world, pos); - radius = height * 0.5F; - makeRoots(world, pos.offset(0, 2, 0), radius, random, bark); - - return true; - } - - private void makeRoots(WorldGenLevel world, BlockPos pos, float radius, Random random, BlockState wood) { - int count = (int) (radius * 3.5F); - for (int i = 0; i < count; i++) { - float angle = (float) i / (float) count * MHelper.PI2; - float scale = radius * MHelper.randRange(0.85F, 1.15F, random); - - List branch = SplineHelper.copySpline(ROOT); - SplineHelper.rotateSpline(branch, angle); - SplineHelper.scale(branch, scale); - Vector3f last = branch.get(branch.size() - 1); - if (world.getBlockState(pos.offset(last.x(), last.y(), last.z())).is(TagAPI.GEN_TERRAIN)) { - SplineHelper.fillSpline(branch, world, wood, pos, REPLACE); - } - } - } - - private SDF makeCap(float radius, Random random, BlockState cap) { - SDF sphere = new SDFSphere().setRadius(radius).setBlock(cap); - SDF sub = new SDFTranslate().setTranslate(0, -4, 0).setSource(sphere); - sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sub); - sphere = new SDFScale3D().setScale(1, 0.5F, 1).setSource(sphere); - sphere = new SDFTranslate().setTranslate(0, 1 - radius * 0.5F, 0).setSource(sphere); - - float angle = random.nextFloat() * MHelper.PI2; - int count = (int) MHelper.randRange(radius * 0.5F, radius, random); - if (count < 3) { - count = 3; - } - sphere = new SDFFlatWave().setAngle(angle).setRaysCount(count).setIntensity(0.2F).setSource(sphere); - - return sphere; - } - - static { - ROOT = Lists.newArrayList(new Vector3f(0.1F, 0.70F, 0), new Vector3f(0.3F, 0.30F, 0), - new Vector3f(0.7F, 0.05F, 0), new Vector3f(0.8F, -0.20F, 0)); - SplineHelper.offset(ROOT, new Vector3f(0, -0.45F, 0)); - - REPLACE = (state) -> { - if (state.is(TagAPI.END_GROUND) || state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - } -} diff --git a/src/main/java/ru/betterend/world/features/trees/LacugroveFeature.java b/src/main/java/ru/betterend/world/features/trees/LacugroveFeature.java deleted file mode 100644 index 9485d5ce..00000000 --- a/src/main/java/ru/betterend/world/features/trees/LacugroveFeature.java +++ /dev/null @@ -1,210 +0,0 @@ -package ru.betterend.world.features.trees; - -import java.util.List; -import java.util.Random; -import java.util.function.Function; - -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.LeavesBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.PosInfo; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class LacugroveFeature extends DefaultFeature { - private static final Function REPLACE; - private static final Function IGNORE; - private static final Function POST; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).is(TagAPI.END_GROUND)) - return false; - - float size = MHelper.randRange(15, 25, random); - List spline = SplineHelper.makeSpline(0, 0, 0, 0, size, 0, 6); - SplineHelper.offsetParts(spline, random, 1F, 0, 1F); - - if (!SplineHelper.canGenerate(spline, pos, world, REPLACE)) { - return false; - } - - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); - - float radius = MHelper.randRange(6F, 8F, random); - radius *= (size - 15F) / 20F + 1F; - Vector3f center = spline.get(4); - leavesBall(world, pos.offset(center.x(), center.y(), center.z()), radius, random, noise); - - radius = MHelper.randRange(1.2F, 1.8F, random); - SDF function = SplineHelper.buildSDF(spline, radius, 0.7F, (bpos) -> { - return EndBlocks.LACUGROVE.bark.defaultBlockState(); - }); - - function.setReplaceFunction(REPLACE); - function.addPostProcess(POST); - function.fillRecursive(world, pos); - - spline = spline.subList(4, 6); - SplineHelper.fillSpline(spline, world, EndBlocks.LACUGROVE.bark.defaultBlockState(), pos, REPLACE); - - MutableBlockPos mut = new MutableBlockPos(); - int offset = random.nextInt(2); - for (int i = 0; i < 100; i++) { - double px = pos.getX() + MHelper.randRange(-5, 5, random); - double pz = pos.getZ() + MHelper.randRange(-5, 5, random); - mut.setX(MHelper.floor(px + 0.5)); - mut.setZ(MHelper.floor(pz + 0.5)); - if (((mut.getX() + mut.getZ() + offset) & 1) == 0) { - double distance = 3.5 - MHelper.length(px - pos.getX(), pz - pos.getZ()) * 0.5; - if (distance > 0) { - int minY = MHelper.floor(pos.getY() - distance * 0.5); - int maxY = MHelper.floor(pos.getY() + distance + random.nextDouble()); - boolean generate = false; - for (int y = minY; y < maxY; y++) { - mut.setY(y); - if (world.getBlockState(mut).is(TagAPI.END_GROUND)) { - generate = true; - break; - } - } - if (generate) { - int top = maxY - 1; - for (int y = top; y >= minY; y--) { - mut.setY(y); - BlockState state = world.getBlockState(mut); - if (state.getMaterial().isReplaceable() || state.getMaterial().equals(Material.PLANT) - || state.is(TagAPI.END_GROUND)) { - BlocksHelper.setWithoutUpdate(world, mut, - y == top ? EndBlocks.LACUGROVE.bark : EndBlocks.LACUGROVE.log); - } else { - break; - } - } - } - } - } - } - - return true; - } - - private void leavesBall(WorldGenLevel world, BlockPos pos, float radius, Random random, OpenSimplexNoise noise) { - SDF sphere = new SDFSphere().setRadius(radius) - .setBlock(EndBlocks.LACUGROVE_LEAVES.defaultBlockState().setValue(LeavesBlock.DISTANCE, 6)); - sphere = new SDFDisplacement().setFunction((vec) -> { - return (float) noise.eval(vec.x() * 0.2, vec.y() * 0.2, vec.z() * 0.2) * 3; - }).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> { - return random.nextFloat() * 3F - 1.5F; - }).setSource(sphere); - sphere = new SDFSubtraction().setSourceA(sphere) - .setSourceB(new SDFTranslate().setTranslate(0, -radius - 2, 0).setSource(sphere)); - MutableBlockPos mut = new MutableBlockPos(); - sphere.addPostProcess((info) -> { - if (random.nextInt(5) == 0) { - for (Direction dir : Direction.values()) { - BlockState state = info.getState(dir, 2); - if (state.isAir()) { - return info.getState(); - } - } - info.setState(EndBlocks.LACUGROVE.bark.defaultBlockState()); - for (int x = -6; x < 7; x++) { - int ax = Math.abs(x); - mut.setX(x + info.getPos().getX()); - for (int z = -6; z < 7; z++) { - int az = Math.abs(z); - mut.setZ(z + info.getPos().getZ()); - for (int y = -6; y < 7; y++) { - int ay = Math.abs(y); - int d = ax + ay + az; - if (d < 7) { - mut.setY(y + info.getPos().getY()); - BlockState state = info.getState(mut); - if (state.getBlock() instanceof LeavesBlock) { - int distance = state.getValue(LeavesBlock.DISTANCE); - if (d < distance) { - info.setState(mut, state.setValue(LeavesBlock.DISTANCE, d)); - } - } - } - } - } - } - } - return info.getState(); - }); - sphere.fillRecursiveIgnore(world, pos, IGNORE); - - if (radius > 5) { - int count = (int) (radius * 2.5F); - for (int i = 0; i < count; i++) { - BlockPos p = pos.offset(random.nextGaussian() * 1, random.nextGaussian() * 1, - random.nextGaussian() * 1); - boolean place = true; - for (Direction d : Direction.values()) { - BlockState state = world.getBlockState(p.relative(d)); - if (!EndBlocks.LACUGROVE.isTreeLog(state) && !state.is(EndBlocks.LACUGROVE_LEAVES)) { - place = false; - break; - } - } - if (place) { - BlocksHelper.setWithoutUpdate(world, p, EndBlocks.LACUGROVE.bark); - } - } - } - - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.LACUGROVE.bark); - } - - static { - REPLACE = (state) -> { - if (state.is(TagAPI.END_GROUND)) { - return true; - } - if (EndBlocks.LACUGROVE.isTreeLog(state)) { - return true; - } - if (state.getBlock() == EndBlocks.LACUGROVE_LEAVES) { - return true; - } - if (state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - - IGNORE = (state) -> { - return EndBlocks.LACUGROVE.isTreeLog(state); - }; - - POST = (info) -> { - if (EndBlocks.LACUGROVE.isTreeLog(info.getStateUp()) - && EndBlocks.LACUGROVE.isTreeLog(info.getStateDown())) { - return EndBlocks.LACUGROVE.log.defaultBlockState(); - } - return info.getState(); - }; - } -} diff --git a/src/main/java/ru/betterend/world/features/trees/LucerniaFeature.java b/src/main/java/ru/betterend/world/features/trees/LucerniaFeature.java deleted file mode 100644 index b8a8ffc6..00000000 --- a/src/main/java/ru/betterend/world/features/trees/LucerniaFeature.java +++ /dev/null @@ -1,215 +0,0 @@ -package ru.betterend.world.features.trees; - -import java.util.List; -import java.util.Random; -import java.util.function.Function; - -import com.google.common.collect.Lists; -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.LeavesBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFScale; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.basis.FurBlock; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class LucerniaFeature extends DefaultFeature { - private static final Direction[] DIRECTIONS = Direction.values(); - private static final Function REPLACE; - private static final Function IGNORE; - private static final List SPLINE; - private static final List ROOT; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND)) - return false; - - float size = MHelper.randRange(12, 20, random); - int count = (int) (size * 0.3F); - float var = MHelper.PI2 / (float) (count * 3); - float start = MHelper.randRange(0, MHelper.PI2, random); - for (int i = 0; i < count; i++) { - float angle = (float) i / (float) count * MHelper.PI2 + MHelper.randRange(0, var, random) + start; - List spline = SplineHelper.copySpline(SPLINE); - SplineHelper.rotateSpline(spline, angle); - SplineHelper.scale(spline, size * MHelper.randRange(0.5F, 1F, random)); - SplineHelper.offsetParts(spline, random, 1F, 0, 1F); - SplineHelper.fillSpline(spline, world, EndBlocks.LUCERNIA.bark.defaultBlockState(), pos, REPLACE); - Vector3f last = spline.get(spline.size() - 1); - float leavesRadius = (size * 0.13F + MHelper.randRange(0.8F, 1.5F, random)) * 1.4F; - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); - leavesBall(world, pos.offset(last.x(), last.y(), last.z()), leavesRadius, random, noise, config != null); - } - - makeRoots(world, pos.offset(0, MHelper.randRange(3, 5, random), 0), size * 0.35F, random); - - return true; - } - - private void leavesBall(WorldGenLevel world, BlockPos pos, float radius, Random random, OpenSimplexNoise noise, - boolean natural) { - SDF sphere = new SDFSphere().setRadius(radius) - .setBlock(EndBlocks.LUCERNIA_LEAVES.defaultBlockState().setValue(LeavesBlock.DISTANCE, 6)); - SDF sub = new SDFScale().setScale(5).setSource(sphere); - sub = new SDFTranslate().setTranslate(0, -radius * 5, 0).setSource(sub); - sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sub); - sphere = new SDFScale3D().setScale(1, 0.75F, 1).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> - (float) noise.eval(vec.x() * 0.2, vec.y() * 0.2, vec.z() * 0.2) * 2F).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> - MHelper.randRange(-1.5F, 1.5F, random)).setSource(sphere); - - MutableBlockPos mut = new MutableBlockPos(); - for (Direction d1 : BlocksHelper.HORIZONTAL) { - BlockPos p = mut.set(pos).move(Direction.UP).move(d1).immutable(); - BlocksHelper.setWithoutUpdate(world, p, EndBlocks.LUCERNIA.bark.defaultBlockState()); - for (Direction d2 : BlocksHelper.HORIZONTAL) { - mut.set(p).move(Direction.UP).move(d2); - BlocksHelper.setWithoutUpdate(world, p, EndBlocks.LUCERNIA.bark.defaultBlockState()); - } - } - - BlockState top = EndBlocks.FILALUX.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP); - BlockState middle = EndBlocks.FILALUX.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, - TripleShape.MIDDLE); - BlockState bottom = EndBlocks.FILALUX.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, - TripleShape.BOTTOM); - BlockState outer = EndBlocks.LUCERNIA_OUTER_LEAVES.defaultBlockState(); - - List support = Lists.newArrayList(); - sphere.addPostProcess((info) -> { - if (natural && random.nextInt(6) == 0 && info.getStateDown().isAir()) { - BlockPos d = info.getPos().below(); - support.add(d); - } - if (random.nextInt(15) == 0) { - for (Direction dir : Direction.values()) { - BlockState state = info.getState(dir, 2); - if (state.isAir()) { - return info.getState(); - } - } - info.setState(EndBlocks.LUCERNIA.bark.defaultBlockState()); - } - - MHelper.shuffle(DIRECTIONS, random); - for (Direction d : DIRECTIONS) { - if (info.getState(d).isAir()) { - info.setBlockPos(info.getPos().relative(d), outer.setValue(FurBlock.FACING, d)); - } - } - - if (EndBlocks.LUCERNIA.isTreeLog(info.getState())) { - for (int x = -6; x < 7; x++) { - int ax = Math.abs(x); - mut.setX(x + info.getPos().getX()); - for (int z = -6; z < 7; z++) { - int az = Math.abs(z); - mut.setZ(z + info.getPos().getZ()); - for (int y = -6; y < 7; y++) { - int ay = Math.abs(y); - int d = ax + ay + az; - if (d < 7) { - mut.setY(y + info.getPos().getY()); - BlockState state = info.getState(mut); - if (state.getBlock() instanceof LeavesBlock) { - int distance = state.getValue(LeavesBlock.DISTANCE); - if (d < distance) { - info.setState(mut, state.setValue(LeavesBlock.DISTANCE, d)); - } - } - } - } - } - } - } - return info.getState(); - }); - sphere.fillRecursiveIgnore(world, pos, IGNORE); - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.LUCERNIA.bark); - - support.forEach((bpos) -> { - BlockState state = world.getBlockState(bpos); - if (state.isAir() || state.is(EndBlocks.LUCERNIA_OUTER_LEAVES)) { - int count = MHelper.randRange(3, 8, random); - mut.set(bpos); - if (world.getBlockState(mut.above()).is(EndBlocks.LUCERNIA_LEAVES)) { - BlocksHelper.setWithoutUpdate(world, mut, top); - for (int i = 1; i < count; i++) { - mut.setY(mut.getY() - 1); - if (world.isEmptyBlock(mut.below())) { - BlocksHelper.setWithoutUpdate(world, mut, middle); - } else { - break; - } - } - BlocksHelper.setWithoutUpdate(world, mut, bottom); - } - } - }); - } - - private void makeRoots(WorldGenLevel world, BlockPos pos, float radius, Random random) { - int count = (int) (radius * 1.5F); - for (int i = 0; i < count; i++) { - float angle = (float) i / (float) count * MHelper.PI2; - float scale = radius * MHelper.randRange(0.85F, 1.15F, random); - - List branch = SplineHelper.copySpline(ROOT); - SplineHelper.rotateSpline(branch, angle); - SplineHelper.scale(branch, scale); - Vector3f last = branch.get(branch.size() - 1); - if (world.getBlockState(pos.offset(last.x(), last.y(), last.z())).is(TagAPI.GEN_TERRAIN)) { - SplineHelper.fillSplineForce(branch, world, EndBlocks.LUCERNIA.bark.defaultBlockState(), pos, REPLACE); - } - } - } - - static { - REPLACE = (state) -> { - if (state.is(TagAPI.END_GROUND)) { - return true; - } - if (state.getBlock() == EndBlocks.LUCERNIA_LEAVES) { - return true; - } - if (state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - - IGNORE = EndBlocks.LUCERNIA::isTreeLog; - - SPLINE = Lists.newArrayList(new Vector3f(0.00F, 0.00F, 0.00F), new Vector3f(0.10F, 0.35F, 0.00F), - new Vector3f(0.20F, 0.50F, 0.00F), new Vector3f(0.30F, 0.55F, 0.00F), new Vector3f(0.42F, 0.70F, 0.00F), - new Vector3f(0.50F, 1.00F, 0.00F)); - - ROOT = Lists.newArrayList(new Vector3f(0.1F, 0.70F, 0), new Vector3f(0.3F, 0.30F, 0), - new Vector3f(0.7F, 0.05F, 0), new Vector3f(0.8F, -0.20F, 0)); - SplineHelper.offset(ROOT, new Vector3f(0, -0.45F, 0)); - } -} diff --git a/src/main/java/ru/betterend/world/features/trees/MossyGlowshroomFeature.java b/src/main/java/ru/betterend/world/features/trees/MossyGlowshroomFeature.java deleted file mode 100644 index fd076dbc..00000000 --- a/src/main/java/ru/betterend/world/features/trees/MossyGlowshroomFeature.java +++ /dev/null @@ -1,177 +0,0 @@ -package ru.betterend.world.features.trees; - -import java.util.List; -import java.util.Random; -import java.util.function.Function; - -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFBinary; -import ru.bclib.sdf.operator.SDFCoordModify; -import ru.bclib.sdf.operator.SDFFlatWave; -import ru.bclib.sdf.operator.SDFScale; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.operator.SDFSmoothUnion; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.operator.SDFUnion; -import ru.bclib.sdf.primitive.SDFCappedCone; -import ru.bclib.sdf.primitive.SDFPrimitive; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.MossyGlowshroomCapBlock; -import ru.betterend.blocks.basis.FurBlock; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class MossyGlowshroomFeature extends DefaultFeature { - private static final Function REPLACE; - private static final Vector3f CENTER = new Vector3f(); - private static final SDFBinary FUNCTION; - private static final SDFTranslate HEAD_POS; - private static final SDFFlatWave ROOTS_ROT; - - private static final SDFPrimitive CONE1; - private static final SDFPrimitive CONE2; - private static final SDFPrimitive CONE_GLOW; - private static final SDFPrimitive ROOTS; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, - NoneFeatureConfiguration featureConfig) { - BlockState down = world.getBlockState(blockPos.below()); - if (!down.is(EndBlocks.END_MYCELIUM) && !down.is(EndBlocks.END_MOSS)) - return false; - - CONE1.setBlock(EndBlocks.MOSSY_GLOWSHROOM_CAP); - CONE2.setBlock(EndBlocks.MOSSY_GLOWSHROOM_CAP); - CONE_GLOW.setBlock(EndBlocks.MOSSY_GLOWSHROOM_HYMENOPHORE); - ROOTS.setBlock(EndBlocks.MOSSY_GLOWSHROOM.bark); - - float height = MHelper.randRange(10F, 25F, random); - int count = MHelper.floor(height / 4); - List spline = SplineHelper.makeSpline(0, 0, 0, 0, height, 0, count); - SplineHelper.offsetParts(spline, random, 1F, 0, 1F); - SDF sdf = SplineHelper.buildSDF(spline, 2.1F, 1.5F, (pos) -> { - return EndBlocks.MOSSY_GLOWSHROOM.log.defaultBlockState(); - }); - Vector3f pos = spline.get(spline.size() - 1); - float scale = MHelper.randRange(0.75F, 1.1F, random); - - if (!SplineHelper.canGenerate(spline, scale, blockPos, world, REPLACE)) { - return false; - } - BlocksHelper.setWithoutUpdate(world, blockPos, AIR); - - CENTER.set(blockPos.getX(), 0, blockPos.getZ()); - HEAD_POS.setTranslate(pos.x(), pos.y(), pos.z()); - ROOTS_ROT.setAngle(random.nextFloat() * MHelper.PI2); - FUNCTION.setSourceA(sdf); - - new SDFScale().setScale(scale).setSource(FUNCTION).setReplaceFunction(REPLACE).addPostProcess((info) -> { - if (EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getState())) { - if (random.nextBoolean() && info.getStateUp().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_CAP) { - info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.defaultBlockState() - .setValue(MossyGlowshroomCapBlock.TRANSITION, true)); - return info.getState(); - } - else if (!EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getStateUp()) - || !EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown())) { - info.setState(EndBlocks.MOSSY_GLOWSHROOM.bark.defaultBlockState()); - return info.getState(); - } - } - else if (info.getState().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_CAP) { - if (EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown().getBlock())) { - info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.defaultBlockState() - .setValue(MossyGlowshroomCapBlock.TRANSITION, true)); - return info.getState(); - } - - info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.defaultBlockState()); - return info.getState(); - } - else if (info.getState().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_HYMENOPHORE) { - for (Direction dir : BlocksHelper.HORIZONTAL) { - if (info.getState(dir) == AIR) { - info.setBlockPos(info.getPos().relative(dir), - EndBlocks.MOSSY_GLOWSHROOM_FUR.defaultBlockState().setValue(FurBlock.FACING, dir)); - } - } - - if (info.getStateDown().getBlock() != EndBlocks.MOSSY_GLOWSHROOM_HYMENOPHORE) { - info.setBlockPos(info.getPos().below(), EndBlocks.MOSSY_GLOWSHROOM_FUR.defaultBlockState() - .setValue(FurBlock.FACING, Direction.DOWN)); - } - } - return info.getState(); - }).fillRecursive(world, blockPos); - - return true; - } - - static { - SDFCappedCone cone1 = new SDFCappedCone().setHeight(2.5F).setRadius1(1.5F).setRadius2(2.5F); - SDFCappedCone cone2 = new SDFCappedCone().setHeight(3F).setRadius1(2.5F).setRadius2(13F); - SDF posedCone2 = new SDFTranslate().setTranslate(0, 5, 0).setSource(cone2); - SDF posedCone3 = new SDFTranslate().setTranslate(0, 12F, 0).setSource(new SDFScale().setScale(2).setSource(cone2)); - SDF upCone = new SDFSubtraction().setSourceA(posedCone2).setSourceB(posedCone3); - SDF wave = new SDFFlatWave().setRaysCount(12).setIntensity(1.3F).setSource(upCone); - SDF cones = new SDFSmoothUnion().setRadius(3).setSourceA(cone1).setSourceB(wave); - - CONE1 = cone1; - CONE2 = cone2; - - SDF innerCone = new SDFTranslate().setTranslate(0, 1.25F, 0).setSource(upCone); - innerCone = new SDFScale3D().setScale(1.2F, 1F, 1.2F).setSource(innerCone); - cones = new SDFUnion().setSourceA(cones).setSourceB(innerCone); - - SDF glowCone = new SDFCappedCone().setHeight(3F).setRadius1(2F).setRadius2(12.5F); - CONE_GLOW = (SDFPrimitive) glowCone; - glowCone = new SDFTranslate().setTranslate(0, 4.25F, 0).setSource(glowCone); - glowCone = new SDFSubtraction().setSourceA(glowCone).setSourceB(posedCone3); - - cones = new SDFUnion().setSourceA(cones).setSourceB(glowCone); - - OpenSimplexNoise noise = new OpenSimplexNoise(1234); - cones = new SDFCoordModify().setFunction((pos) -> { - float dist = MHelper.length(pos.x(), pos.z()); - float y = pos.y() + (float) noise.eval(pos.x() * 0.1 + CENTER.x(), pos.z() * 0.1 + CENTER.z()) * dist * 0.3F - - dist * 0.15F; - pos.set(pos.x(), y, pos.z()); - }).setSource(cones); - - HEAD_POS = (SDFTranslate) new SDFTranslate() - .setSource(new SDFTranslate().setTranslate(0, 2.5F, 0).setSource(cones)); - - SDF roots = new SDFSphere().setRadius(4F); - ROOTS = (SDFPrimitive) roots; - roots = new SDFScale3D().setScale(1, 0.7F, 1).setSource(roots); - ROOTS_ROT = (SDFFlatWave) new SDFFlatWave().setRaysCount(5).setIntensity(1.5F).setSource(roots); - - FUNCTION = new SDFSmoothUnion().setRadius(4) - .setSourceB(new SDFUnion().setSourceA(HEAD_POS).setSourceB(ROOTS_ROT)); - - REPLACE = (state) -> { - if (state.is(TagAPI.END_GROUND)) { - return true; - } - if (state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - } -} diff --git a/src/main/java/ru/betterend/world/features/trees/PythadendronTreeFeature.java b/src/main/java/ru/betterend/world/features/trees/PythadendronTreeFeature.java deleted file mode 100644 index 178bc53c..00000000 --- a/src/main/java/ru/betterend/world/features/trees/PythadendronTreeFeature.java +++ /dev/null @@ -1,195 +0,0 @@ -package ru.betterend.world.features.trees; - -import java.util.List; -import java.util.Random; -import java.util.function.Function; - -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.LeavesBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.PosInfo; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class PythadendronTreeFeature extends DefaultFeature { - private static final Function REPLACE; - private static final Function IGNORE; - private static final Function POST; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, NoneFeatureConfiguration config) { - if (world.getBlockState(pos.below()).getBlock() != EndBlocks.CHORUS_NYLIUM) { - return false; - } - BlocksHelper.setWithoutUpdate(world, pos, AIR); - - float size = MHelper.randRange(10, 20, random); - List spline = SplineHelper.makeSpline(0, 0, 0, 0, size, 0, 4); - SplineHelper.offsetParts(spline, random, 0.7F, 0, 0.7F); - Vector3f last = spline.get(spline.size() - 1); - - int depth = MHelper.floor((size - 10F) * 3F / 10F + 1F); - float bsize = (10F - (size - 10F)) / 10F + 1.5F; - branch(last.x(), last.y(), last.z(), size * bsize, MHelper.randRange(0, MHelper.PI2, random), random, depth, - world, pos); - - SDF function = SplineHelper.buildSDF(spline, 1.7F, 1.1F, (bpos) -> { - return EndBlocks.PYTHADENDRON.bark.defaultBlockState(); - }); - function.setReplaceFunction(REPLACE); - function.addPostProcess(POST); - function.fillRecursive(world, pos); - - return true; - } - - private void branch(float x, float y, float z, float size, float angle, Random random, int depth, - WorldGenLevel world, BlockPos pos) { - if (depth == 0) - return; - - float dx = (float) Math.cos(angle) * size * 0.15F; - float dz = (float) Math.sin(angle) * size * 0.15F; - - float x1 = x + dx; - float z1 = z + dz; - float x2 = x - dx; - float z2 = z - dz; - - List spline = SplineHelper.makeSpline(x, y, z, x1, y, z1, 5); - SplineHelper.powerOffset(spline, size * MHelper.randRange(1.0F, 2.0F, random), 4); - SplineHelper.offsetParts(spline, random, 0.3F, 0, 0.3F); - Vector3f pos1 = spline.get(spline.size() - 1); - - boolean s1 = SplineHelper.fillSpline(spline, world, EndBlocks.PYTHADENDRON.bark.defaultBlockState(), pos, - REPLACE); - - spline = SplineHelper.makeSpline(x, y, z, x2, y, z2, 5); - SplineHelper.powerOffset(spline, size * MHelper.randRange(1.0F, 2.0F, random), 4); - SplineHelper.offsetParts(spline, random, 0.3F, 0, 0.3F); - Vector3f pos2 = spline.get(spline.size() - 1); - - boolean s2 = SplineHelper.fillSpline(spline, world, EndBlocks.PYTHADENDRON.bark.defaultBlockState(), pos, - REPLACE); - - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextInt()); - if (depth < 3) { - if (s1) { - leavesBall(world, pos.offset(pos1.x(), pos1.y(), pos1.z()), random, noise); - } - if (s2) { - leavesBall(world, pos.offset(pos2.x(), pos2.y(), pos2.z()), random, noise); - } - } - - float size1 = size * MHelper.randRange(0.75F, 0.95F, random); - float size2 = size * MHelper.randRange(0.75F, 0.95F, random); - float angle1 = angle + (float) Math.PI * 0.5F + MHelper.randRange(-0.1F, 0.1F, random); - float angle2 = angle + (float) Math.PI * 0.5F + MHelper.randRange(-0.1F, 0.1F, random); - - if (s1) { - branch(pos1.x(), pos1.y(), pos1.z(), size1, angle1, random, depth - 1, world, pos); - } - if (s2) { - branch(pos2.x(), pos2.y(), pos2.z(), size2, angle2, random, depth - 1, world, pos); - } - } - - private void leavesBall(WorldGenLevel world, BlockPos pos, Random random, OpenSimplexNoise noise) { - float radius = MHelper.randRange(4.5F, 6.5F, random); - - SDF sphere = new SDFSphere().setRadius(radius) - .setBlock(EndBlocks.PYTHADENDRON_LEAVES.defaultBlockState().setValue(LeavesBlock.DISTANCE, 6)); - sphere = new SDFScale3D().setScale(1, 0.6F, 1).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> { - return (float) noise.eval(vec.x() * 0.2, vec.y() * 0.2, vec.z() * 0.2) * 3; - }).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> { - return random.nextFloat() * 3F - 1.5F; - }).setSource(sphere); - sphere = new SDFSubtraction().setSourceA(sphere) - .setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere)); - MutableBlockPos mut = new MutableBlockPos(); - sphere.addPostProcess((info) -> { - if (random.nextInt(5) == 0) { - for (Direction dir : Direction.values()) { - BlockState state = info.getState(dir, 2); - if (state.isAir()) { - return info.getState(); - } - } - info.setState(EndBlocks.PYTHADENDRON.bark.defaultBlockState()); - for (int x = -6; x < 7; x++) { - int ax = Math.abs(x); - mut.setX(x + info.getPos().getX()); - for (int z = -6; z < 7; z++) { - int az = Math.abs(z); - mut.setZ(z + info.getPos().getZ()); - for (int y = -6; y < 7; y++) { - int ay = Math.abs(y); - int d = ax + ay + az; - if (d < 7) { - mut.setY(y + info.getPos().getY()); - BlockState state = info.getState(mut); - if (state.getBlock() instanceof LeavesBlock) { - int distance = state.getValue(LeavesBlock.DISTANCE); - if (d < distance) { - info.setState(mut, state.setValue(LeavesBlock.DISTANCE, d)); - } - } - } - } - } - } - } - return info.getState(); - }); - sphere.fillRecursiveIgnore(world, pos, IGNORE); - } - - static { - REPLACE = (state) -> { - if (state.is(TagAPI.END_GROUND)) { - return true; - } - if (state.getBlock() == EndBlocks.PYTHADENDRON_LEAVES) { - return true; - } - if (state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - - IGNORE = (state) -> { - return EndBlocks.PYTHADENDRON.isTreeLog(state); - }; - - POST = (info) -> { - if (EndBlocks.PYTHADENDRON.isTreeLog(info.getStateUp()) - && EndBlocks.PYTHADENDRON.isTreeLog(info.getStateDown())) { - return EndBlocks.PYTHADENDRON.log.defaultBlockState(); - } - return info.getState(); - }; - } -} diff --git a/src/main/java/ru/betterend/world/features/trees/TenaneaFeature.java b/src/main/java/ru/betterend/world/features/trees/TenaneaFeature.java deleted file mode 100644 index 7f9c7ecb..00000000 --- a/src/main/java/ru/betterend/world/features/trees/TenaneaFeature.java +++ /dev/null @@ -1,192 +0,0 @@ -package ru.betterend.world.features.trees; - -import java.util.List; -import java.util.Random; -import java.util.function.Function; - -import com.google.common.collect.Lists; -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.LeavesBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.blocks.BlockProperties; -import ru.bclib.blocks.BlockProperties.TripleShape; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFDisplacement; -import ru.bclib.sdf.operator.SDFScale; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.basis.FurBlock; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class TenaneaFeature extends DefaultFeature { - private static final Direction[] DIRECTIONS = Direction.values(); - private static final Function REPLACE; - private static final Function IGNORE; - private static final List SPLINE; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND)) - return false; - - float size = MHelper.randRange(7, 10, random); - int count = (int) (size * 0.45F); - float var = MHelper.PI2 / (float) (count * 3); - float start = MHelper.randRange(0, MHelper.PI2, random); - for (int i = 0; i < count; i++) { - float angle = (float) i / (float) count * MHelper.PI2 + MHelper.randRange(0, var, random) + start; - List spline = SplineHelper.copySpline(SPLINE); - SplineHelper.rotateSpline(spline, angle); - SplineHelper.scale(spline, size + MHelper.randRange(0, size * 0.5F, random)); - SplineHelper.offsetParts(spline, random, 1F, 0, 1F); - SplineHelper.fillSpline(spline, world, EndBlocks.TENANEA.bark.defaultBlockState(), pos, REPLACE); - Vector3f last = spline.get(spline.size() - 1); - float leavesRadius = (size * 0.3F + MHelper.randRange(0.8F, 1.5F, random)) * 1.4F; - OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); - leavesBall(world, pos.offset(last.x(), last.y(), last.z()), leavesRadius, random, noise); - } - - return true; - } - - private void leavesBall(WorldGenLevel world, BlockPos pos, float radius, Random random, OpenSimplexNoise noise) { - SDF sphere = new SDFSphere().setRadius(radius) - .setBlock(EndBlocks.TENANEA_LEAVES.defaultBlockState().setValue(LeavesBlock.DISTANCE, 6)); - SDF sub = new SDFScale().setScale(5).setSource(sphere); - sub = new SDFTranslate().setTranslate(0, -radius * 5, 0).setSource(sub); - sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sub); - sphere = new SDFScale3D().setScale(1, 0.75F, 1).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> - (float) noise.eval(vec.x() * 0.2, vec.y() * 0.2, vec.z() * 0.2) * 2F).setSource(sphere); - sphere = new SDFDisplacement().setFunction((vec) -> - MHelper.randRange(-1.5F, 1.5F, random)).setSource(sphere); - - MutableBlockPos mut = new MutableBlockPos(); - for (Direction d1 : BlocksHelper.HORIZONTAL) { - BlockPos p = mut.set(pos).move(Direction.UP).move(d1).immutable(); - BlocksHelper.setWithoutUpdate(world, p, EndBlocks.TENANEA.bark.defaultBlockState()); - for (Direction d2 : BlocksHelper.HORIZONTAL) { - mut.set(p).move(Direction.UP).move(d2); - BlocksHelper.setWithoutUpdate(world, p, EndBlocks.TENANEA.bark.defaultBlockState()); - } - } - - BlockState top = EndBlocks.TENANEA_FLOWERS.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, - TripleShape.TOP); - BlockState middle = EndBlocks.TENANEA_FLOWERS.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, - TripleShape.MIDDLE); - BlockState bottom = EndBlocks.TENANEA_FLOWERS.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, - TripleShape.BOTTOM); - BlockState outer = EndBlocks.TENANEA_OUTER_LEAVES.defaultBlockState(); - - List support = Lists.newArrayList(); - sphere.addPostProcess((info) -> { - if (random.nextInt(6) == 0 && info.getStateDown().isAir()) { - BlockPos d = info.getPos().below(); - support.add(d); - } - if (random.nextInt(5) == 0) { - for (Direction dir : Direction.values()) { - BlockState state = info.getState(dir, 2); - if (state.isAir()) { - return info.getState(); - } - } - info.setState(EndBlocks.TENANEA.bark.defaultBlockState()); - } - - MHelper.shuffle(DIRECTIONS, random); - for (Direction d : DIRECTIONS) { - if (info.getState(d).isAir()) { - info.setBlockPos(info.getPos().relative(d), outer.setValue(FurBlock.FACING, d)); - } - } - - if (EndBlocks.TENANEA.isTreeLog(info.getState())) { - for (int x = -6; x < 7; x++) { - int ax = Math.abs(x); - mut.setX(x + info.getPos().getX()); - for (int z = -6; z < 7; z++) { - int az = Math.abs(z); - mut.setZ(z + info.getPos().getZ()); - for (int y = -6; y < 7; y++) { - int ay = Math.abs(y); - int d = ax + ay + az; - if (d < 7) { - mut.setY(y + info.getPos().getY()); - BlockState state = info.getState(mut); - if (state.getBlock() instanceof LeavesBlock) { - int distance = state.getValue(LeavesBlock.DISTANCE); - if (d < distance) { - info.setState(mut, state.setValue(LeavesBlock.DISTANCE, d)); - } - } - } - } - } - } - } - return info.getState(); - }); - sphere.fillRecursiveIgnore(world, pos, IGNORE); - BlocksHelper.setWithoutUpdate(world, pos, EndBlocks.TENANEA.bark); - - support.forEach((bpos) -> { - BlockState state = world.getBlockState(bpos); - if (state.isAir() || state.is(EndBlocks.TENANEA_OUTER_LEAVES)) { - int count = MHelper.randRange(3, 8, random); - mut.set(bpos); - if (world.getBlockState(mut.above()).is(EndBlocks.TENANEA_LEAVES)) { - BlocksHelper.setWithoutUpdate(world, mut, top); - for (int i = 1; i < count; i++) { - mut.setY(mut.getY() - 1); - if (world.isEmptyBlock(mut.below())) { - BlocksHelper.setWithoutUpdate(world, mut, middle); - } else { - break; - } - } - BlocksHelper.setWithoutUpdate(world, mut, bottom); - } - } - }); - } - - static { - REPLACE = (state) -> { - if (state.is(TagAPI.END_GROUND)) { - return true; - } - if (state.getBlock() == EndBlocks.TENANEA_LEAVES) { - return true; - } - if (state.getMaterial().equals(Material.PLANT)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - - IGNORE = EndBlocks.TENANEA::isTreeLog; - - SPLINE = Lists.newArrayList(new Vector3f(0.00F, 0.00F, 0.00F), new Vector3f(0.10F, 0.35F, 0.00F), - new Vector3f(0.20F, 0.50F, 0.00F), new Vector3f(0.30F, 0.55F, 0.00F), new Vector3f(0.42F, 0.70F, 0.00F), - new Vector3f(0.50F, 1.00F, 0.00F)); - } -} diff --git a/src/main/java/ru/betterend/world/features/trees/UmbrellaTreeFeature.java b/src/main/java/ru/betterend/world/features/trees/UmbrellaTreeFeature.java deleted file mode 100644 index f2f7366e..00000000 --- a/src/main/java/ru/betterend/world/features/trees/UmbrellaTreeFeature.java +++ /dev/null @@ -1,234 +0,0 @@ -package ru.betterend.world.features.trees; - -import java.util.List; -import java.util.Random; -import java.util.function.Function; - -import com.google.common.collect.Lists; -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.util.Mth; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.material.Material; -import ru.bclib.api.TagAPI; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFFlatWave; -import ru.bclib.sdf.operator.SDFScale; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.operator.SDFSmoothUnion; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.operator.SDFUnion; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.bclib.world.features.DefaultFeature; -import ru.betterend.blocks.UmbrellaTreeClusterBlock; -import ru.betterend.blocks.UmbrellaTreeMembraneBlock; -import ru.betterend.registry.EndBlocks; - -public class UmbrellaTreeFeature extends DefaultFeature { - private static final Function REPLACE; - private static final List SPLINE; - private static final List ROOT; - - @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).getBlock().is(TagAPI.END_GROUND)) - return false; - - BlockState wood = EndBlocks.UMBRELLA_TREE.bark.defaultBlockState(); - BlockState membrane = EndBlocks.UMBRELLA_TREE_MEMBRANE.defaultBlockState() - .setValue(UmbrellaTreeMembraneBlock.COLOR, 1); - BlockState center = EndBlocks.UMBRELLA_TREE_MEMBRANE.defaultBlockState() - .setValue(UmbrellaTreeMembraneBlock.COLOR, 0); - BlockState fruit = EndBlocks.UMBRELLA_TREE_CLUSTER.defaultBlockState() - .setValue(UmbrellaTreeClusterBlock.NATURAL, true); - - float size = MHelper.randRange(10, 20, random); - int count = (int) (size * 0.15F); - float var = MHelper.PI2 / (float) (count * 3); - float start = MHelper.randRange(0, MHelper.PI2, random); - SDF sdf = null; - List
centers = Lists.newArrayList(); - - float scale = 1; - if (config != null) { - scale = MHelper.randRange(1F, 1.7F, random); - } - - for (int i = 0; i < count; i++) { - float angle = (float) i / (float) count * MHelper.PI2 + MHelper.randRange(0, var, random) + start; - List spline = SplineHelper.copySpline(SPLINE); - float sizeXZ = (size + MHelper.randRange(0, size * 0.5F, random)) * 0.7F; - SplineHelper.scale(spline, sizeXZ, sizeXZ * MHelper.randRange(1F, 2F, random), sizeXZ); - // SplineHelper.offset(spline, new Vector3f((20 - size) * 0.2F, 0, 0)); - SplineHelper.rotateSpline(spline, angle); - SplineHelper.offsetParts(spline, random, 0.5F, 0, 0.5F); - - if (SplineHelper.canGenerate(spline, pos, world, REPLACE)) { - float rScale = (scale - 1) * 0.4F + 1; - SDF branch = SplineHelper.buildSDF(spline, 1.2F * rScale, 0.8F * rScale, (bpos) -> { - return wood; - }); - - Vector3f vec = spline.get(spline.size() - 1); - float radius = (size + MHelper.randRange(0, size * 0.5F, random)) * 0.4F; - - sdf = (sdf == null) ? branch : new SDFUnion().setSourceA(sdf).setSourceB(branch); - SDF mem = makeMembrane(world, radius, random, membrane, center); - - float px = MHelper.floor(vec.x()) + 0.5F; - float py = MHelper.floor(vec.y()) + 0.5F; - float pz = MHelper.floor(vec.z()) + 0.5F; - mem = new SDFTranslate().setTranslate(px, py, pz).setSource(mem); - sdf = new SDFSmoothUnion().setRadius(2).setSourceA(sdf).setSourceB(mem); - centers.add(new Center(pos.getX() + (double) (px * scale), pos.getY() + (double) (py * scale), - pos.getZ() + (double) (pz * scale), radius * scale)); - - vec = spline.get(0); - } - } - - if (sdf == null) { - return false; - } - - if (scale > 1) { - sdf = new SDFScale().setScale(scale).setSource(sdf); - } - - sdf.setReplaceFunction(REPLACE).addPostProcess((info) -> { - if (EndBlocks.UMBRELLA_TREE.isTreeLog(info.getStateUp()) - && EndBlocks.UMBRELLA_TREE.isTreeLog(info.getStateDown())) { - return EndBlocks.UMBRELLA_TREE.log.defaultBlockState(); - } else if (info.getState().equals(membrane)) { - Center min = centers.get(0); - double d = Double.MAX_VALUE; - BlockPos bpos = info.getPos(); - for (Center c : centers) { - double d2 = c.distance(bpos.getX(), bpos.getZ()); - if (d2 < d) { - d = d2; - min = c; - } - } - int color = MHelper.floor(d / min.radius * 7); - color = Mth.clamp(color, 1, 7); - return info.getState().setValue(UmbrellaTreeMembraneBlock.COLOR, color); - } - return info.getState(); - }).fillRecursive(world, pos); - makeRoots(world, pos, (size * 0.5F + 3) * scale, random, wood); - - for (Center c : centers) { - if (!world.getBlockState(new BlockPos(c.px, c.py, c.pz)).isAir()) { - count = MHelper.floor(MHelper.randRange(5F, 10F, random) * scale); - float startAngle = random.nextFloat() * MHelper.PI2; - for (int i = 0; i < count; i++) { - float angle = (float) i / count * MHelper.PI2 + startAngle; - float dist = MHelper.randRange(1.5F, 2.5F, random) * scale; - double px = c.px + Math.sin(angle) * dist; - double pz = c.pz + Math.cos(angle) * dist; - makeFruits(world, px, c.py - 1, pz, fruit, scale); - } - } - } - - return true; - } - - private void makeRoots(WorldGenLevel world, BlockPos pos, float radius, Random random, BlockState wood) { - int count = (int) (radius * 1.5F); - for (int i = 0; i < count; i++) { - float angle = (float) i / (float) count * MHelper.PI2; - float scale = radius * MHelper.randRange(0.85F, 1.15F, random); - - List branch = SplineHelper.copySpline(ROOT); - SplineHelper.rotateSpline(branch, angle); - SplineHelper.scale(branch, scale); - Vector3f last = branch.get(branch.size() - 1); - if (world.getBlockState(pos.offset(last.x(), last.y(), last.z())).is(TagAPI.GEN_TERRAIN)) { - SplineHelper.fillSplineForce(branch, world, wood, pos, REPLACE); - } - } - } - - private SDF makeMembrane(WorldGenLevel world, float radius, Random random, BlockState membrane, BlockState center) { - SDF sphere = new SDFSphere().setRadius(radius).setBlock(membrane); - SDF sub = new SDFTranslate().setTranslate(0, -4, 0).setSource(sphere); - sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(sub); - sphere = new SDFScale3D().setScale(1, 0.5F, 1).setSource(sphere); - sphere = new SDFTranslate().setTranslate(0, 1 - radius * 0.5F, 0).setSource(sphere); - - float angle = random.nextFloat() * MHelper.PI2; - int count = (int) MHelper.randRange(radius, radius * 2, random); - if (count < 5) { - count = 5; - } - sphere = new SDFFlatWave().setAngle(angle).setRaysCount(count).setIntensity(0.6F).setSource(sphere); - - SDF cent = new SDFSphere().setRadius(2.5F).setBlock(center); - sphere = new SDFUnion().setSourceA(sphere).setSourceB(cent); - - return sphere; - } - - private void makeFruits(WorldGenLevel world, double px, double py, double pz, BlockState fruit, float scale) { - MutableBlockPos mut = new MutableBlockPos().set(px, py, pz); - for (int i = 0; i < 8; i++) { - mut.move(Direction.DOWN); - if (world.isEmptyBlock(mut)) { - BlockState state = world.getBlockState(mut.above()); - if (state.is(EndBlocks.UMBRELLA_TREE_MEMBRANE) && state.getValue(UmbrellaTreeMembraneBlock.COLOR) < 2) { - BlocksHelper.setWithoutUpdate(world, mut, fruit); - } - break; - } - } - } - - static { - SPLINE = Lists.newArrayList(new Vector3f(0.00F, 0.00F, 0.00F), new Vector3f(0.10F, 0.35F, 0.00F), - new Vector3f(0.20F, 0.50F, 0.00F), new Vector3f(0.30F, 0.55F, 0.00F), new Vector3f(0.42F, 0.70F, 0.00F), - new Vector3f(0.50F, 1.00F, 0.00F)); - - ROOT = Lists.newArrayList(new Vector3f(0.1F, 0.70F, 0), new Vector3f(0.3F, 0.30F, 0), - new Vector3f(0.7F, 0.05F, 0), new Vector3f(0.8F, -0.20F, 0)); - SplineHelper.offset(ROOT, new Vector3f(0, -0.45F, 0)); - - REPLACE = (state) -> { - if (state.is(TagAPI.END_GROUND) || state.getMaterial().equals(Material.PLANT) - || state.is(EndBlocks.UMBRELLA_TREE_MEMBRANE)) { - return true; - } - return state.getMaterial().isReplaceable(); - }; - } - - private class Center { - final double px; - final double py; - final double pz; - final float radius; - - Center(double x, double y, double z, float radius) { - this.px = x; - this.py = y; - this.pz = z; - this.radius = radius; - } - - double distance(float x, float z) { - return MHelper.length(px - x, pz - z); - } - } -} diff --git a/src/main/java/ru/betterend/world/generator/BetterEndBiomeSource.java b/src/main/java/ru/betterend/world/generator/BetterEndBiomeSource.java deleted file mode 100644 index 602a095b..00000000 --- a/src/main/java/ru/betterend/world/generator/BetterEndBiomeSource.java +++ /dev/null @@ -1,151 +0,0 @@ -package ru.betterend.world.generator; - -import java.util.List; - -import com.google.common.collect.Lists; -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; - -import net.minecraft.core.Registry; -import net.minecraft.resources.RegistryLookupCodec; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.Biomes; -import net.minecraft.world.level.biome.TheEndBiomeSource; -import net.minecraft.world.level.levelgen.WorldgenRandom; -import net.minecraft.world.level.levelgen.synth.SimplexNoise; -import ru.bclib.api.BiomeAPI; -import ru.bclib.world.biomes.BCLBiome; -import ru.bclib.world.generator.BiomeMap; -import ru.betterend.BetterEnd; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBiomes; -import ru.betterend.registry.EndTags; -import ru.betterend.util.FeaturesHelper; -import ru.betterend.world.biome.EndBiome; - -public class BetterEndBiomeSource extends BiomeSource { - public static final Codec CODEC = RecordCodecBuilder.create((instance) -> { - return instance.group(RegistryLookupCodec.create(Registry.BIOME_REGISTRY).forGetter((theEndBiomeSource) -> { - return theEndBiomeSource.biomeRegistry; - }), Codec.LONG.fieldOf("seed").stable().forGetter((theEndBiomeSource) -> { - return theEndBiomeSource.seed; - })).apply(instance, instance.stable(BetterEndBiomeSource::new)); - }); - private static final OpenSimplexNoise SMALL_NOISE = new OpenSimplexNoise(8324); - private final Registry biomeRegistry; - private final SimplexNoise noise; - private final Biome centerBiome; - private final Biome barrens; - private BiomeMap mapLand; - private BiomeMap mapVoid; - private final long seed; - - public BetterEndBiomeSource(Registry biomeRegistry, long seed) { - super(getBiomes(biomeRegistry)); - - this.mapLand = new BiomeMap(seed, GeneratorOptions.getBiomeSizeLand(), EndBiomes.LAND_BIOMES); - this.mapVoid = new BiomeMap(seed, GeneratorOptions.getBiomeSizeVoid(), EndBiomes.VOID_BIOMES); - this.centerBiome = biomeRegistry.getOrThrow(Biomes.THE_END); - this.barrens = biomeRegistry.getOrThrow(Biomes.END_BARRENS); - this.biomeRegistry = biomeRegistry; - this.seed = seed; - - WorldgenRandom chunkRandom = new WorldgenRandom(seed); - chunkRandom.consumeCount(17292); - this.noise = new SimplexNoise(chunkRandom); - - EndBiomes.mutateRegistry(biomeRegistry); - EndTags.addTerrainTags(biomeRegistry); - FeaturesHelper.addFeatures(biomeRegistry); - } - - private static List getBiomes(Registry biomeRegistry) { - List list = Lists.newArrayList(); - biomeRegistry.forEach((biome) -> { - if (EndBiomes.hasBiome(biomeRegistry.getKey(biome))) { - list.add(biome); - } - }); - return list; - } - - @Override - public Biome getNoiseBiome(int biomeX, int biomeY, int biomeZ) { - boolean hasVoid = !GeneratorOptions.useNewGenerator() || !GeneratorOptions.noRingVoid(); - long i = (long) biomeX * (long) biomeX; - long j = (long) biomeZ * (long) biomeZ; - - long dist = i + j; - if (hasVoid) { - if (dist <= 65536L) return this.centerBiome; - } - else if (dist <= 625L) { - dist += noise.getValue(i * 0.2, j * 0.2) * 10; - if (dist <= 625L) { - return this.centerBiome; - } - } - - if (biomeX == 0 && biomeZ == 0) { - mapLand.clearCache(); - mapVoid.clearCache(); - } - - BCLBiome endBiome = null; - if (GeneratorOptions.useNewGenerator()) { - if (TerrainGenerator.isLand(biomeX, biomeZ)) { - endBiome = (EndBiome) mapLand.getBiome(biomeX << 2, biomeZ << 2); - } - else { - if (!GeneratorOptions.noRingVoid() && dist <= 65536L) { - return barrens; - } - endBiome = mapVoid.getBiome(biomeX << 2, biomeZ << 2); - } - } - else { - float height = TheEndBiomeSource.getHeightValue(noise, (biomeX >> 1) + 1, (biomeZ >> 1) + 1) + (float) SMALL_NOISE.eval(biomeX, biomeZ) * 5; - - if (height > -20F && height < -5F) { - return barrens; - } - - endBiome = height < -10F ? mapVoid.getBiome(biomeX << 2, biomeZ << 2) : mapLand.getBiome(biomeX << 2, biomeZ << 2); - } - - return BiomeAPI.getActualBiome(endBiome); - } - - public Biome getLandBiome(int biomeX, int biomeY, int biomeZ) { - boolean hasVoid = !GeneratorOptions.useNewGenerator() || !GeneratorOptions.noRingVoid(); - long i = (long) biomeX * (long) biomeX; - long j = (long) biomeZ * (long) biomeZ; - - long dist = i + j; - if (hasVoid) { - if (dist <= 65536L) return this.centerBiome; - } - else if (dist <= 625L) { - dist += noise.getValue(i * 0.2, j * 0.2) * 10; - if (dist <= 625L) { - return this.centerBiome; - } - } - return BiomeAPI.getActualBiome(mapLand.getBiome(biomeX << 2, biomeZ << 2)); - } - - @Override - public BiomeSource withSeed(long seed) { - return new BetterEndBiomeSource(biomeRegistry, seed); - } - - @Override - protected Codec codec() { - return CODEC; - } - - public static void register() { - Registry.register(Registry.BIOME_SOURCE, BetterEnd.makeID("better_end_biome_source"), CODEC); - } -} diff --git a/src/main/java/ru/betterend/world/generator/BiomeType.java b/src/main/java/ru/betterend/world/generator/BiomeType.java deleted file mode 100644 index d259cf03..00000000 --- a/src/main/java/ru/betterend/world/generator/BiomeType.java +++ /dev/null @@ -1,6 +0,0 @@ -package ru.betterend.world.generator; - -public enum BiomeType { - LAND, - VOID; -} diff --git a/src/main/java/ru/betterend/world/generator/GeneratorOptions.java b/src/main/java/ru/betterend/world/generator/GeneratorOptions.java deleted file mode 100644 index 346dd2a7..00000000 --- a/src/main/java/ru/betterend/world/generator/GeneratorOptions.java +++ /dev/null @@ -1,162 +0,0 @@ -package ru.betterend.world.generator; - -import net.minecraft.core.BlockPos; -import net.minecraft.util.Mth; -import ru.betterend.config.Configs; - -public class GeneratorOptions { - private static int biomeSizeLand; - private static int biomeSizeVoid; - private static int biomeSizeCaves; - private static boolean hasPortal; - private static boolean hasPillars; - private static boolean hasDragonFights; - private static boolean swapOverworldToEnd; - private static boolean changeChorusPlant; - private static boolean removeChorusFromVanillaBiomes; - private static boolean newGenerator; - private static boolean noRingVoid; - private static boolean generateCentralIsland; - private static boolean generateObsidianPlatform; - private static int endCityFailChance; - public static LayerOptions bigOptions; - public static LayerOptions mediumOptions; - public static LayerOptions smallOptions; - private static boolean changeSpawn; - private static BlockPos spawn; - private static BlockPos portal = BlockPos.ZERO; - private static boolean replacePortal; - private static boolean replacePillars; - private static long islandDistBlock; - private static int islandDistChunk; - private static boolean directSpikeHeight; - - public static void init() { - biomeSizeLand = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeLand", 256); - biomeSizeVoid = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeVoid", 256); - biomeSizeCaves = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeCaves", 32); - hasPortal = Configs.GENERATOR_CONFIG.getBoolean("portal", "hasPortal", true); - hasPillars = Configs.GENERATOR_CONFIG.getBoolean("spikes", "hasSpikes", true); - hasDragonFights = Configs.GENERATOR_CONFIG.getBooleanRoot("hasDragonFights", true); - swapOverworldToEnd = Configs.GENERATOR_CONFIG.getBooleanRoot("swapOverworldToEnd", false); - changeChorusPlant = Configs.GENERATOR_CONFIG.getBoolean("chorusPlant", "changeChorusPlant", true); - removeChorusFromVanillaBiomes = Configs.GENERATOR_CONFIG.getBoolean("chorusPlant", "removeChorusFromVanillaBiomes", true); - newGenerator = Configs.GENERATOR_CONFIG.getBoolean("customGenerator", "useNewGenerator", true); - noRingVoid = Configs.GENERATOR_CONFIG.getBoolean("customGenerator", "noRingVoid", false); - generateCentralIsland = Configs.GENERATOR_CONFIG.getBoolean("customGenerator", "generateCentralIsland", true); - endCityFailChance = Configs.GENERATOR_CONFIG.getInt("customGenerator", "endCityFailChance", 5); - generateObsidianPlatform = Configs.GENERATOR_CONFIG.getBooleanRoot("generateObsidianPlatform", true); - bigOptions = new LayerOptions("customGenerator.layers.bigIslands", Configs.GENERATOR_CONFIG, 300, 200, 70, 10, false); - mediumOptions = new LayerOptions("customGenerator.layers.mediumIslands", Configs.GENERATOR_CONFIG, 150, 100, 70, 20, true); - smallOptions = new LayerOptions("customGenerator.layers.smallIslands", Configs.GENERATOR_CONFIG, 60, 50, 70, 30, false); - changeSpawn = Configs.GENERATOR_CONFIG.getBoolean("spawn", "changeSpawn", false); - spawn = new BlockPos( - Configs.GENERATOR_CONFIG.getInt("spawn.point", "x", 20), - Configs.GENERATOR_CONFIG.getInt("spawn.point", "y", 65), - Configs.GENERATOR_CONFIG.getInt("spawn.point", "z", 0) - ); - replacePortal = Configs.GENERATOR_CONFIG.getBoolean("portal", "customEndPortal", true); - replacePillars = Configs.GENERATOR_CONFIG.getBoolean("spikes", "customObsidianSpikes", true); - int circleRadius = Configs.GENERATOR_CONFIG.getInt("customGenerator", "voidRingSize", 1000); - islandDistBlock = (long) circleRadius * (long) circleRadius; - islandDistChunk = (circleRadius >> 3); // Twice bigger than normal - } - - public static int getBiomeSizeLand() { - return Mth.clamp(biomeSizeLand, 1, 8192); - } - - public static int getBiomeSizeVoid() { - return Mth.clamp(biomeSizeVoid, 1, 8192); - } - - public static int getBiomeSizeCaves() { - return Mth.clamp(biomeSizeCaves, 1, 8192); - } - - public static boolean hasPortal() { - return hasPortal; - } - - public static boolean hasPillars() { - return hasPillars; - } - - public static boolean hasDragonFights() { - return hasDragonFights; - } - - public static boolean swapOverworldToEnd() { - return swapOverworldToEnd; - } - - public static boolean changeChorusPlant() { - return changeChorusPlant; - } - - public static boolean removeChorusFromVanillaBiomes() { - return removeChorusFromVanillaBiomes; - } - - public static boolean noRingVoid() { - return noRingVoid; - } - - public static boolean useNewGenerator() { - return newGenerator; - } - - public static boolean hasCentralIsland() { - return generateCentralIsland; - } - - public static boolean generateObsidianPlatform() { - return generateObsidianPlatform; - } - - public static int getEndCityFailChance() { - return endCityFailChance; - } - - public static boolean changeSpawn() { - return changeSpawn; - } - - public static BlockPos getSpawn() { - return spawn; - } - - public static BlockPos getPortalPos() { - return portal; - } - - public static void setPortalPos(BlockPos portal) { - GeneratorOptions.portal = portal; - } - - public static boolean replacePortal() { - return replacePortal; - } - - public static boolean replacePillars() { - return replacePillars; - } - - public static long getIslandDistBlock() { - return islandDistBlock; - } - - public static int getIslandDistChunk() { - return islandDistChunk; - } - - public static void setDirectSpikeHeight() { - directSpikeHeight = true; - } - - public static boolean isDirectSpikeHeight() { - boolean height = directSpikeHeight; - directSpikeHeight = false; - return height; - } -} diff --git a/src/main/java/ru/betterend/world/generator/IslandLayer.java b/src/main/java/ru/betterend/world/generator/IslandLayer.java deleted file mode 100644 index d7858317..00000000 --- a/src/main/java/ru/betterend/world/generator/IslandLayer.java +++ /dev/null @@ -1,188 +0,0 @@ -package ru.betterend.world.generator; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import com.google.common.collect.Maps; - -import net.minecraft.core.BlockPos; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFRadialNoiseMap; -import ru.bclib.sdf.operator.SDFScale; -import ru.bclib.sdf.operator.SDFSmoothUnion; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.primitive.SDFCappedCone; -import ru.bclib.util.MHelper; -import ru.betterend.noise.OpenSimplexNoise; - -public class IslandLayer { - private static final Random RANDOM = new Random(); - private final SDFRadialNoiseMap noise; - private final SDF island; - - private final List positions = new ArrayList(9); - private final Map islands = Maps.newHashMap(); - private final OpenSimplexNoise density; - private final int seed; - private int lastX = Integer.MIN_VALUE; - private int lastZ = Integer.MIN_VALUE; - private final LayerOptions options; - - public IslandLayer(int seed, LayerOptions options) { - this.density = new OpenSimplexNoise(seed); - this.options = options; - this.seed = seed; - - SDF cone1 = makeCone(0, 0.4F, 0.2F, -0.3F); - SDF cone2 = makeCone(0.4F, 0.5F, 0.1F, -0.1F); - SDF cone3 = makeCone(0.5F, 0.45F, 0.03F, 0.0F); - SDF cone4 = makeCone(0.45F, 0, 0.02F, 0.03F); - - SDF coneBottom = new SDFSmoothUnion().setRadius(0.02F).setSourceA(cone1).setSourceB(cone2); - SDF coneTop = new SDFSmoothUnion().setRadius(0.02F).setSourceA(cone3).setSourceB(cone4); - noise = (SDFRadialNoiseMap) new SDFRadialNoiseMap().setSeed(seed).setRadius(0.5F).setIntensity(0.2F).setSource(coneTop); - island = new SDFSmoothUnion().setRadius(0.01F).setSourceA(noise).setSourceB(coneBottom); - } - - private int getSeed(int x, int z) { - int h = seed + x * 374761393 + z * 668265263; - h = (h ^ (h >> 13)) * 1274126177; - return h ^ (h >> 16); - } - - public void updatePositions(double x, double z) { - int ix = MHelper.floor(x / options.distance); - int iz = MHelper.floor(z / options.distance); - - if (lastX != ix || lastZ != iz) { - lastX = ix; - lastZ = iz; - positions.clear(); - for (int pox = -1; pox < 2; pox++) { - int px = pox + ix; - long px2 = px; - for (int poz = -1; poz < 2; poz++) { - int pz = poz + iz; - long pz2 = pz; - if (GeneratorOptions.noRingVoid() || px2 * px2 + pz2 * pz2 > options.centerDist) { - RANDOM.setSeed(getSeed(px, pz)); - double posX = (px + RANDOM.nextFloat()) * options.distance; - double posY = MHelper.randRange(options.minY, options.maxY, RANDOM); - double posZ = (pz + RANDOM.nextFloat()) * options.distance; - if (density.eval(posX * 0.01, posZ * 0.01) > options.coverage) { - positions.add(new BlockPos(posX, posY, posZ)); - } - } - } - } - } - - if (GeneratorOptions.hasCentralIsland() && Math.abs(ix) < GeneratorOptions.getIslandDistChunk() && Math.abs(iz) < GeneratorOptions.getIslandDistChunk()) { - int count = positions.size(); - for (int n = 0; n < count; n++) { - BlockPos pos = positions.get(n); - long d = (long) pos.getX() * (long) pos.getX() + (long) pos.getZ() * (long) pos.getZ(); - if (d < GeneratorOptions.getIslandDistBlock()) { - positions.remove(n); - count--; - n--; - } - } - if (options.hasCentralIsland) { - positions.add(new BlockPos(0, 64, 0)); - } - } - } - - private SDF getIsland(BlockPos pos) { - SDF island = islands.get(pos); - if (island == null) { - if (pos.getX() == 0 && pos.getZ() == 0) { - island = new SDFScale().setScale(1.3F).setSource(this.island); - } - else { - RANDOM.setSeed(getSeed(pos.getX(), pos.getZ())); - island = new SDFScale().setScale(RANDOM.nextFloat() + 0.5F).setSource(this.island); - } - islands.put(pos, island); - } - noise.setOffset(pos.getX(), pos.getZ()); - return island; - } - - private float getRelativeDistance(SDF sdf, BlockPos center, double px, double py, double pz) { - float x = (float) (px - center.getX()) / options.scale; - float y = (float) (py - center.getY()) / options.scale; - float z = (float) (pz - center.getZ()) / options.scale; - return sdf.getDistance(x, y, z); - } - - private float calculateSDF(double x, double y, double z) { - float distance = 10; - for (BlockPos pos: positions) { - SDF island = getIsland(pos); - float dist = getRelativeDistance(island, pos, x, y, z); - distance = MHelper.min(distance, dist); - } - return distance; - } - - public float getDensity(double x, double y, double z) { - return -calculateSDF(x, y, z); - } - - public float getDensity(double x, double y, double z, float height) { - noise.setIntensity(height); - noise.setRadius(0.5F / (1 + height)); - return -calculateSDF(x, y, z); - } - - public void clearCache() { - if (islands.size() > 128) { - islands.clear(); - } - } - - private static SDF makeCone(float radiusBottom, float radiusTop, float height, float minY) { - float hh = height * 0.5F; - SDF sdf = new SDFCappedCone().setHeight(hh).setRadius1(radiusBottom).setRadius2(radiusTop); - return new SDFTranslate().setTranslate(0, minY + hh, 0).setSource(sdf); - } - - /*private static NativeImage loadMap(String path) { - InputStream stream = IslandLayer.class.getResourceAsStream(path); - if (stream != null) { - try { - NativeImage map = NativeImage.read(stream); - stream.close(); - return map; - } - catch (IOException e) { - BetterEnd.LOGGER.warning(e.getMessage()); - } - } - return null; - }*/ - - /*static { - NativeImage map = loadMap("/assets/" + BetterEnd.MOD_ID + "/textures/heightmaps/mountain_1.png"); - - SDF cone1 = makeCone(0, 0.4F, 0.2F, -0.3F); - SDF cone2 = makeCone(0.4F, 0.5F, 0.1F, -0.1F); - SDF cone3 = makeCone(0.5F, 0.45F, 0.03F, 0.0F); - SDF cone4 = makeCone(0.45F, 0, 0.02F, 0.03F); - - SDF coneBottom = new SDFSmoothUnion().setRadius(0.02F).setSourceA(cone1).setSourceB(cone2); - SDF coneTop = new SDFSmoothUnion().setRadius(0.02F).setSourceA(cone3).setSourceB(cone4); - - SDF map1 = new SDFHeightmap().setMap(map).setIntensity(0.3F).setSource(coneTop); - NOISE = (SDFRadialNoiseMap) new SDFRadialNoiseMap().setSource(coneTop); - - ISLAND = new SDF[] { - new SDFSmoothUnion().setRadius(0.01F).setSourceA(coneTop).setSourceB(coneBottom), - new SDFSmoothUnion().setRadius(0.01F).setSourceA(map1).setSourceB(coneBottom) - }; - }*/ -} diff --git a/src/main/java/ru/betterend/world/generator/LayerOptions.java b/src/main/java/ru/betterend/world/generator/LayerOptions.java deleted file mode 100644 index 03c6ecab..00000000 --- a/src/main/java/ru/betterend/world/generator/LayerOptions.java +++ /dev/null @@ -1,48 +0,0 @@ -package ru.betterend.world.generator; - -import net.minecraft.util.Mth; -import ru.bclib.config.PathConfig; - -public class LayerOptions { - public final float distance; - public final float scale; - public final float coverage; - public final int center; - public final int heightVariation; - public final int minY; - public final int maxY; - public final long centerDist; - public final boolean hasCentralIsland; - - public LayerOptions(String name, PathConfig config, float distance, float scale, int center, int heightVariation, boolean hasCentral) { - this.distance = clampDistance(config.getFloat(name, "distance[1-8192]", distance)); - this.scale = clampScale(config.getFloat(name, "scale[0.1-1024]", scale)); - this.center = clampCenter(config.getInt(name, "averageHeight[0-255]", center)); - this.heightVariation = clampVariation(config.getInt(name, "heightVariation[0-255]", heightVariation)); - this.coverage = clampCoverage(config.getFloat(name, "coverage[0-1]", 0.5F)); - this.minY = this.center - this.heightVariation; - this.maxY = this.center + this.heightVariation; - this.centerDist = Mth.floor(1000 / this.distance); - this.hasCentralIsland = config.getBoolean(name, "hasCentralIsland", hasCentral); - } - - private float clampDistance(float value) { - return Mth.clamp(value, 1, 8192); - } - - private float clampScale(float value) { - return Mth.clamp(value, 0.1F, 1024); - } - - private float clampCoverage(float value) { - return 0.9999F - Mth.clamp(value, 0, 1) * 2; - } - - private int clampCenter(int value) { - return Mth.clamp(value, 0, 255); - } - - private int clampVariation(int value) { - return Mth.clamp(value, 0, 255); - } -} diff --git a/src/main/java/ru/betterend/world/generator/TerrainGenerator.java b/src/main/java/ru/betterend/world/generator/TerrainGenerator.java deleted file mode 100644 index 1214b56b..00000000 --- a/src/main/java/ru/betterend/world/generator/TerrainGenerator.java +++ /dev/null @@ -1,196 +0,0 @@ -package ru.betterend.world.generator; - -import java.awt.Point; -import java.util.List; -import java.util.Random; -import java.util.concurrent.locks.ReentrantLock; - -import com.google.common.collect.Lists; - -import net.minecraft.util.Mth; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import ru.bclib.util.MHelper; -import ru.betterend.noise.OpenSimplexNoise; - -public class TerrainGenerator { - private static final ReentrantLock LOCKER = new ReentrantLock(); - private static final double SCALE_XZ = 8.0; - private static final double SCALE_Y = 4.0; - private static final float[] COEF; - private static final Point[] OFFS; - - private static IslandLayer largeIslands; - private static IslandLayer mediumIslands; - private static IslandLayer smallIslands; - private static OpenSimplexNoise noise1; - private static OpenSimplexNoise noise2; - - /*public static boolean canGenerate(int x, int z) { - return GeneratorOptions.noRingVoid() || (long) x + (long) z > CENTER; - }*/ - - public static void initNoise(long seed) { - Random random = new Random(seed); - largeIslands = new IslandLayer(random.nextInt(), GeneratorOptions.bigOptions); - mediumIslands = new IslandLayer(random.nextInt(), GeneratorOptions.mediumOptions); - smallIslands = new IslandLayer(random.nextInt(), GeneratorOptions.smallOptions); - noise1 = new OpenSimplexNoise(random.nextInt()); - noise2 = new OpenSimplexNoise(random.nextInt()); - } - - public static void fillTerrainDensity(double[] buffer, int x, int z, BiomeSource biomeSource) { - LOCKER.lock(); - - largeIslands.clearCache(); - mediumIslands.clearCache(); - smallIslands.clearCache(); - - double distortion1 = noise1.eval(x * 0.1, z * 0.1) * 20 + noise2.eval(x * 0.2, z * 0.2) * 10 + noise1.eval(x * 0.4, z * 0.4) * 5; - double distortion2 = noise2.eval(x * 0.1, z * 0.1) * 20 + noise1.eval(x * 0.2, z * 0.2) * 10 + noise2.eval(x * 0.4, z * 0.4) * 5; - double px = (double) x * SCALE_XZ + distortion1; - double pz = (double) z * SCALE_XZ + distortion2; - - largeIslands.updatePositions(px, pz); - mediumIslands.updatePositions(px, pz); - smallIslands.updatePositions(px, pz); - - float height = getAverageDepth(biomeSource, x << 1, z << 1) * 0.5F; - - for (int y = 0; y < buffer.length; y++) { - double py = (double) y * SCALE_Y; - float dist = largeIslands.getDensity(px, py, pz, height); - dist = dist > 1 ? dist : MHelper.max(dist, mediumIslands.getDensity(px, py, pz, height)); - dist = dist > 1 ? dist : MHelper.max(dist, smallIslands.getDensity(px, py, pz, height)); - if (dist > -0.5F) { - dist += noise1.eval(px * 0.01, py * 0.01, pz * 0.01) * 0.02 + 0.02; - dist += noise2.eval(px * 0.05, py * 0.05, pz * 0.05) * 0.01 + 0.01; - dist += noise1.eval(px * 0.1, py * 0.1, pz * 0.1) * 0.005 + 0.005; - } - buffer[y] = dist; - } - - LOCKER.unlock(); - } - - private static float getAverageDepth(BiomeSource biomeSource, int x, int z) { - if (getBiome(biomeSource, x, z).getDepth() < 0.1F) { - return 0F; - } - float depth = 0F; - for (int i = 0; i < OFFS.length; i++) { - int px = x + OFFS[i].x; - int pz = z + OFFS[i].y; - depth += getBiome(biomeSource, px, pz).getDepth() * COEF[i]; - } - return depth; - } - - private static Biome getBiome(BiomeSource biomeSource, int x, int z) { - if (biomeSource instanceof BetterEndBiomeSource) { - return ((BetterEndBiomeSource) biomeSource).getLandBiome(x, 0, z); - } - return biomeSource.getNoiseBiome(x, 0, z); - } - - /** - * Check if this is land - * @param x - biome pos x - * @param z - biome pos z - */ - public static boolean isLand(int x, int z) { - LOCKER.lock(); - - double px = (x >> 1) + 0.5; - double pz = (z >> 1) + 0.5; - - double distortion1 = noise1.eval(px * 0.1, pz * 0.1) * 20 + noise2.eval(px * 0.2, pz * 0.2) * 10 + noise1.eval(px * 0.4, pz * 0.4) * 5; - double distortion2 = noise2.eval(px * 0.1, pz * 0.1) * 20 + noise1.eval(px * 0.2, pz * 0.2) * 10 + noise2.eval(px * 0.4, pz * 0.4) * 5; - px = px * SCALE_XZ + distortion1; - pz = pz * SCALE_XZ + distortion2; - - largeIslands.updatePositions(px, pz); - mediumIslands.updatePositions(px, pz); - smallIslands.updatePositions(px, pz); - - for (int y = 0; y < 32; y++) { - double py = (double) y * SCALE_Y; - float dist = largeIslands.getDensity(px, py, pz); - dist = dist > 1 ? dist : MHelper.max(dist, mediumIslands.getDensity(px, py, pz)); - dist = dist > 1 ? dist : MHelper.max(dist, smallIslands.getDensity(px, py, pz)); - if (dist > -0.5F) { - dist += noise1.eval(px * 0.01, py * 0.01, pz * 0.01) * 0.02 + 0.02; - dist += noise2.eval(px * 0.05, py * 0.05, pz * 0.05) * 0.01 + 0.01; - dist += noise1.eval(px * 0.1, py * 0.1, pz * 0.1) * 0.005 + 0.005; - } - if (dist > -0.01) { - LOCKER.unlock(); - return true; - } - } - - LOCKER.unlock(); - return false; - } - - /** - * Get something like height - * @param x - block pos x - * @param z - block pos z - */ - public static int getHeight(int x, int z) { - LOCKER.lock(); - - double px = (double) x / 8.0; - double pz = (double) z / 8.0; - - double distortion1 = noise1.eval(px * 0.1, pz * 0.1) * 20 + noise2.eval(px * 0.2, pz * 0.2) * 10 + noise1.eval(px * 0.4, pz * 0.4) * 5; - double distortion2 = noise2.eval(px * 0.1, pz * 0.1) * 20 + noise1.eval(px * 0.2, pz * 0.2) * 10 + noise2.eval(px * 0.4, pz * 0.4) * 5; - px = (double) x * SCALE_XZ + distortion1; - pz = (double) z * SCALE_XZ + distortion2; - - largeIslands.updatePositions(px, pz); - mediumIslands.updatePositions(px, pz); - smallIslands.updatePositions(px, pz); - - for (int y = 32; y >= 0; y--) { - double py = (double) y * SCALE_Y; - float dist = largeIslands.getDensity(px, py, pz); - dist = dist > 1 ? dist : MHelper.max(dist, mediumIslands.getDensity(px, py, pz)); - dist = dist > 1 ? dist : MHelper.max(dist, smallIslands.getDensity(px, py, pz)); - if (dist > -0.5F) { - dist += noise1.eval(px * 0.01, py * 0.01, pz * 0.01) * 0.02 + 0.02; - dist += noise2.eval(px * 0.05, py * 0.05, pz * 0.05) * 0.01 + 0.01; - dist += noise1.eval(px * 0.1, py * 0.1, pz * 0.1) * 0.005 + 0.005; - } - if (dist > 0) { - LOCKER.unlock(); - return Mth.floor(Mth.clamp(y + dist, y, y + 1) * SCALE_Y); - } - } - - LOCKER.unlock(); - return 0; - } - - static { - float sum = 0; - List coef = Lists.newArrayList(); - List pos = Lists.newArrayList(); - for (int x = -3; x <= 3; x++) { - for (int z = -3; z <= 3; z++) { - float dist = MHelper.length(x, z) / 3F; - if (dist <= 1) { - sum += dist; - coef.add(dist); - pos.add(new Point(x, z)); - } - } - } - OFFS = pos.toArray(new Point[] {}); - COEF = new float[coef.size()]; - for (int i = 0; i < COEF.length; i++) { - COEF[i] = coef.get(i) / sum; - } - } -} diff --git a/src/main/java/ru/betterend/world/structures/EndStructureFeature.java b/src/main/java/ru/betterend/world/structures/EndStructureFeature.java deleted file mode 100644 index 396fc2a1..00000000 --- a/src/main/java/ru/betterend/world/structures/EndStructureFeature.java +++ /dev/null @@ -1,45 +0,0 @@ -package ru.betterend.world.structures; - -import java.util.Random; - -import net.fabricmc.fabric.api.structure.v1.FabricStructureBuilder; -import net.minecraft.data.BuiltinRegistries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.levelgen.GenerationStep; -import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.betterend.BetterEnd; - -public class EndStructureFeature { - private static final Random RANDOM = new Random(354); - private final StructureFeature structure; - private final ConfiguredStructureFeature featureConfigured; - private final GenerationStep.Decoration featureStep; - - public EndStructureFeature(String name, StructureFeature structure, GenerationStep.Decoration step, int spacing, int separation) { - ResourceLocation id = BetterEnd.makeID(name); - - this.featureStep = step; - this.structure = FabricStructureBuilder.create(id, structure) - .step(step) - .defaultConfig(spacing, separation, RANDOM.nextInt(8192)) - .register(); - - this.featureConfigured = this.structure.configured(NoneFeatureConfiguration.NONE); - - BuiltinRegistries.register(BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE, id, this.featureConfigured); - } - - public StructureFeature getStructure() { - return structure; - } - - public ConfiguredStructureFeature getFeatureConfigured() { - return featureConfigured; - } - - public GenerationStep.Decoration getFeatureStep() { - return featureStep; - } -} diff --git a/src/main/java/ru/betterend/world/structures/features/EternalPortalStructure.java b/src/main/java/ru/betterend/world/structures/features/EternalPortalStructure.java deleted file mode 100644 index f67a71d4..00000000 --- a/src/main/java/ru/betterend/world/structures/features/EternalPortalStructure.java +++ /dev/null @@ -1,62 +0,0 @@ -package ru.betterend.world.structures.features; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.RegistryAccess; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.WorldgenRandom; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.StructureStart; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; -import ru.bclib.util.MHelper; -import ru.bclib.util.StructureHelper; -import ru.betterend.BetterEnd; -import ru.betterend.world.structures.piece.NBTPiece; - -public class EternalPortalStructure extends FeatureBaseStructure { - private static final ResourceLocation STRUCTURE_ID = BetterEnd.makeID("portal/eternal_portal"); - private static final StructureTemplate STRUCTURE = StructureHelper.readStructure(STRUCTURE_ID); - - @Override - protected boolean isFeatureChunk(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long worldSeed, WorldgenRandom chunkRandom, int chunkX, int chunkZ, Biome biome, ChunkPos chunkPos, NoneFeatureConfiguration featureConfig) { - long x = (long) chunkPos.x * (long) chunkPos.x; - long z = (long) chunkPos.z * (long) chunkPos.z; - if (x + z < 1024L) { - return false; - } - if (chunkGenerator.getBaseHeight((chunkX << 4) | 8, (chunkZ << 4) | 8, Heightmap.Types.WORLD_SURFACE_WG) < 10) { - return false; - } - return super.isFeatureChunk(chunkGenerator, biomeSource, worldSeed, chunkRandom, chunkX, chunkZ, biome, chunkPos, featureConfig); - } - - @Override - public StructureFeature.StructureStartFactory getStartFactory() { - return PortalStructureStart::new; - } - - public static class PortalStructureStart extends StructureStart { - public PortalStructureStart(StructureFeature feature, int chunkX, int chunkZ, BoundingBox box, int references, long seed) { - super(feature, chunkX, chunkZ, box, references, seed); - } - - @Override - public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager manager, int chunkX, int chunkZ, Biome biome, NoneFeatureConfiguration config) { - int x = (chunkX << 4) | MHelper.randRange(4, 12, random); - int z = (chunkZ << 4) | MHelper.randRange(4, 12, random); - int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG); - if (y > 4) { - this.pieces.add(new NBTPiece(STRUCTURE_ID, STRUCTURE, new BlockPos(x, y - 4, z), random.nextInt(5), true, random)); - } - this.calculateBoundingBox(); - } - } -} diff --git a/src/main/java/ru/betterend/world/structures/features/FeatureBaseStructure.java b/src/main/java/ru/betterend/world/structures/features/FeatureBaseStructure.java deleted file mode 100644 index 219ec6f5..00000000 --- a/src/main/java/ru/betterend/world/structures/features/FeatureBaseStructure.java +++ /dev/null @@ -1,51 +0,0 @@ -package ru.betterend.world.structures.features; - -import java.util.Random; - -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.WorldgenRandom; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; - -public abstract class FeatureBaseStructure extends StructureFeature { - protected static final BlockState AIR = Blocks.AIR.defaultBlockState(); - - public FeatureBaseStructure() { - super(NoneFeatureConfiguration.CODEC); - } - - @Override - protected boolean isFeatureChunk(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long worldSeed, WorldgenRandom chunkRandom, int chunkX, int chunkZ, Biome biome, ChunkPos chunkPos, NoneFeatureConfiguration featureConfig) { - return getGenerationHeight(chunkX, chunkZ, chunkGenerator) >= 20; - } - - private static int getGenerationHeight(int chunkX, int chunkZ, ChunkGenerator chunkGenerator) { - Random random = new Random((long) (chunkX + chunkZ * 10387313)); - Rotation blockRotation = Rotation.getRandom(random); - int i = 5; - int j = 5; - if (blockRotation == Rotation.CLOCKWISE_90) { - i = -5; - } else if (blockRotation == Rotation.CLOCKWISE_180) { - i = -5; - j = -5; - } else if (blockRotation == Rotation.COUNTERCLOCKWISE_90) { - j = -5; - } - - int k = (chunkX << 4) + 7; - int l = (chunkZ << 4) + 7; - int m = chunkGenerator.getFirstOccupiedHeight(k, l, Heightmap.Types.WORLD_SURFACE_WG); - int n = chunkGenerator.getFirstOccupiedHeight(k, l + j, Heightmap.Types.WORLD_SURFACE_WG); - int o = chunkGenerator.getFirstOccupiedHeight(k + i, l, Heightmap.Types.WORLD_SURFACE_WG); - int p = chunkGenerator.getFirstOccupiedHeight(k + i, l + j, Heightmap.Types.WORLD_SURFACE_WG); - return Math.min(Math.min(m, n), Math.min(o, p)); - } -} diff --git a/src/main/java/ru/betterend/world/structures/features/GiantIceStarStructure.java b/src/main/java/ru/betterend/world/structures/features/GiantIceStarStructure.java deleted file mode 100644 index b60dac4a..00000000 --- a/src/main/java/ru/betterend/world/structures/features/GiantIceStarStructure.java +++ /dev/null @@ -1,120 +0,0 @@ -package ru.betterend.world.structures.features; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.RegistryAccess; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.StructureStart; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFRotation; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.operator.SDFUnion; -import ru.bclib.sdf.primitive.SDFCappedCone; -import ru.bclib.util.MHelper; -import ru.betterend.registry.EndBlocks; -import ru.betterend.world.structures.piece.VoxelPiece; - -public class GiantIceStarStructure extends SDFStructureFeature { - private final float minSize = 20; - private final float maxSize = 35; - private final int minCount = 25; - private final int maxCount = 40; - - @Override - protected SDF getSDF(BlockPos pos, Random random) { - float size = MHelper.randRange(minSize, maxSize, random); - int count = MHelper.randRange(minCount, maxCount, random); - List points = getFibonacciPoints(count); - SDF sdf = null; - SDF spike = new SDFCappedCone().setRadius1(3 + (size - 5) * 0.2F).setRadius2(0).setHeight(size).setBlock(EndBlocks.DENSE_SNOW); - spike = new SDFTranslate().setTranslate(0, size - 0.5F, 0).setSource(spike); - for (Vector3f point: points) { - SDF rotated = spike; - point = MHelper.normalize(point); - float angle = MHelper.angle(Vector3f.YP, point); - if (angle > 0.01F && angle < 3.14F) { - Vector3f axis = MHelper.normalize(MHelper.cross(Vector3f.YP, point)); - rotated = new SDFRotation().setRotation(axis, angle).setSource(spike); - } - else if (angle > 1) { - rotated = new SDFRotation().setRotation(Vector3f.YP, (float) Math.PI).setSource(spike); - } - sdf = (sdf == null) ? rotated : new SDFUnion().setSourceA(sdf).setSourceB(rotated); - } - - final float ancientRadius = size * 0.7F; - final float denseRadius = size * 0.9F; - final float iceRadius = size < 7 ? size * 5 : size * 1.3F; - final float randScale = size * 0.3F; - - final BlockPos center = pos; - final BlockState ice = EndBlocks.EMERALD_ICE.defaultBlockState(); - final BlockState dense = EndBlocks.DENSE_EMERALD_ICE.defaultBlockState(); - final BlockState ancient = EndBlocks.ANCIENT_EMERALD_ICE.defaultBlockState(); - final SDF sdfCopy = sdf; - - return sdf.addPostProcess((info) -> { - BlockPos bpos = info.getPos(); - float px = bpos.getX() - center.getX(); - float py = bpos.getY() - center.getY(); - float pz = bpos.getZ() - center.getZ(); - float distance = MHelper.length(px, py, pz) + sdfCopy.getDistance(px, py, pz) * 0.4F + random.nextFloat() * randScale; - if (distance < ancientRadius) { - return ancient; - } - else if (distance < denseRadius) { - return dense; - } - else if (distance < iceRadius) { - return ice; - } - return info.getState(); - }); - } - - private List getFibonacciPoints(int count) { - float max = count - 1; - List result = new ArrayList(count); - for (int i = 0; i < count; i++) { - float y = 1F - (i / max) * 2F; - float radius = (float) Math.sqrt(1F - y * y); - float theta = MHelper.PHI * i; - float x = (float) Math.cos(theta) * radius; - float z = (float) Math.sin(theta) * radius; - result.add(new Vector3f(x, y, z)); - } - return result; - } - - @Override - public StructureFeature.StructureStartFactory getStartFactory() { - return StarStructureStart::new; - } - - public static class StarStructureStart extends StructureStart { - public StarStructureStart(StructureFeature feature, int chunkX, int chunkZ, BoundingBox box, int references, long seed) { - super(feature, chunkX, chunkZ, box, references, seed); - } - - @Override - public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager manager, int chunkX, int chunkZ, Biome biome, NoneFeatureConfiguration config) { - int x = (chunkX << 4) | MHelper.randRange(4, 12, random); - int z = (chunkZ << 4) | MHelper.randRange(4, 12, random); - BlockPos start = new BlockPos(x, MHelper.randRange(32, 128, random), z); - VoxelPiece piece = new VoxelPiece((world) -> { ((SDFStructureFeature) this.getFeature()).getSDF(start, this.random).fillRecursive(world, start); }, random.nextInt()); - this.pieces.add(piece); - this.calculateBoundingBox(); - } - } -} diff --git a/src/main/java/ru/betterend/world/structures/features/GiantMossyGlowshroomStructure.java b/src/main/java/ru/betterend/world/structures/features/GiantMossyGlowshroomStructure.java deleted file mode 100644 index e24626db..00000000 --- a/src/main/java/ru/betterend/world/structures/features/GiantMossyGlowshroomStructure.java +++ /dev/null @@ -1,126 +0,0 @@ -package ru.betterend.world.structures.features; - -import java.util.List; -import java.util.Random; - -import com.mojang.math.Vector3f; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import ru.bclib.sdf.SDF; -import ru.bclib.sdf.operator.SDFBinary; -import ru.bclib.sdf.operator.SDFCoordModify; -import ru.bclib.sdf.operator.SDFFlatWave; -import ru.bclib.sdf.operator.SDFRound; -import ru.bclib.sdf.operator.SDFScale; -import ru.bclib.sdf.operator.SDFScale3D; -import ru.bclib.sdf.operator.SDFSmoothUnion; -import ru.bclib.sdf.operator.SDFSubtraction; -import ru.bclib.sdf.operator.SDFTranslate; -import ru.bclib.sdf.operator.SDFUnion; -import ru.bclib.sdf.primitive.SDFCappedCone; -import ru.bclib.sdf.primitive.SDFPrimitive; -import ru.bclib.sdf.primitive.SDFSphere; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.bclib.util.SplineHelper; -import ru.betterend.blocks.MossyGlowshroomCapBlock; -import ru.betterend.blocks.basis.FurBlock; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; - -public class GiantMossyGlowshroomStructure extends SDFStructureFeature { - @Override - protected SDF getSDF(BlockPos center, Random random) { - SDFCappedCone cone1 = new SDFCappedCone().setHeight(2.5F).setRadius1(1.5F).setRadius2(2.5F); - SDFCappedCone cone2 = new SDFCappedCone().setHeight(3F).setRadius1(2.5F).setRadius2(13F); - SDF posedCone2 = new SDFTranslate().setTranslate(0, 5, 0).setSource(cone2); - SDF posedCone3 = new SDFTranslate().setTranslate(0, 12F, 0).setSource(new SDFScale().setScale(2).setSource(cone2)); - SDF upCone = new SDFSubtraction().setSourceA(posedCone2).setSourceB(posedCone3); - SDF wave = new SDFFlatWave().setRaysCount(12).setIntensity(1.3F).setSource(upCone); - SDF cones = new SDFSmoothUnion().setRadius(3).setSourceA(cone1).setSourceB(wave); - - SDF innerCone = new SDFTranslate().setTranslate(0, 1.25F, 0).setSource(upCone); - innerCone = new SDFScale3D().setScale(1.2F, 1F, 1.2F).setSource(innerCone); - cones = new SDFUnion().setSourceA(cones).setSourceB(innerCone); - - SDF glowCone = new SDFCappedCone().setHeight(3F).setRadius1(2F).setRadius2(12.5F); - SDFPrimitive priGlowCone = (SDFPrimitive) glowCone; - glowCone = new SDFTranslate().setTranslate(0, 4.25F, 0).setSource(glowCone); - glowCone = new SDFSubtraction().setSourceA(glowCone).setSourceB(posedCone3); - - cones = new SDFUnion().setSourceA(cones).setSourceB(glowCone); - - OpenSimplexNoise noise = new OpenSimplexNoise(1234); - cones = new SDFCoordModify().setFunction((pos) -> { - float dist = MHelper.length(pos.x(), pos.z()); - float y = pos.y() + (float) noise.eval(pos.x() * 0.1 + center.getX(), pos.z() * 0.1 + center.getZ()) * dist * 0.3F - dist * 0.15F; - pos.set(pos.x(), y, pos.z()); - }).setSource(cones); - - SDFTranslate HEAD_POS = (SDFTranslate) new SDFTranslate().setSource(new SDFTranslate().setTranslate(0, 2.5F, 0).setSource(cones)); - - SDF roots = new SDFSphere().setRadius(4F); - SDFPrimitive primRoots = (SDFPrimitive) roots; - roots = new SDFScale3D().setScale(1, 0.7F, 1).setSource(roots); - SDFFlatWave rotRoots = (SDFFlatWave) new SDFFlatWave().setRaysCount(5).setIntensity(1.5F).setSource(roots); - - SDFBinary function = new SDFSmoothUnion().setRadius(4).setSourceB(new SDFUnion().setSourceA(HEAD_POS).setSourceB(rotRoots)); - - cone1.setBlock(EndBlocks.MOSSY_GLOWSHROOM_CAP); - cone2.setBlock(EndBlocks.MOSSY_GLOWSHROOM_CAP); - priGlowCone.setBlock(EndBlocks.MOSSY_GLOWSHROOM_HYMENOPHORE); - primRoots.setBlock(EndBlocks.MOSSY_GLOWSHROOM.bark); - - float height = MHelper.randRange(10F, 25F, random); - int count = MHelper.floor(height / 4); - List spline = SplineHelper.makeSpline(0, 0, 0, 0, height, 0, count); - SplineHelper.offsetParts(spline, random, 1F, 0, 1F); - SDF sdf = SplineHelper.buildSDF(spline, 2.1F, 1.5F, (pos) -> { - return EndBlocks.MOSSY_GLOWSHROOM.log.defaultBlockState(); - }); - Vector3f pos = spline.get(spline.size() - 1); - float scale = MHelper.randRange(2F, 3.5F, random); - - HEAD_POS.setTranslate(pos.x(), pos.y(), pos.z()); - rotRoots.setAngle(random.nextFloat() * MHelper.PI2); - function.setSourceA(sdf); - - return new SDFRound().setRadius(1.5F).setSource(new SDFScale() - .setScale(scale) - .setSource(function)) - .addPostProcess((info) -> { - if (EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getState())) { - if (random.nextBoolean() && info.getStateUp().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_CAP) { - info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.defaultBlockState().setValue(MossyGlowshroomCapBlock.TRANSITION, true)); - return info.getState(); - } - else if (!EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getStateUp()) || !EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown())) { - info.setState(EndBlocks.MOSSY_GLOWSHROOM.bark.defaultBlockState()); - return info.getState(); - } - } - else if (info.getState().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_CAP) { - if (EndBlocks.MOSSY_GLOWSHROOM.isTreeLog(info.getStateDown().getBlock())) { - info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.defaultBlockState().setValue(MossyGlowshroomCapBlock.TRANSITION, true)); - return info.getState(); - } - - info.setState(EndBlocks.MOSSY_GLOWSHROOM_CAP.defaultBlockState()); - return info.getState(); - } - else if (info.getState().getBlock() == EndBlocks.MOSSY_GLOWSHROOM_HYMENOPHORE) { - for (Direction dir: BlocksHelper.HORIZONTAL) { - if (info.getState(dir) == AIR) { - info.setBlockPos(info.getPos().relative(dir), EndBlocks.MOSSY_GLOWSHROOM_FUR.defaultBlockState().setValue(FurBlock.FACING, dir)); - } - } - - if (info.getStateDown().getBlock() != EndBlocks.MOSSY_GLOWSHROOM_HYMENOPHORE) { - info.setBlockPos(info.getPos().below(), EndBlocks.MOSSY_GLOWSHROOM_FUR.defaultBlockState().setValue(FurBlock.FACING, Direction.DOWN)); - } - } - return info.getState(); - }); - } -} diff --git a/src/main/java/ru/betterend/world/structures/features/MegaLakeSmallStructure.java b/src/main/java/ru/betterend/world/structures/features/MegaLakeSmallStructure.java deleted file mode 100644 index d4397767..00000000 --- a/src/main/java/ru/betterend/world/structures/features/MegaLakeSmallStructure.java +++ /dev/null @@ -1,41 +0,0 @@ -package ru.betterend.world.structures.features; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.RegistryAccess; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.StructureStart; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import ru.bclib.util.MHelper; -import ru.betterend.world.structures.piece.LakePiece; - -public class MegaLakeSmallStructure extends FeatureBaseStructure { - @Override - public StructureFeature.StructureStartFactory getStartFactory() { - return SDFStructureStart::new; - } - - public static class SDFStructureStart extends StructureStart { - public SDFStructureStart(StructureFeature feature, int chunkX, int chunkZ, BoundingBox box, int references, long seed) { - super(feature, chunkX, chunkZ, box, references, seed); - } - - @Override - public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager manager, int chunkX, int chunkZ, Biome biome, NoneFeatureConfiguration config) { - int x = (chunkX << 4) | MHelper.randRange(4, 12, random); - int z = (chunkZ << 4) | MHelper.randRange(4, 12, random); - int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG); - if (y > 5) { - float radius = MHelper.randRange(20, 40, random); - float depth = MHelper.randRange(5, 10, random); - LakePiece piece = new LakePiece(new BlockPos(x, y, z), radius, depth, random, biome); - this.pieces.add(piece); - } - this.calculateBoundingBox(); - } - } -} diff --git a/src/main/java/ru/betterend/world/structures/features/MegaLakeStructure.java b/src/main/java/ru/betterend/world/structures/features/MegaLakeStructure.java deleted file mode 100644 index 2d554d4c..00000000 --- a/src/main/java/ru/betterend/world/structures/features/MegaLakeStructure.java +++ /dev/null @@ -1,41 +0,0 @@ -package ru.betterend.world.structures.features; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.RegistryAccess; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.StructureStart; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import ru.bclib.util.MHelper; -import ru.betterend.world.structures.piece.LakePiece; - -public class MegaLakeStructure extends FeatureBaseStructure { - @Override - public StructureFeature.StructureStartFactory getStartFactory() { - return SDFStructureStart::new; - } - - public static class SDFStructureStart extends StructureStart { - public SDFStructureStart(StructureFeature feature, int chunkX, int chunkZ, BoundingBox box, int references, long seed) { - super(feature, chunkX, chunkZ, box, references, seed); - } - - @Override - public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager manager, int chunkX, int chunkZ, Biome biome, NoneFeatureConfiguration config) { - int x = (chunkX << 4) | MHelper.randRange(4, 12, random); - int z = (chunkZ << 4) | MHelper.randRange(4, 12, random); - int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG); - if (y > 5) { - float radius = MHelper.randRange(32, 64, random); - float depth = MHelper.randRange(7, 15, random); - LakePiece piece = new LakePiece(new BlockPos(x, y, z), radius, depth, random, biome); - this.pieces.add(piece); - } - this.calculateBoundingBox(); - } - } -} diff --git a/src/main/java/ru/betterend/world/structures/features/MountainStructure.java b/src/main/java/ru/betterend/world/structures/features/MountainStructure.java deleted file mode 100644 index a968c7d1..00000000 --- a/src/main/java/ru/betterend/world/structures/features/MountainStructure.java +++ /dev/null @@ -1,41 +0,0 @@ -package ru.betterend.world.structures.features; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.RegistryAccess; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.StructureStart; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import ru.bclib.util.MHelper; -import ru.betterend.world.structures.piece.CrystalMountainPiece; - -public class MountainStructure extends FeatureBaseStructure { - @Override - public StructureFeature.StructureStartFactory getStartFactory() { - return SDFStructureStart::new; - } - - public static class SDFStructureStart extends StructureStart { - public SDFStructureStart(StructureFeature feature, int chunkX, int chunkZ, BoundingBox box, int references, long seed) { - super(feature, chunkX, chunkZ, box, references, seed); - } - - @Override - public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager manager, int chunkX, int chunkZ, Biome biome, NoneFeatureConfiguration config) { - int x = (chunkX << 4) | MHelper.randRange(4, 12, random); - int z = (chunkZ << 4) | MHelper.randRange(4, 12, random); - int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG); - if (y > 5) { - float radius = MHelper.randRange(50, 100, random); - float height = radius * MHelper.randRange(0.8F, 1.2F, random); - CrystalMountainPiece piece = new CrystalMountainPiece(new BlockPos(x, y, z), radius, height, random, biome); - this.pieces.add(piece); - } - this.calculateBoundingBox(); - } - } -} diff --git a/src/main/java/ru/betterend/world/structures/features/PaintedMountainStructure.java b/src/main/java/ru/betterend/world/structures/features/PaintedMountainStructure.java deleted file mode 100644 index cbb6735a..00000000 --- a/src/main/java/ru/betterend/world/structures/features/PaintedMountainStructure.java +++ /dev/null @@ -1,58 +0,0 @@ -package ru.betterend.world.structures.features; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.RegistryAccess; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.StructureStart; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import ru.bclib.util.MHelper; -import ru.betterend.registry.EndBlocks; -import ru.betterend.world.structures.piece.PaintedMountainPiece; - -public class PaintedMountainStructure extends FeatureBaseStructure { - private static final BlockState[] VARIANTS; - - @Override - public StructureFeature.StructureStartFactory getStartFactory() { - return SDFStructureStart::new; - } - - public static class SDFStructureStart extends StructureStart { - public SDFStructureStart(StructureFeature feature, int chunkX, int chunkZ, BoundingBox box, int references, long seed) { - super(feature, chunkX, chunkZ, box, references, seed); - } - - @Override - public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager manager, int chunkX, int chunkZ, Biome biome, NoneFeatureConfiguration config) { - int x = (chunkX << 4) | MHelper.randRange(4, 12, random); - int z = (chunkZ << 4) | MHelper.randRange(4, 12, random); - int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG); - if (y > 50) { - float radius = MHelper.randRange(50, 100, random); - float height = radius * MHelper.randRange(0.4F, 0.6F, random); - int count = MHelper.floor(height * MHelper.randRange(0.1F, 0.35F, random) + 1); - BlockState[] slises = new BlockState[count]; - for (int i = 0; i < count; i++) { - slises[i] = VARIANTS[random.nextInt(VARIANTS.length)]; - } - this.pieces.add(new PaintedMountainPiece(new BlockPos(x, y, z), radius, height, random, biome, slises )); - } - this.calculateBoundingBox(); - } - } - - static { - VARIANTS = new BlockState[] { - Blocks.END_STONE.defaultBlockState(), - EndBlocks.FLAVOLITE.stone.defaultBlockState(), - EndBlocks.VIOLECITE.stone.defaultBlockState(), - }; - } -} diff --git a/src/main/java/ru/betterend/world/structures/features/SDFStructureFeature.java b/src/main/java/ru/betterend/world/structures/features/SDFStructureFeature.java deleted file mode 100644 index 40e28a3c..00000000 --- a/src/main/java/ru/betterend/world/structures/features/SDFStructureFeature.java +++ /dev/null @@ -1,46 +0,0 @@ -package ru.betterend.world.structures.features; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.RegistryAccess; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.feature.StructureFeature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.StructureStart; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import ru.bclib.sdf.SDF; -import ru.bclib.util.MHelper; -import ru.betterend.world.structures.piece.VoxelPiece; - -public abstract class SDFStructureFeature extends FeatureBaseStructure { - - protected abstract SDF getSDF(BlockPos pos, Random random); - - @Override - public StructureFeature.StructureStartFactory getStartFactory() { - return SDFStructureStart::new; - } - - public static class SDFStructureStart extends StructureStart { - public SDFStructureStart(StructureFeature feature, int chunkX, int chunkZ, BoundingBox box, int references, long seed) { - super(feature, chunkX, chunkZ, box, references, seed); - } - - @Override - public void generatePieces(RegistryAccess registryManager, ChunkGenerator chunkGenerator, StructureManager manager, int chunkX, int chunkZ, Biome biome, NoneFeatureConfiguration config) { - int x = (chunkX << 4) | MHelper.randRange(4, 12, random); - int z = (chunkZ << 4) | MHelper.randRange(4, 12, random); - int y = chunkGenerator.getBaseHeight(x, z, Types.WORLD_SURFACE_WG); - if (y > 5) { - BlockPos start = new BlockPos(x, y, z); - VoxelPiece piece = new VoxelPiece((world) -> { ((SDFStructureFeature) this.getFeature()).getSDF(start, this.random).fillRecursive(world, start); }, random.nextInt()); - this.pieces.add(piece); - } - this.calculateBoundingBox(); - } - } -} diff --git a/src/main/java/ru/betterend/world/structures/piece/BasePiece.java b/src/main/java/ru/betterend/world/structures/piece/BasePiece.java deleted file mode 100644 index b5ce64f8..00000000 --- a/src/main/java/ru/betterend/world/structures/piece/BasePiece.java +++ /dev/null @@ -1,18 +0,0 @@ -package ru.betterend.world.structures.piece; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.levelgen.feature.StructurePieceType; -import net.minecraft.world.level.levelgen.structure.StructurePiece; - -public abstract class BasePiece extends StructurePiece { - protected BasePiece(StructurePieceType type, int i) { - super(type, i); - } - - protected BasePiece(StructurePieceType type, CompoundTag tag) { - super(type, tag); - fromNbt(tag); - } - - protected abstract void fromNbt(CompoundTag tag); -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/world/structures/piece/CavePiece.java b/src/main/java/ru/betterend/world/structures/piece/CavePiece.java deleted file mode 100644 index a964e0e7..00000000 --- a/src/main/java/ru/betterend/world/structures/piece/CavePiece.java +++ /dev/null @@ -1,107 +0,0 @@ -package ru.betterend.world.structures.piece; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.StructureFeatureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndStructures; - -public class CavePiece extends BasePiece { - private OpenSimplexNoise noise; - private BlockPos center; - private float radius; - - public CavePiece(BlockPos center, float radius, int id) { - super(EndStructures.CAVE_PIECE, id); - this.center = center; - this.radius = radius; - this.noise = new OpenSimplexNoise(MHelper.getSeed(534, center.getX(), center.getZ())); - makeBoundingBox(); - } - - public CavePiece(StructureManager manager, CompoundTag tag) { - super(EndStructures.CAVE_PIECE, tag); - makeBoundingBox(); - } - - @Override - public boolean postProcess(WorldGenLevel world, StructureFeatureManager arg, ChunkGenerator chunkGenerator, Random random, BoundingBox blockBox, ChunkPos chunkPos, BlockPos blockPos) { - int x1 = MHelper.max(this.boundingBox.x0, blockBox.x0); - int z1 = MHelper.max(this.boundingBox.z0, blockBox.z0); - int x2 = MHelper.min(this.boundingBox.x1, blockBox.x1); - int z2 = MHelper.min(this.boundingBox.z1, blockBox.z1); - int y1 = this.boundingBox.y0; - int y2 = this.boundingBox.y1; - - double hr = radius * 0.75; - double nr = radius * 0.25; - MutableBlockPos pos = new MutableBlockPos(); - for (int x = x1; x <= x2; x++) { - int xsq = x - center.getX(); - xsq *= xsq; - pos.setX(x); - for (int z = z1; z <= z2; z++) { - int zsq = z - center.getZ(); - zsq *= zsq; - pos.setZ(z); - for (int y = y1; y <= y2; y++) { - int ysq = y - center.getY(); - ysq *= 1.6; - ysq *= ysq; - pos.setY(y); - double r = noise.eval(x * 0.1, y * 0.1, z * 0.1) * nr + hr; - double r2 = r - 4.5; - double dist = xsq + ysq + zsq; - if (dist < r2 * r2) { - if (world.getBlockState(pos).is(TagAPI.END_GROUND)) { - BlocksHelper.setWithoutUpdate(world, pos, CAVE_AIR); - } - } - else if (dist < r * r) { - if (world.getBlockState(pos).getMaterial().isReplaceable()) { - BlocksHelper.setWithoutUpdate(world, pos, Blocks.END_STONE); - } - } - } - } - } - - return true; - } - - @Override - protected void addAdditionalSaveData(CompoundTag tag) { - tag.put("center", NbtUtils.writeBlockPos(center)); - tag.putFloat("radius", radius); - } - - @Override - protected void fromNbt(CompoundTag tag) { - center = NbtUtils.readBlockPos(tag.getCompound("center")); - radius = tag.getFloat("radius"); - noise = new OpenSimplexNoise(MHelper.getSeed(534, center.getX(), center.getZ())); - } - - private void makeBoundingBox() { - int minX = MHelper.floor(center.getX() - radius); - int minY = MHelper.floor(center.getY() - radius); - int minZ = MHelper.floor(center.getZ() - radius); - int maxX = MHelper.floor(center.getX() + radius + 1); - int maxY = MHelper.floor(center.getY() + radius + 1); - int maxZ = MHelper.floor(center.getZ() + radius + 1); - this.boundingBox = new BoundingBox(minX, minY, minZ, maxX, maxY, maxZ); - } -} diff --git a/src/main/java/ru/betterend/world/structures/piece/CrystalMountainPiece.java b/src/main/java/ru/betterend/world/structures/piece/CrystalMountainPiece.java deleted file mode 100644 index e7a77628..00000000 --- a/src/main/java/ru/betterend/world/structures/piece/CrystalMountainPiece.java +++ /dev/null @@ -1,167 +0,0 @@ -package ru.betterend.world.structures.piece; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.util.Mth; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.StructureFeatureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import ru.bclib.api.BiomeAPI; -import ru.bclib.api.TagAPI; -import ru.bclib.util.MHelper; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndStructures; - -public class CrystalMountainPiece extends MountainPiece { - private BlockState top; - - public CrystalMountainPiece(BlockPos center, float radius, float height, Random random, Biome biome) { - super(EndStructures.MOUNTAIN_PIECE, center, radius, height, random, biome); - top = biome.getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - } - - public CrystalMountainPiece(StructureManager manager, CompoundTag tag) { - super(EndStructures.MOUNTAIN_PIECE, manager, tag); - } - - @Override - protected void fromNbt(CompoundTag tag) { - super.fromNbt(tag); - top = BiomeAPI.getBiome(biomeID).getBiome().getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - } - - @Override - public boolean postProcess(WorldGenLevel world, StructureFeatureManager arg, ChunkGenerator chunkGenerator, Random random, BoundingBox blockBox, ChunkPos chunkPos, BlockPos blockPos) { - int sx = chunkPos.getMinBlockX(); - int sz = chunkPos.getMinBlockZ(); - MutableBlockPos pos = new MutableBlockPos(); - ChunkAccess chunk = world.getChunk(chunkPos.x, chunkPos.z); - Heightmap map = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE); - Heightmap map2 = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE_WG); - for (int x = 0; x < 16; x++) { - int px = x + sx; - int px2 = px - center.getX(); - px2 *= px2; - pos.setX(x); - for (int z = 0; z < 16; z++) { - int pz = z + sz; - int pz2 = pz - center.getZ(); - pz2 *= pz2; - float dist = px2 + pz2; - if (dist < r2) { - pos.setZ(z); - dist = 1 - (float) Math.pow(dist / r2, 0.3); - int minY = map.getFirstAvailable(x, z); - if (minY < 10) { - continue; - } - pos.setY(minY); - while (!chunk.getBlockState(pos).is(TagAPI.GEN_TERRAIN) && pos.getY() > 56 && !chunk.getBlockState(pos.below()).is(Blocks.CAVE_AIR)) { - pos.setY(pos.getY() - 1); - } - minY = pos.getY(); - minY = Math.max(minY, map2.getFirstAvailable(x, z)); - if (minY > center.getY() - 8) { - float maxY = dist * height * getHeightClamp(world, 12, px, pz); - if (maxY > 0) { - maxY *= (float) noise1.eval(px * 0.05, pz * 0.05) * 0.3F + 0.7F; - maxY *= (float) noise1.eval(px * 0.1, pz * 0.1) * 0.1F + 0.8F; - maxY += center.getY(); - int maxYI = (int) (maxY); - int cover = maxYI - 1; - boolean needCover = (noise1.eval(px * 0.1, pz * 0.1) + MHelper.randRange(-0.4, 0.4, random) - (center.getY() + 14) * 0.1) > 0; - for (int y = minY - 1; y < maxYI; y++) { - pos.setY(y); - chunk.setBlockState(pos, needCover && y == cover ? top : Blocks.END_STONE.defaultBlockState(), false); - } - } - } - } - } - } - - map = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE); - - // Big crystals - int count = (map.getFirstAvailable(8, 8) - (center.getY() + 24)) / 7; - count = Mth.clamp(count, 0, 8); - for (int i = 0; i < count; i++) { - int radius = MHelper.randRange(2, 3, random); - float fill = MHelper.randRange(0F, 1F, random); - int x = MHelper.randRange(radius, 15 - radius, random); - int z = MHelper.randRange(radius, 15 - radius, random); - int y = map.getFirstAvailable(x, z); - if (y > 80) { - pos.set(x, y, z); - if (chunk.getBlockState(pos.below()).is(Blocks.END_STONE)) { - int height = MHelper.floor(radius * MHelper.randRange(1.5F, 3F, random) + (y - 80) * 0.3F); - crystal(chunk, pos, radius, height, fill, random); - } - } - } - - // Small crystals - count = (map.getFirstAvailable(8, 8) - (center.getY() + 24)) / 2; - count = Mth.clamp(count, 4, 8); - for (int i = 0; i < count; i++) { - int radius = MHelper.randRange(1, 2, random); - float fill = random.nextBoolean() ? 0 : 1; - int x = MHelper.randRange(radius, 15 - radius, random); - int z = MHelper.randRange(radius, 15 - radius, random); - int y = map.getFirstAvailable(x, z); - if (y > 80) { - pos.set(x, y, z); - if (chunk.getBlockState(pos.below()).getBlock() == Blocks.END_STONE) { - int height = MHelper.floor(radius * MHelper.randRange(1.5F, 3F, random) + (y - 80) * 0.3F); - crystal(chunk, pos, radius, height, fill, random); - } - } - } - - return true; - } - - private void crystal(ChunkAccess chunk, BlockPos pos, int radius, int height, float fill, Random random) { - MutableBlockPos mut = new MutableBlockPos(); - int max = MHelper.floor(fill * radius + radius + 0.5F); - height += pos.getY(); - Heightmap map = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE); - int coefX = MHelper.randRange(-1, 1, random); - int coefZ = MHelper.randRange(-1, 1, random); - for (int x = -radius; x <= radius; x++) { - mut.setX(x + pos.getX()); - if (mut.getX() >= 0 && mut.getX() < 16) { - int ax = Math.abs(x); - for (int z = -radius; z <= radius; z++) { - mut.setZ(z + pos.getZ()); - if (mut.getZ() >= 0 && mut.getZ() < 16) { - int az = Math.abs(z); - if (ax + az < max) { - int minY = map.getFirstAvailable(mut.getX(), mut.getZ()) - MHelper.randRange(3, 7, random); - if (pos.getY() - minY > 8) { - minY = pos.getY() - 8; - } - int h = coefX * x + coefZ * z + height; - for (int y = minY; y < h; y++) { - mut.setY(y); - chunk.setBlockState(mut, EndBlocks.AURORA_CRYSTAL.defaultBlockState(), false); - } - } - } - } - } - } - } -} diff --git a/src/main/java/ru/betterend/world/structures/piece/LakePiece.java b/src/main/java/ru/betterend/world/structures/piece/LakePiece.java deleted file mode 100644 index b304d42e..00000000 --- a/src/main/java/ru/betterend/world/structures/piece/LakePiece.java +++ /dev/null @@ -1,261 +0,0 @@ -package ru.betterend.world.structures.piece; - -import java.util.Map; -import java.util.Random; - -import com.google.common.collect.Maps; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Mth; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.StructureFeatureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import net.minecraft.world.level.material.FluidState; -import ru.bclib.api.BiomeAPI; -import ru.bclib.api.TagAPI; -import ru.bclib.util.BlocksHelper; -import ru.bclib.util.MHelper; -import ru.betterend.noise.OpenSimplexNoise; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndStructures; - -public class LakePiece extends BasePiece { - private static final BlockState ENDSTONE = Blocks.END_STONE.defaultBlockState(); - private static final BlockState WATER = Blocks.WATER.defaultBlockState(); - private Map heightmap = Maps.newHashMap(); - private OpenSimplexNoise noise; - private BlockPos center; - private float radius; - private float aspect; - private float depth; - private int seed; - - private ResourceLocation biomeID; - - public LakePiece(BlockPos center, float radius, float depth, Random random, Biome biome) { - super(EndStructures.LAKE_PIECE, random.nextInt()); - this.center = center; - this.radius = radius; - this.depth = depth; - this.seed = random.nextInt(); - this.noise = new OpenSimplexNoise(this.seed); - this.aspect = radius / depth; - this.biomeID = BiomeAPI.getBiomeID(biome); - makeBoundingBox(); - } - - public LakePiece(StructureManager manager, CompoundTag tag) { - super(EndStructures.LAKE_PIECE, tag); - makeBoundingBox(); - } - - @Override - protected void addAdditionalSaveData(CompoundTag tag) { - tag.put("center", NbtUtils.writeBlockPos(center)); - tag.putFloat("radius", radius); - tag.putFloat("depth", depth); - tag.putInt("seed", seed); - tag.putString("biome", biomeID.toString()); - } - - @Override - protected void fromNbt(CompoundTag tag) { - center = NbtUtils.readBlockPos(tag.getCompound("center")); - radius = tag.getFloat("radius"); - depth = tag.getFloat("depth"); - seed = tag.getInt("seed"); - noise = new OpenSimplexNoise(seed); - aspect = radius / depth; - biomeID = new ResourceLocation(tag.getString("biome")); - } - - @Override - public boolean postProcess(WorldGenLevel world, StructureFeatureManager arg, ChunkGenerator chunkGenerator, Random random, BoundingBox blockBox, ChunkPos chunkPos, BlockPos blockPos) { - int minY = this.boundingBox.y0; - int maxY = this.boundingBox.y1; - int sx = chunkPos.x << 4; - int sz = chunkPos.z << 4; - MutableBlockPos mut = new MutableBlockPos(); - ChunkAccess chunk = world.getChunk(chunkPos.x, chunkPos.z); - for (int x = 0; x < 16; x++) { - mut.setX(x); - int wx = x | sx; - double nx = wx * 0.1; - int x2 = wx - center.getX(); - for (int z = 0; z < 16; z++) { - mut.setZ(z); - int wz = z | sz; - double nz = wz * 0.1; - int z2 = wz - center.getZ(); - float clamp = getHeightClamp(world, 8, wx, wz); - if (clamp < 0.01) continue; - - double n = noise.eval(nx, nz) * 1.5 + 1.5; - double x3 = MHelper.sqr(x2 + noise.eval(nx, nz, 100) * 10); - double z3 = MHelper.sqr(z2 + noise.eval(nx, nz, -100) * 10); - - for (int y = minY; y <= maxY; y++) { - mut.setY((int) (y + n)); - double y2 = MHelper.sqr((y - center.getY()) * aspect); - double r2 = radius * clamp; - double r3 = r2 + 8; - r2 *= r2; - r3 = r3 * r3 + 100; - double dist = x3 + y2 + z3; - if (dist < r2) { - BlockState state = chunk.getBlockState(mut); - if (state.is(TagAPI.GEN_TERRAIN) || state.isAir()) { - state = mut.getY() < center.getY() ? WATER : CAVE_AIR; - chunk.setBlockState(mut, state, false); - } - } - else if (dist <= r3 && mut.getY() < center.getY()) { - BlockState state = chunk.getBlockState(mut); - BlockPos worldPos = mut.offset(sx, 0, sz); - if (!state.isCollisionShapeFullBlock(world, worldPos) && !state.isRedstoneConductor(world, worldPos)) { - state = chunk.getBlockState(mut.above()); - if (state.isAir()) { - state = random.nextBoolean() ? ENDSTONE : world.getBiome(worldPos).getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - } - else { - state = state.getFluidState().isEmpty() ? ENDSTONE : EndBlocks.ENDSTONE_DUST.defaultBlockState(); - } - chunk.setBlockState(mut, state, false); - } - } - } - } - } - fixWater(world, chunk, mut, random, sx, sz); - return true; - } - - private void fixWater(WorldGenLevel world, ChunkAccess chunk, MutableBlockPos mut, Random random, int sx, int sz) { - int minY = this.boundingBox.y0; - int maxY = this.boundingBox.y1; - for (int x = 0; x < 16; x++) { - mut.setX(x); - for (int z = 0; z < 16; z++) { - mut.setZ(z); - for (int y = minY; y <= maxY; y++) { - mut.setY(y); - FluidState state = chunk.getFluidState(mut); - if (!state.isEmpty()) { - mut.setY(y - 1); - if (chunk.getBlockState(mut).isAir()) { - mut.setY(y + 1); - - BlockState bState = chunk.getBlockState(mut); - if (bState.isAir()) { - bState = random.nextBoolean() ? ENDSTONE : world.getBiome(mut.offset(sx, 0, sz)).getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - } - else { - bState = bState.getFluidState().isEmpty() ? ENDSTONE : EndBlocks.ENDSTONE_DUST.defaultBlockState(); - } - - mut.setY(y); - - makeEndstonePillar(chunk, mut, bState); - } - else if (x > 1 && x < 15 && z > 1 && z < 15) { - mut.setY(y); - for (Direction dir: BlocksHelper.HORIZONTAL) { - BlockPos wPos = mut.offset(dir.getStepX(), 0, dir.getStepZ()); - if (chunk.getBlockState(wPos).isAir()) { - mut.setY(y + 1); - BlockState bState = chunk.getBlockState(mut); - if (bState.isAir()) { - bState = random.nextBoolean() ? ENDSTONE : world.getBiome(mut.offset(sx, 0, sz)).getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); - } - else { - bState = bState.getFluidState().isEmpty() ? ENDSTONE : EndBlocks.ENDSTONE_DUST.defaultBlockState(); - } - mut.setY(y); - makeEndstonePillar(chunk, mut, bState); - break; - } - } - } - else if (chunk.getBlockState(mut.move(Direction.UP)).isAir()) { - chunk.getLiquidTicks().scheduleTick(mut.move(Direction.DOWN), state.getType(), 0); - } - } - } - } - } - } - - private void makeEndstonePillar(ChunkAccess chunk, MutableBlockPos mut, BlockState terrain) { - chunk.setBlockState(mut, terrain, false); - mut.setY(mut.getY() - 1); - while (!chunk.getFluidState(mut).isEmpty()) { - chunk.setBlockState(mut, ENDSTONE, false); - mut.setY(mut.getY() - 1); - } - } - - private int getHeight(WorldGenLevel world, BlockPos pos) { - int p = ((pos.getX() & 2047) << 11) | (pos.getZ() & 2047); - int h = heightmap.getOrDefault(p, Byte.MIN_VALUE); - if (h > Byte.MIN_VALUE) { - return h; - } - - if (!BiomeAPI.getBiomeID(world.getBiome(pos)).equals(biomeID)) { - heightmap.put(p, (byte) 0); - return 0; - } - - h = world.getHeight(Types.WORLD_SURFACE_WG, pos.getX(), pos.getZ()); - h = Mth.abs(h - center.getY()); - h = h < 8 ? 1 : 0; - - heightmap.put(p, (byte) h); - return h; - } - - private float getHeightClamp(WorldGenLevel world, int radius, int posX, int posZ) { - MutableBlockPos mut = new MutableBlockPos(); - int r2 = radius * radius; - float height = 0; - float max = 0; - for (int x = -radius; x <= radius; x++) { - mut.setX(posX + x); - int x2 = x * x; - for (int z = -radius; z <= radius; z++) { - mut.setZ(posZ + z); - int z2 = z * z; - if (x2 + z2 < r2) { - float mult = 1 - (float) Math.sqrt(x2 + z2) / radius; - max += mult; - height += getHeight(world, mut) * mult; - } - } - } - height /= max; - return Mth.clamp(height, 0, 1); - } - - private void makeBoundingBox() { - int minX = MHelper.floor(center.getX() - radius - 8); - int minY = MHelper.floor(center.getY() - depth - 8); - int minZ = MHelper.floor(center.getZ() - radius - 8); - int maxX = MHelper.floor(center.getX() + radius + 8); - int maxY = MHelper.floor(center.getY() + depth); - int maxZ = MHelper.floor(center.getZ() + radius + 8); - this.boundingBox = new BoundingBox(minX, minY, minZ, maxX, maxY, maxZ); - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/world/structures/piece/MountainPiece.java b/src/main/java/ru/betterend/world/structures/piece/MountainPiece.java deleted file mode 100644 index bc2ef668..00000000 --- a/src/main/java/ru/betterend/world/structures/piece/MountainPiece.java +++ /dev/null @@ -1,137 +0,0 @@ -package ru.betterend.world.structures.piece; - -import java.util.Map; -import java.util.Random; - -import com.google.common.collect.Maps; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Mth; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.feature.StructurePieceType; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import ru.bclib.api.BiomeAPI; -import ru.bclib.util.MHelper; -import ru.betterend.noise.OpenSimplexNoise; - -public abstract class MountainPiece extends BasePiece { - protected Map heightmap = Maps.newHashMap(); - protected OpenSimplexNoise noise1; - protected OpenSimplexNoise noise2; - protected BlockPos center; - protected float radius; - protected float height; - protected float r2; - protected ResourceLocation biomeID; - protected int seed1; - protected int seed2; - - public MountainPiece(StructurePieceType type, BlockPos center, float radius, float height, Random random, Biome biome) { - super(type, random.nextInt()); - this.center = center; - this.radius = radius; - this.height = height; - this.r2 = radius * radius; - this.seed1 = random.nextInt(); - this.seed2 = random.nextInt(); - this.noise1 = new OpenSimplexNoise(this.seed1); - this.noise2 = new OpenSimplexNoise(this.seed2); - this.biomeID = BiomeAPI.getBiomeID(biome); - makeBoundingBox(); - } - - public MountainPiece(StructurePieceType type, StructureManager manager, CompoundTag tag) { - super(type, tag); - makeBoundingBox(); - } - - @Override - protected void addAdditionalSaveData(CompoundTag tag) { - tag.put("center", NbtUtils.writeBlockPos(center)); - tag.putFloat("radius", radius); - tag.putFloat("height", height); - tag.putString("biome", biomeID.toString()); - tag.putInt("seed1", seed1); - tag.putInt("seed2", seed2); - } - - @Override - protected void fromNbt(CompoundTag tag) { - center = NbtUtils.readBlockPos(tag.getCompound("center")); - radius = tag.getFloat("radius"); - height = tag.getFloat("height"); - biomeID = new ResourceLocation(tag.getString("biome")); - r2 = radius * radius; - seed1 = tag.getInt("seed1"); - seed2 = tag.getInt("seed2"); - noise1 = new OpenSimplexNoise(seed1); - noise2 = new OpenSimplexNoise(seed2); - } - - private int getHeight(WorldGenLevel world, BlockPos pos) { - int p = ((pos.getX() & 2047) << 11) | (pos.getZ() & 2047); - int h = heightmap.getOrDefault(p, Integer.MIN_VALUE); - if (h > Integer.MIN_VALUE) { - return h; - } - - if (!BiomeAPI.getBiomeID(world.getBiome(pos)).equals(biomeID)) { - heightmap.put(p, -10); - return -10; - } - h = world.getHeight(Types.WORLD_SURFACE_WG, pos.getX(), pos.getZ()); - h = Mth.abs(h - center.getY()); - if (h > 4) { - h = 4 - h; - heightmap.put(p, h); - return h; - } - - h = MHelper.floor(noise2.eval(pos.getX() * 0.01, pos.getZ() * 0.01) * noise2.eval(pos.getX() * 0.002, pos.getZ() * 0.002) * 8 + 8); - - if (h < 0) { - heightmap.put(p, 0); - return 0; - } - - heightmap.put(p, h); - - return h; - } - - protected float getHeightClamp(WorldGenLevel world, int radius, int posX, int posZ) { - MutableBlockPos mut = new MutableBlockPos(); - float height = 0; - float max = 0; - for (int x = -radius; x <= radius; x++) { - mut.setX(posX + x); - int x2 = x * x; - for (int z = -radius; z <= radius; z++) { - mut.setZ(posZ + z); - int z2 = z * z; - float mult = 1 - (float) Math.sqrt(x2 + z2) / radius; - if (mult > 0) { - max += mult; - height += getHeight(world, mut) * mult; - } - } - } - height /= max; - return Mth.clamp(height / radius, 0, 1); - } - - private void makeBoundingBox() { - int minX = MHelper.floor(center.getX() - radius); - int minZ = MHelper.floor(center.getZ() - radius); - int maxX = MHelper.floor(center.getX() + radius + 1); - int maxZ = MHelper.floor(center.getZ() + radius + 1); - this.boundingBox = new BoundingBox(minX, minZ, maxX, maxZ); - } -} diff --git a/src/main/java/ru/betterend/world/structures/piece/NBTPiece.java b/src/main/java/ru/betterend/world/structures/piece/NBTPiece.java deleted file mode 100644 index bc5388f3..00000000 --- a/src/main/java/ru/betterend/world/structures/piece/NBTPiece.java +++ /dev/null @@ -1,93 +0,0 @@ -package ru.betterend.world.structures.piece; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.StructureFeatureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; -import ru.bclib.util.MHelper; -import ru.bclib.util.StructureHelper; -import ru.betterend.registry.EndStructures; - -public class NBTPiece extends BasePiece { - private ResourceLocation structureID; - private Rotation rotation; - private Mirror mirror; - private StructureTemplate structure; - private BlockPos pos; - private int erosion; - private boolean cover; - - public NBTPiece(ResourceLocation structureID, StructureTemplate structure, BlockPos pos, int erosion, boolean cover, Random random) { - super(EndStructures.NBT_PIECE, random.nextInt()); - this.structureID = structureID; - this.structure = structure; - this.rotation = Rotation.getRandom(random); - this.mirror = Mirror.values()[random.nextInt(3)]; - this.pos = StructureHelper.offsetPos(pos, structure, rotation, mirror); - this.erosion = erosion; - this.cover = cover; - makeBoundingBox(); - } - - public NBTPiece(StructureManager manager, CompoundTag tag) { - super(EndStructures.NBT_PIECE, tag); - makeBoundingBox(); - } - - @Override - protected void addAdditionalSaveData(CompoundTag tag) { - tag.putString("structureID", structureID.toString()); - tag.putInt("rotation", rotation.ordinal()); - tag.putInt("mirror", mirror.ordinal()); - tag.putInt("erosion", erosion); - tag.put("pos", NbtUtils.writeBlockPos(pos)); - tag.putBoolean("cover", cover); - } - - @Override - protected void fromNbt(CompoundTag tag) { - structureID = new ResourceLocation(tag.getString("structureID")); - rotation = Rotation.values()[tag.getInt("rotation")]; - mirror = Mirror.values()[tag.getInt("mirror")]; - erosion = tag.getInt("erosion"); - pos = NbtUtils.readBlockPos(tag.getCompound("pos")); - cover = tag.getBoolean("cover"); - structure = StructureHelper.readStructure(structureID); - } - - @Override - public boolean postProcess(WorldGenLevel world, StructureFeatureManager arg, ChunkGenerator chunkGenerator, Random random, BoundingBox blockBox, ChunkPos chunkPos, BlockPos blockPos) { - BoundingBox bounds = new BoundingBox(blockBox); - bounds.y1 = this.boundingBox.y1; - bounds.y0 = this.boundingBox.y0; - StructurePlaceSettings placementData = new StructurePlaceSettings().setRotation(rotation).setMirror(mirror).setBoundingBox(bounds); - structure.placeInWorldChunk(world, pos, placementData, random); - if (erosion > 0) { - bounds.x1 = MHelper.min(bounds.x1, boundingBox.x1); - bounds.x0 = MHelper.max(bounds.x0, boundingBox.x0); - bounds.z1 = MHelper.min(bounds.z1, boundingBox.z1); - bounds.z0 = MHelper.max(bounds.z0, boundingBox.z0); - StructureHelper.erode(world, bounds, erosion, random); - } - if (cover) { - StructureHelper.cover(world, bounds, random); - } - return true; - } - - private void makeBoundingBox() { - this.boundingBox = StructureHelper.getStructureBounds(pos, structure, rotation, mirror); - } -} diff --git a/src/main/java/ru/betterend/world/structures/piece/PaintedMountainPiece.java b/src/main/java/ru/betterend/world/structures/piece/PaintedMountainPiece.java deleted file mode 100644 index cbbaa91d..00000000 --- a/src/main/java/ru/betterend/world/structures/piece/PaintedMountainPiece.java +++ /dev/null @@ -1,103 +0,0 @@ -package ru.betterend.world.structures.piece; - -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.StructureFeatureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import ru.bclib.util.MHelper; -import ru.betterend.registry.EndStructures; - -public class PaintedMountainPiece extends MountainPiece { - private BlockState[] slises; - public PaintedMountainPiece(BlockPos center, float radius, float height, Random random, Biome biome, BlockState[] slises) { - super(EndStructures.PAINTED_MOUNTAIN_PIECE, center, radius, height, random, biome); - this.slises = slises; - } - - public PaintedMountainPiece(StructureManager manager, CompoundTag tag) { - super(EndStructures.PAINTED_MOUNTAIN_PIECE, manager, tag); - } - - @Override - protected void addAdditionalSaveData(CompoundTag tag) { - super.addAdditionalSaveData(tag); - ListTag slise = new ListTag(); - for (BlockState state: slises) { - slise.add(NbtUtils.writeBlockState(state)); - } - tag.put("slises", slise); - } - - @Override - protected void fromNbt(CompoundTag tag) { - super.fromNbt(tag); - ListTag slise = tag.getList("slises", 10); - slises = new BlockState[slise.size()]; - for (int i = 0; i < slises.length; i++) { - slises[i] = NbtUtils.readBlockState(slise.getCompound(i)); - } - } - - @Override - public boolean postProcess(WorldGenLevel world, StructureFeatureManager arg, ChunkGenerator chunkGenerator, Random random, BoundingBox blockBox, ChunkPos chunkPos, BlockPos blockPos) { - int sx = chunkPos.getMinBlockX(); - int sz = chunkPos.getMinBlockZ(); - MutableBlockPos pos = new MutableBlockPos(); - ChunkAccess chunk = world.getChunk(chunkPos.x, chunkPos.z); - Heightmap map = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE); - Heightmap map2 = chunk.getOrCreateHeightmapUnprimed(Types.WORLD_SURFACE_WG); - for (int x = 0; x < 16; x++) { - int px = x + sx; - int px2 = px - center.getX(); - px2 *= px2; - pos.setX(x); - for (int z = 0; z < 16; z++) { - int pz = z + sz; - int pz2 = pz - center.getZ(); - pz2 *= pz2; - float dist = px2 + pz2; - if (dist < r2) { - pos.setZ(z); - dist = 1 - dist / r2; - int minY = map.getFirstAvailable(x, z); - pos.setY(minY - 1); - while (chunk.getBlockState(pos).isAir() && pos.getY() > 50) { - pos.setY(minY --); - } - minY = pos.getY(); - minY = Math.max(minY, map2.getFirstAvailable(x, z)); - if (minY > center.getY() - 8) { - float maxY = dist * height * getHeightClamp(world, 10, px, pz); - if (maxY > 0) { - maxY *= (float) noise1.eval(px * 0.05, pz * 0.05) * 0.3F + 0.7F; - maxY *= (float) noise1.eval(px * 0.1, pz * 0.1) * 0.1F + 0.9F; - maxY += center.getY(); - float offset = (float) (noise1.eval(px * 0.07, pz * 0.07) * 5 + noise1.eval(px * 0.2, pz * 0.2) * 2 + 7); - for (int y = minY - 1; y < maxY; y++) { - pos.setY(y); - int index = MHelper.floor((y + offset) * 0.65F) % slises.length; - chunk.setBlockState(pos, slises[index], false); - } - } - } - } - } - } - - return true; - } -} diff --git a/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java b/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java deleted file mode 100644 index 08a4a100..00000000 --- a/src/main/java/ru/betterend/world/structures/piece/VoxelPiece.java +++ /dev/null @@ -1,47 +0,0 @@ -package ru.betterend.world.structures.piece; - -import java.util.Random; -import java.util.function.Consumer; - -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.StructureFeatureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import ru.bclib.world.structures.StructureWorld; -import ru.betterend.registry.EndStructures; - -public class VoxelPiece extends BasePiece { - private StructureWorld world; - - public VoxelPiece(Consumer function, int id) { - super(EndStructures.VOXEL_PIECE, id); - world = new StructureWorld(); - function.accept(world); - this.boundingBox = world.getBounds(); - } - - public VoxelPiece(StructureManager manager, CompoundTag tag) { - super(EndStructures.VOXEL_PIECE, tag); - this.boundingBox = world.getBounds(); - } - - @Override - protected void addAdditionalSaveData(CompoundTag tag) { - tag.put("world", world.toBNT()); - } - - @Override - protected void fromNbt(CompoundTag tag) { - world = new StructureWorld(tag.getCompound("world")); - } - - @Override - public boolean postProcess(WorldGenLevel world, StructureFeatureManager arg, ChunkGenerator chunkGenerator, Random random, BoundingBox blockBox, ChunkPos chunkPos, BlockPos blockPos) { - this.world.placeChunk(world, chunkPos); - return true; - } -} diff --git a/src/main/java/ru/betterend/world/surface/SulphuricSurfaceBuilder.java b/src/main/java/ru/betterend/world/surface/SulphuricSurfaceBuilder.java deleted file mode 100644 index 90841b95..00000000 --- a/src/main/java/ru/betterend/world/surface/SulphuricSurfaceBuilder.java +++ /dev/null @@ -1,41 +0,0 @@ -package ru.betterend.world.surface; - -import java.util.Random; - -import net.minecraft.core.Registry; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilder; -import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilderBaseConfiguration; -import ru.bclib.util.MHelper; -import ru.betterend.noise.OpenSimplexNoise; - -public class SulphuricSurfaceBuilder extends SurfaceBuilder { - private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(5123); - - public SulphuricSurfaceBuilder() { - super(SurfaceBuilderBaseConfiguration.CODEC); - } - - @Override - public void apply(Random random, ChunkAccess chunk, Biome biome, int x, int z, int height, double noise, BlockState defaultBlock, BlockState defaultFluid, int seaLevel, long seed, SurfaceBuilderBaseConfiguration surfaceBlocks) { - double value = NOISE.eval(x * 0.03, z * 0.03) + NOISE.eval(x * 0.1, z * 0.1) * 0.3 + MHelper.randRange(-0.1, 0.1, MHelper.RANDOM); - if (value < -0.6) { - SurfaceBuilder.DEFAULT.apply(random, chunk, biome, x, z, height, noise, defaultBlock, defaultFluid, seaLevel, seed, SurfaceBuilders.DEFAULT_END_CONFIG); - } - else if (value < -0.3) { - SurfaceBuilder.DEFAULT.apply(random, chunk, biome, x, z, height, noise, defaultBlock, defaultFluid, seaLevel, seed, SurfaceBuilders.FLAVOLITE_CONFIG); - } - else if (value < 0.5) { - SurfaceBuilder.DEFAULT.apply(random, chunk, biome, x, z, height, noise, defaultBlock, defaultFluid, seaLevel, seed, SurfaceBuilders.SULFURIC_ROCK_CONFIG); - } - else { - SurfaceBuilder.DEFAULT.apply(random, chunk, biome, x, z, height, noise, defaultBlock, defaultFluid, seaLevel, seed, SurfaceBuilders.BRIMSTONE_CONFIG); - } - } - - public static SulphuricSurfaceBuilder register(String name) { - return Registry.register(Registry.SURFACE_BUILDER, name, new SulphuricSurfaceBuilder()); - } -} \ No newline at end of file diff --git a/src/main/java/ru/betterend/world/surface/SurfaceBuilders.java b/src/main/java/ru/betterend/world/surface/SurfaceBuilders.java deleted file mode 100644 index b00b12ca..00000000 --- a/src/main/java/ru/betterend/world/surface/SurfaceBuilders.java +++ /dev/null @@ -1,29 +0,0 @@ -package ru.betterend.world.surface; - -import net.minecraft.core.Registry; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilder; -import net.minecraft.world.level.levelgen.surfacebuilders.SurfaceBuilderBaseConfiguration; -import ru.betterend.registry.EndBlocks; - -public class SurfaceBuilders { - public static final SurfaceBuilderBaseConfiguration DEFAULT_END_CONFIG = makeSimpleConfig(Blocks.END_STONE); - public static final SurfaceBuilderBaseConfiguration FLAVOLITE_CONFIG = makeSimpleConfig(EndBlocks.FLAVOLITE.stone); - public static final SurfaceBuilderBaseConfiguration BRIMSTONE_CONFIG = makeSimpleConfig(EndBlocks.BRIMSTONE); - public static final SurfaceBuilderBaseConfiguration SULFURIC_ROCK_CONFIG = makeSimpleConfig(EndBlocks.SULPHURIC_ROCK.stone); - - public static final SurfaceBuilder SULPHURIC_SURFACE = register("sulphuric_surface", new SulphuricSurfaceBuilder()); - - private static SurfaceBuilder register(String name, SurfaceBuilder builder) { - return Registry.register(Registry.SURFACE_BUILDER, name, builder); - } - - private static SurfaceBuilderBaseConfiguration makeSimpleConfig(Block block) { - BlockState state = block.defaultBlockState(); - return new SurfaceBuilderBaseConfiguration(state, state, state); - } - - public static void register() {} -} diff --git a/src/main/java/shadow/fabric/api/client/rendering/v1/ArmorRenderingRegistry.java b/src/main/java/shadow/fabric/api/client/rendering/v1/ArmorRenderingRegistry.java new file mode 100644 index 00000000..fee2cc5c --- /dev/null +++ b/src/main/java/shadow/fabric/api/client/rendering/v1/ArmorRenderingRegistry.java @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + /* + This file is a refactor from fabric-api, based on the work of shedaniel. + */ + + +package shadow.fabric.api.client.rendering.v1; + +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import shadow.fabric.impl.client.rendering.ArmorRenderingRegistryImpl; + +import java.util.Arrays; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A class for registering custom armor models and textures for {@link Item}, to be provided by a {@link ModelProvider} or {@link TextureProvider}. + * + *

This can be used to replace existing vanilla armor models and textures conditionally, however each {@link Item} + * instance can only allow one {@link ModelProvider} or {@link TextureProvider} respectively, causing potential conflicts + * with other mods if you replace the model or texture for vanilla items. Consider using a separate item instead.

+ * + *

A custom model would probably also require a custom texture to go along it, the model will use the vanilla texture if it is undefined.

+ * + *

Since armor textures identifier in vanilla is hardcoded to be in the {@code minecraft} namespace, this registry can also be + * used to use a custom namespace if desired.

+ */ +@Environment(EnvType.CLIENT) +public final class ArmorRenderingRegistry { + private ArmorRenderingRegistry() { + } + + /** + * Registers a provider for custom armor models for an item. + * + * @param provider the provider for the model + * @param items the items to be registered for + */ + public static void registerModel(@Nullable ModelProvider provider, Item... items) { + registerModel(provider, Arrays.asList(items)); + } + + /** + * Registers a provider for custom armor models for an item. + * + * @param provider the provider for the model + * @param items the items to be registered for + */ + public static void registerModel(@Nullable ModelProvider provider, Iterable items) { + ArmorRenderingRegistryImpl.registerModel(provider, items); + } + + /** + * Registers a provider for custom texture models for an item. + * + * @param provider the provider for the texture + * @param items the items to be registered for + */ + public static void registerTexture(@Nullable TextureProvider provider, Item... items) { + registerTexture(provider, Arrays.asList(items)); + } + + /** + * Registers a provider for custom texture models for an item. + * + * @param provider the provider for the texture + * @param items the items to be registered for + */ + public static void registerTexture(@Nullable TextureProvider provider, Iterable items) { + ArmorRenderingRegistryImpl.registerTexture(provider, items); + } + + /** + * Register simple armor items to use the vanilla armor file name under the mods namespace. + * + * @param identifier The namespace + path to use for the armor texture location. + * @param items the items to be registered + */ + public static void registerSimpleTexture(ResourceLocation identifier, Item... items) { + registerTexture((entity, stack, slot, secondLayer, suffix, defaultTexture) -> { + return new ResourceLocation( + identifier.getNamespace(), + "textures/models/armor/" + identifier.getPath() + "_layer_" + (secondLayer + ? 2 + : 1) + (suffix == null ? "" : "_" + suffix) + ".png" + ); + }, items); + } + + /** + * Gets the model of the armor piece. + * + * @param entity The entity equipping the armor + * @param stack The item stack of the armor + * @param slot The slot which the armor is in + * @param defaultModel The default model that vanilla provides + * @return The model of the armor piece. + */ + @NotNull + public static HumanoidModel getArmorModel( + LivingEntity entity, + ItemStack stack, + EquipmentSlot slot, + HumanoidModel defaultModel + ) { + return ArmorRenderingRegistryImpl.getArmorModel(entity, stack, slot, defaultModel); + } + + /** + * Gets the armor texture {@link net.minecraft.resources.ResourceLocation}. + * + * @param entity The entity equipping the armor + * @param stack The item stack of the armor + * @param slot The slot which the armor is in + * @param secondLayer True if using the second texture layer + * @param suffix The texture suffix, used in vanilla by {@link net.minecraft.world.item.DyeableArmorItem} + * @param defaultTexture The default vanilla texture identifier + * @return the custom armor texture identifier, return null to use the vanilla ones. Defaulted to the item's registry id. + */ + @NotNull + public static ResourceLocation getArmorTexture( + LivingEntity entity, + ItemStack stack, + EquipmentSlot slot, + boolean secondLayer, + @Nullable String suffix, + ResourceLocation defaultTexture + ) { + return ArmorRenderingRegistryImpl.getArmorTexture(entity, stack, slot, secondLayer, suffix, defaultTexture); + } + + @FunctionalInterface + @Environment(EnvType.CLIENT) + public interface ModelProvider { + /** + * Gets the model of the armor piece. + * + * @param entity The entity equipping the armor + * @param stack The item stack of the armor + * @param slot The slot which the armor is in + * @param defaultModel The default vanilla armor model + * @return The model of the armor piece. Should never be null. + */ + @NotNull HumanoidModel getArmorModel( + LivingEntity entity, + ItemStack stack, + EquipmentSlot slot, + HumanoidModel defaultModel + ); + } + + @FunctionalInterface + @Environment(EnvType.CLIENT) + public interface TextureProvider { + /** + * Gets the armor texture {@link net.minecraft.resources.ResourceLocation}. + * + * @param entity The entity equipping the armor + * @param stack The item stack of the armor + * @param slot The slot which the armor is in + * @param defaultTexture The default vanilla texture identifier + * @return the custom armor texture identifier. Should never be null. + */ + @NotNull ResourceLocation getArmorTexture( + LivingEntity entity, + ItemStack stack, + EquipmentSlot slot, + boolean secondLayer, + @Nullable String suffix, + ResourceLocation defaultTexture + ); + } +} diff --git a/src/main/java/shadow/fabric/impl/client/rendering/ArmorProviderExtensions.java b/src/main/java/shadow/fabric/impl/client/rendering/ArmorProviderExtensions.java new file mode 100644 index 00000000..667adca8 --- /dev/null +++ b/src/main/java/shadow/fabric/impl/client/rendering/ArmorProviderExtensions.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + /* + This file is a refactor from fabric-api, based on the work of shedaniel. + */ + + +package shadow.fabric.impl.client.rendering; + +import shadow.fabric.api.client.rendering.v1.ArmorRenderingRegistry; + +import org.jetbrains.annotations.Nullable; + +public interface ArmorProviderExtensions { + @Nullable ArmorRenderingRegistry.ModelProvider fabric_getArmorModelProvider(); + + @Nullable ArmorRenderingRegistry.TextureProvider fabric_getArmorTextureProvider(); + + void fabric_setArmorModelProvider(@Nullable ArmorRenderingRegistry.ModelProvider provider); + + void fabric_setArmorTextureProvider(@Nullable ArmorRenderingRegistry.TextureProvider provider); +} diff --git a/src/main/java/shadow/fabric/impl/client/rendering/ArmorRenderingRegistryImpl.java b/src/main/java/shadow/fabric/impl/client/rendering/ArmorRenderingRegistryImpl.java new file mode 100644 index 00000000..f69bff9f --- /dev/null +++ b/src/main/java/shadow/fabric/impl/client/rendering/ArmorRenderingRegistryImpl.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + /* + This file is a refactor from fabric-api, based on the work of shedaniel. + */ + + +package shadow.fabric.impl.client.rendering; + +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +import shadow.fabric.api.client.rendering.v1.ArmorRenderingRegistry; + +import java.util.Objects; +import org.jetbrains.annotations.Nullable; + +public final class ArmorRenderingRegistryImpl { + private ArmorRenderingRegistryImpl() { + } + + public static void registerModel(ArmorRenderingRegistry.ModelProvider provider, Iterable items) { + Objects.requireNonNull(items); + + for (Item item : items) { + Objects.requireNonNull(item); + + ((ArmorProviderExtensions) item).fabric_setArmorModelProvider(provider); + } + } + + public static void registerTexture(ArmorRenderingRegistry.TextureProvider provider, Iterable items) { + Objects.requireNonNull(items); + + for (Item item : items) { + Objects.requireNonNull(item); + + ((ArmorProviderExtensions) item).fabric_setArmorTextureProvider(provider); + } + } + + public static HumanoidModel getArmorModel( + LivingEntity entity, + ItemStack stack, + EquipmentSlot slot, + HumanoidModel defaultModel + ) { + if (!stack.isEmpty()) { + ArmorRenderingRegistry.ModelProvider provider = ((ArmorProviderExtensions) stack.getItem()).fabric_getArmorModelProvider(); + + if (provider != null) { + return provider.getArmorModel(entity, stack, slot, defaultModel); + } + } + + return defaultModel; + } + + public static ResourceLocation getArmorTexture( + LivingEntity entity, + ItemStack stack, + EquipmentSlot slot, + boolean secondLayer, + @Nullable String suffix, + ResourceLocation defaultTexture + ) { + if (!stack.isEmpty()) { + ArmorRenderingRegistry.TextureProvider provider = ((ArmorProviderExtensions) stack.getItem()).fabric_getArmorTextureProvider(); + + if (provider != null) { + return provider.getArmorTexture(entity, stack, slot, secondLayer, suffix, defaultTexture); + } + } + + return defaultTexture; + } +} diff --git a/src/main/java/shadow/fabric/mixin/client/rendering/MixinArmorFeatureRenderer.java b/src/main/java/shadow/fabric/mixin/client/rendering/MixinArmorFeatureRenderer.java new file mode 100644 index 00000000..6b4c8f40 --- /dev/null +++ b/src/main/java/shadow/fabric/mixin/client/rendering/MixinArmorFeatureRenderer.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + /* + This file is a refactor from fabric-api, based on the work of shedaniel. + */ + + +package shadow.fabric.mixin.client.rendering; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.RenderLayerParent; +import net.minecraft.client.renderer.entity.layers.HumanoidArmorLayer; +import net.minecraft.client.renderer.entity.layers.RenderLayer; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ArmorItem; +import net.minecraft.world.item.ItemStack; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import shadow.fabric.api.client.rendering.v1.ArmorRenderingRegistry; + +import java.util.Map; +import java.util.Objects; + +@Mixin(HumanoidArmorLayer.class) +@Environment(EnvType.CLIENT) +public abstract class MixinArmorFeatureRenderer extends RenderLayer { + @Shadow + @Final + private static Map ARMOR_LOCATION_CACHE; + + public MixinArmorFeatureRenderer(RenderLayerParent context) { + super(context); + + } + + @Unique + private LivingEntity be_storedEntity; + @Unique + private EquipmentSlot be_storedSlot; + + @Inject(method = "render", at = @At("HEAD")) + private void be_storeEntity( + PoseStack matrixStack, + MultiBufferSource vertexConsumerProvider, + int i, + LivingEntity livingEntity, + float f, + float g, + float h, + float j, + float k, + float l, + CallbackInfo ci + ) { + // We store the living entity wearing the armor before we render + this.be_storedEntity = livingEntity; + } + + @Inject(method = "renderArmorPiece", at = @At("HEAD")) + private void be_storeSlot( + PoseStack matrices, + MultiBufferSource vertexConsumers, + LivingEntity livingEntity, + EquipmentSlot slot, + int i, + HumanoidModel bipedEntityModel, + CallbackInfo ci + ) { + // We store the current armor slot that is rendering before we render each armor piece + this.be_storedSlot = slot; + } + + @Inject(method = "render", at = @At("RETURN")) + private void be_removeStored( + PoseStack matrixStack, + MultiBufferSource vertexConsumerProvider, + int i, + LivingEntity livingEntity, + float f, + float g, + float h, + float j, + float k, + float l, + CallbackInfo ci + ) { + // We remove the stored data after we render + this.be_storedEntity = null; + this.be_storedSlot = null; + } + + @Inject(method = "getArmorModel", at = @At("RETURN"), cancellable = true) + private void be_selectArmorModel(EquipmentSlot slot, CallbackInfoReturnable> cir) { + if (be_storedEntity != null) { + ItemStack stack = be_storedEntity.getItemBySlot(slot); + + HumanoidModel defaultModel = cir.getReturnValue(); + HumanoidModel model = ArmorRenderingRegistry.getArmorModel( + be_storedEntity, + stack, + slot, + defaultModel + ); + + if (model != defaultModel) { + cir.setReturnValue(model); + } + } + } + + @Inject(method = "getArmorLocation", at = @At(value = "INVOKE", target = "Ljava/util/Map;computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;"), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD) + private void be_getArmorTexture( + ArmorItem armorItem, + boolean secondLayer, /* @Nullable */ + String suffix, + CallbackInfoReturnable cir, + String vanillaIdentifier + ) { + String texture = ArmorRenderingRegistry.getArmorTexture( + be_storedEntity, + be_storedEntity.getItemBySlot(be_storedSlot), + be_storedSlot, + secondLayer, + suffix, + new ResourceLocation(vanillaIdentifier) + ).toString(); + + if (!Objects.equals(texture, vanillaIdentifier)) { + cir.setReturnValue(ARMOR_LOCATION_CACHE.computeIfAbsent(texture, ResourceLocation::new)); + } + } +} diff --git a/src/main/java/shadow/fabric/mixin/client/rendering/MixinItem.java b/src/main/java/shadow/fabric/mixin/client/rendering/MixinItem.java new file mode 100644 index 00000000..37dbaa36 --- /dev/null +++ b/src/main/java/shadow/fabric/mixin/client/rendering/MixinItem.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + /* + This file is a refactor from fabric-api, based on the work of shedaniel. + */ + +package shadow.fabric.mixin.client.rendering; + + +import net.minecraft.world.item.Item; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import shadow.fabric.api.client.rendering.v1.ArmorRenderingRegistry; +import shadow.fabric.impl.client.rendering.ArmorProviderExtensions; + + +@Mixin(Item.class) +public class MixinItem implements ArmorProviderExtensions { + @Unique + private ArmorRenderingRegistry.ModelProvider armorModelProvider; + @Unique + private ArmorRenderingRegistry.TextureProvider armorTextureProvider; + + @Override + public ArmorRenderingRegistry.ModelProvider fabric_getArmorModelProvider() { + return armorModelProvider; + } + + @Override + public ArmorRenderingRegistry.TextureProvider fabric_getArmorTextureProvider() { + return armorTextureProvider; + } + + @Override + public void fabric_setArmorModelProvider(ArmorRenderingRegistry.ModelProvider provider) { + armorModelProvider = provider; + } + + @Override + public void fabric_setArmorTextureProvider(ArmorRenderingRegistry.TextureProvider provider) { + armorTextureProvider = provider; + } +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/blockstates/crystal_moss_cover.json b/src/main/resources/assets/betterend/blockstates/crystal_moss_cover.json new file mode 100644 index 00000000..785593b9 --- /dev/null +++ b/src/main/resources/assets/betterend/blockstates/crystal_moss_cover.json @@ -0,0 +1,150 @@ +{ + "multipart": [ + { + "apply": { + "model": "betterend:block/crystal_moss_cover" + }, + "when": { + "north": "true" + } + }, + { + "apply": { + "model": "betterend:block/crystal_moss_cover" + }, + "when": { + "down": "false", + "east": "false", + "north": "false", + "south": "false", + "up": "false", + "west": "false" + } + }, + { + "apply": { + "model": "betterend:block/crystal_moss_cover", + "uvlock": true, + "y": 90 + }, + "when": { + "east": "true" + } + }, + { + "apply": { + "model": "betterend:block/crystal_moss_cover", + "uvlock": true, + "y": 90 + }, + "when": { + "down": "false", + "east": "false", + "north": "false", + "south": "false", + "up": "false", + "west": "false" + } + }, + { + "apply": { + "model": "betterend:block/crystal_moss_cover", + "uvlock": true, + "y": 180 + }, + "when": { + "south": "true" + } + }, + { + "apply": { + "model": "betterend:block/crystal_moss_cover", + "uvlock": true, + "y": 180 + }, + "when": { + "down": "false", + "east": "false", + "north": "false", + "south": "false", + "up": "false", + "west": "false" + } + }, + { + "apply": { + "model": "betterend:block/crystal_moss_cover", + "uvlock": true, + "y": 270 + }, + "when": { + "west": "true" + } + }, + { + "apply": { + "model": "betterend:block/crystal_moss_cover", + "uvlock": true, + "y": 270 + }, + "when": { + "down": "false", + "east": "false", + "north": "false", + "south": "false", + "up": "false", + "west": "false" + } + }, + { + "apply": { + "model": "betterend:block/crystal_moss_cover", + "uvlock": true, + "x": 270 + }, + "when": { + "up": "true" + } + }, + { + "apply": { + "model": "betterend:block/crystal_moss_cover", + "uvlock": true, + "x": 270 + }, + "when": { + "down": "false", + "east": "false", + "north": "false", + "south": "false", + "up": "false", + "west": "false" + } + }, + { + "apply": { + "model": "betterend:block/crystal_moss_cover", + "uvlock": true, + "x": 90 + }, + "when": { + "down": "true" + } + }, + { + "apply": { + "model": "betterend:block/crystal_moss_cover", + "uvlock": true, + "x": 90 + }, + "when": { + "down": "false", + "east": "false", + "north": "false", + "south": "false", + "up": "false", + "west": "false" + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/minecraft/blockstates/custom_chorus_flower.json b/src/main/resources/assets/betterend/blockstates/custom_chorus_flower.json similarity index 95% rename from src/main/resources/assets/minecraft/blockstates/custom_chorus_flower.json rename to src/main/resources/assets/betterend/blockstates/custom_chorus_flower.json index fed5be0f..45269fb3 100644 --- a/src/main/resources/assets/minecraft/blockstates/custom_chorus_flower.json +++ b/src/main/resources/assets/betterend/blockstates/custom_chorus_flower.json @@ -1,22 +1,22 @@ -{ - "variants": { - "age=0": { - "model": "betterend:block/chorus_plant_flower" - }, - "age=1": { - "model": "betterend:block/chorus_plant_flower" - }, - "age=2": { - "model": "betterend:block/chorus_plant_flower" - }, - "age=3": { - "model": "betterend:block/chorus_plant_flower" - }, - "age=4": { - "model": "betterend:block/chorus_plant_flower" - }, - "age=5": { - "model": "betterend:block/chorus_plant_flower_open" - } - } +{ + "variants": { + "age=0": { + "model": "betterend:block/chorus_plant_flower" + }, + "age=1": { + "model": "betterend:block/chorus_plant_flower" + }, + "age=2": { + "model": "betterend:block/chorus_plant_flower" + }, + "age=3": { + "model": "betterend:block/chorus_plant_flower" + }, + "age=4": { + "model": "betterend:block/chorus_plant_flower" + }, + "age=5": { + "model": "betterend:block/chorus_plant_flower_open" + } + } } \ No newline at end of file diff --git a/src/main/resources/assets/minecraft/blockstates/custom_chorus_plant.json b/src/main/resources/assets/betterend/blockstates/custom_chorus_plant.json similarity index 92% rename from src/main/resources/assets/minecraft/blockstates/custom_chorus_plant.json rename to src/main/resources/assets/betterend/blockstates/custom_chorus_plant.json index 52268ebc..4db5e7db 100644 --- a/src/main/resources/assets/minecraft/blockstates/custom_chorus_plant.json +++ b/src/main/resources/assets/betterend/blockstates/custom_chorus_plant.json @@ -1,69 +1,65 @@ -{ - "multipart": [ - { - "when": { "OR": [ - {"up": "false"}, - {"down": "false"} - ]}, - "apply": { "model": "betterend:block/chorus_plant_center" } - }, - { - "when": {"roots": "true"}, - "apply": { "model": "betterend:block/chorus_plant_roots" } - }, - { - "when": {"north": "true"}, - "apply": [ - { "model": "betterend:block/chorus_plant_stem", "x": 90, "y": 180 }, - { "model": "betterend:block/chorus_plant_stem_2", "x": 90, "y": 180 }, - { "model": "betterend:block/chorus_plant_stem_3", "x": 90, "y": 180 }, - { "model": "betterend:block/chorus_plant_stem_4", "x": 90, "y": 180 } - ] - }, - { - "when": { "east": "true" }, - "apply": [ - { "model": "betterend:block/chorus_plant_stem", "x": 90, "y": 270 }, - { "model": "betterend:block/chorus_plant_stem_2", "x": 90, "y": 270 }, - { "model": "betterend:block/chorus_plant_stem_3", "x": 90, "y": 270 }, - { "model": "betterend:block/chorus_plant_stem_4", "x": 90, "y": 270 } - ] - }, - { - "when": { "south": "true" }, - "apply": [ - { "model": "betterend:block/chorus_plant_stem", "x": 90 }, - { "model": "betterend:block/chorus_plant_stem_2", "x": 90 }, - { "model": "betterend:block/chorus_plant_stem_3", "x": 90 }, - { "model": "betterend:block/chorus_plant_stem_4", "x": 90 } - ] - }, - { - "when": { "west": "true" }, - "apply": [ - { "model": "betterend:block/chorus_plant_stem", "x": 90, "y": 90 }, - { "model": "betterend:block/chorus_plant_stem_2", "x": 90, "y": 90 }, - { "model": "betterend:block/chorus_plant_stem_3", "x": 90, "y": 90 }, - { "model": "betterend:block/chorus_plant_stem_4", "x": 90, "y": 90 } - ] - }, - { - "when": { "up": "true" }, - "apply": [ - { "model": "betterend:block/chorus_plant_stem", "x": 180 }, - { "model": "betterend:block/chorus_plant_stem_2", "x": 180 }, - { "model": "betterend:block/chorus_plant_stem_3", "x": 180 }, - { "model": "betterend:block/chorus_plant_stem_4", "x": 180 } - ] - }, - { - "when": { "down": "true" }, - "apply": [ - { "model": "betterend:block/chorus_plant_stem" }, - { "model": "betterend:block/chorus_plant_stem_2" }, - { "model": "betterend:block/chorus_plant_stem_3" }, - { "model": "betterend:block/chorus_plant_stem_4" } - ] - } - ] +{ + "multipart": [ + { + "when": { "OR": [ + {"up": "false"}, + {"down": "false"} + ]}, + "apply": { "model": "betterend:block/chorus_plant_center" } + }, + { + "when": {"north": "true"}, + "apply": [ + { "model": "betterend:block/chorus_plant_stem", "x": 90, "y": 180 }, + { "model": "betterend:block/chorus_plant_stem_2", "x": 90, "y": 180 }, + { "model": "betterend:block/chorus_plant_stem_3", "x": 90, "y": 180 }, + { "model": "betterend:block/chorus_plant_stem_4", "x": 90, "y": 180 } + ] + }, + { + "when": { "east": "true" }, + "apply": [ + { "model": "betterend:block/chorus_plant_stem", "x": 90, "y": 270 }, + { "model": "betterend:block/chorus_plant_stem_2", "x": 90, "y": 270 }, + { "model": "betterend:block/chorus_plant_stem_3", "x": 90, "y": 270 }, + { "model": "betterend:block/chorus_plant_stem_4", "x": 90, "y": 270 } + ] + }, + { + "when": { "south": "true" }, + "apply": [ + { "model": "betterend:block/chorus_plant_stem", "x": 90 }, + { "model": "betterend:block/chorus_plant_stem_2", "x": 90 }, + { "model": "betterend:block/chorus_plant_stem_3", "x": 90 }, + { "model": "betterend:block/chorus_plant_stem_4", "x": 90 } + ] + }, + { + "when": { "west": "true" }, + "apply": [ + { "model": "betterend:block/chorus_plant_stem", "x": 90, "y": 90 }, + { "model": "betterend:block/chorus_plant_stem_2", "x": 90, "y": 90 }, + { "model": "betterend:block/chorus_plant_stem_3", "x": 90, "y": 90 }, + { "model": "betterend:block/chorus_plant_stem_4", "x": 90, "y": 90 } + ] + }, + { + "when": { "up": "true" }, + "apply": [ + { "model": "betterend:block/chorus_plant_stem", "x": 180 }, + { "model": "betterend:block/chorus_plant_stem_2", "x": 180 }, + { "model": "betterend:block/chorus_plant_stem_3", "x": 180 }, + { "model": "betterend:block/chorus_plant_stem_4", "x": 180 } + ] + }, + { + "when": { "down": "true" }, + "apply": [ + { "model": "betterend:block/chorus_plant_stem" }, + { "model": "betterend:block/chorus_plant_stem_2" }, + { "model": "betterend:block/chorus_plant_stem_3" }, + { "model": "betterend:block/chorus_plant_stem_4" } + ] + } + ] } \ No newline at end of file diff --git a/src/main/resources/assets/betterend/blockstates/flammalix.json b/src/main/resources/assets/betterend/blockstates/flammalix.json new file mode 100644 index 00000000..9e6c8183 --- /dev/null +++ b/src/main/resources/assets/betterend/blockstates/flammalix.json @@ -0,0 +1,22 @@ +{ + "variants": { + "": [ + { "model": "betterend:block/flammalix_1" }, + { "model": "betterend:block/flammalix_1", "y": 90 }, + { "model": "betterend:block/flammalix_1", "y": 180 }, + { "model": "betterend:block/flammalix_1", "y": 270 }, + { "model": "betterend:block/flammalix_2" }, + { "model": "betterend:block/flammalix_2", "y": 90 }, + { "model": "betterend:block/flammalix_2", "y": 180 }, + { "model": "betterend:block/flammalix_2", "y": 270 }, + { "model": "betterend:block/flammalix_3" }, + { "model": "betterend:block/flammalix_3", "y": 90 }, + { "model": "betterend:block/flammalix_3", "y": 180 }, + { "model": "betterend:block/flammalix_3", "y": 270 }, + { "model": "betterend:block/flammalix_4" }, + { "model": "betterend:block/flammalix_4", "y": 90 }, + { "model": "betterend:block/flammalix_4", "y": 180 }, + { "model": "betterend:block/flammalix_4", "y": 270 } + ] + } +} diff --git a/src/main/resources/assets/betterend/blockstates/smaragdant_crystal.json b/src/main/resources/assets/betterend/blockstates/smaragdant_crystal.json deleted file mode 100644 index 2d3e15ba..00000000 --- a/src/main/resources/assets/betterend/blockstates/smaragdant_crystal.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "axis=x": { "model": "betterend:block/smaragdant_crystal", "x": 90, "y": 90 }, - "axis=y": { "model": "betterend:block/smaragdant_crystal" }, - "axis=z": { "model": "betterend:block/smaragdant_crystal", "x": 90 } - } -} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_bricks_stairs.json b/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_bricks_stairs.json new file mode 100644 index 00000000..61ea29d6 --- /dev/null +++ b/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_bricks_stairs.json @@ -0,0 +1,44 @@ +{ + "variants": { + "facing=east,half=bottom,shape=straight": { "model": "betterend:block/smaragdant_bricks_stairs" }, + "facing=west,half=bottom,shape=straight": { "model": "betterend:block/smaragdant_bricks_stairs", "y": 180 }, + "facing=south,half=bottom,shape=straight": { "model": "betterend:block/smaragdant_bricks_stairs", "y": 90 }, + "facing=north,half=bottom,shape=straight": { "model": "betterend:block/smaragdant_bricks_stairs", "y": 270 }, + "facing=east,half=bottom,shape=outer_right": { "model": "betterend:block/smaragdant_bricks_stairs_outer" }, + "facing=west,half=bottom,shape=outer_right": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "y": 180 }, + "facing=south,half=bottom,shape=outer_right": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "y": 90 }, + "facing=north,half=bottom,shape=outer_right": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "y": 270 }, + "facing=east,half=bottom,shape=outer_left": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "y": 270 }, + "facing=west,half=bottom,shape=outer_left": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "y": 90 }, + "facing=south,half=bottom,shape=outer_left": { "model": "betterend:block/smaragdant_bricks_stairs_outer" }, + "facing=north,half=bottom,shape=outer_left": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "y": 180 }, + "facing=east,half=bottom,shape=inner_right": { "model": "betterend:block/smaragdant_bricks_stairs_inner" }, + "facing=west,half=bottom,shape=inner_right": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "y": 180 }, + "facing=south,half=bottom,shape=inner_right": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "y": 90 }, + "facing=north,half=bottom,shape=inner_right": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "y": 270 }, + "facing=east,half=bottom,shape=inner_left": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "y": 270 }, + "facing=west,half=bottom,shape=inner_left": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "y": 90 }, + "facing=south,half=bottom,shape=inner_left": { "model": "betterend:block/smaragdant_bricks_stairs_inner" }, + "facing=north,half=bottom,shape=inner_left": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "y": 180 }, + "facing=east,half=top,shape=straight": { "model": "betterend:block/smaragdant_bricks_stairs", "x": 180 }, + "facing=west,half=top,shape=straight": { "model": "betterend:block/smaragdant_bricks_stairs", "x": 180, "y": 180 }, + "facing=south,half=top,shape=straight": { "model": "betterend:block/smaragdant_bricks_stairs", "x": 180, "y": 90 }, + "facing=north,half=top,shape=straight": { "model": "betterend:block/smaragdant_bricks_stairs", "x": 180, "y": 270 }, + "facing=east,half=top,shape=outer_right": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "x": 180, "y": 90 }, + "facing=west,half=top,shape=outer_right": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "x": 180, "y": 270 }, + "facing=south,half=top,shape=outer_right": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "x": 180, "y": 180 }, + "facing=north,half=top,shape=outer_right": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "x": 180 }, + "facing=east,half=top,shape=outer_left": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "x": 180 }, + "facing=west,half=top,shape=outer_left": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "x": 180, "y": 180 }, + "facing=south,half=top,shape=outer_left": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "x": 180, "y": 90 }, + "facing=north,half=top,shape=outer_left": { "model": "betterend:block/smaragdant_bricks_stairs_outer", "x": 180, "y": 270 }, + "facing=east,half=top,shape=inner_right": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "x": 180, "y": 90 }, + "facing=west,half=top,shape=inner_right": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "x": 180, "y": 270 }, + "facing=south,half=top,shape=inner_right": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "x": 180, "y": 180 }, + "facing=north,half=top,shape=inner_right": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "x": 180 }, + "facing=east,half=top,shape=inner_left": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "x": 180 }, + "facing=west,half=top,shape=inner_left": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "x": 180, "y": 180 }, + "facing=south,half=top,shape=inner_left": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "x": 180, "y": 90 }, + "facing=north,half=top,shape=inner_left": { "model": "betterend:block/smaragdant_bricks_stairs_inner", "x": 180, "y": 270 } + } +} diff --git a/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_bricks_wall.json b/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_bricks_wall.json new file mode 100644 index 00000000..b68ce3e7 --- /dev/null +++ b/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_bricks_wall.json @@ -0,0 +1,90 @@ +{ + "multipart": [ + { + "when": { + "up": "true" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_bricks_wall_post" + } + }, + { + "when": { + "north": "low" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_bricks_wall_side", + "uvlock": true + } + }, + { + "when": { + "east": "low" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_bricks_wall_side", + "y": 90, + "uvlock": true + } + }, + { + "when": { + "south": "low" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_bricks_wall_side", + "y": 180, + "uvlock": true + } + }, + { + "when": { + "west": "low" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_bricks_wall_side", + "y": 270, + "uvlock": true + } + }, + { + "when": { + "north": "tall" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_bricks_wall_side_tall", + "uvlock": true + } + }, + { + "when": { + "east": "tall" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_bricks_wall_side_tall", + "y": 90, + "uvlock": true + } + }, + { + "when": { + "south": "tall" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_bricks_wall_side_tall", + "y": 180, + "uvlock": true + } + }, + { + "when": { + "west": "tall" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_bricks_wall_side_tall", + "y": 270, + "uvlock": true + } + } + ] +} diff --git a/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_pedestal.json b/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_pedestal.json new file mode 100644 index 00000000..f199dcf1 --- /dev/null +++ b/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_pedestal.json @@ -0,0 +1,22 @@ +{ + "variants": { + "state=default": { + "model": "betterend:block/smaragdant_pedestal_default" + }, + "state=column": { + "model": "betterend:block/smaragdant_pedestal_column" + }, + "state=column_top": { + "model": "betterend:block/smaragdant_pedestal_column_top" + }, + "state=pedestal_top": { + "model": "betterend:block/smaragdant_pedestal_top" + }, + "state=bottom": { + "model": "betterend:block/smaragdant_pedestal_bottom" + }, + "state=pillar": { + "model": "betterend:block/smaragdant_pedestal_pillar" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_slab.json b/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_slab.json new file mode 100644 index 00000000..e944b672 --- /dev/null +++ b/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_slab.json @@ -0,0 +1,15 @@ +{ + "variants": { + "type=bottom": { + "model": "betterend:block/smaragdant_slab" + }, + "type=top": { + "model": "betterend:block/smaragdant_slab", + "x": 180, + "uvlock": true + }, + "type=double": { + "model": "betterend:block/smaragdant_crystal" + } + } +} diff --git a/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_stairs.json b/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_stairs.json new file mode 100644 index 00000000..2d3fc25c --- /dev/null +++ b/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_stairs.json @@ -0,0 +1,44 @@ +{ + "variants": { + "facing=east,half=bottom,shape=straight": { "model": "betterend:block/smaragdant_stairs" }, + "facing=west,half=bottom,shape=straight": { "model": "betterend:block/smaragdant_stairs", "y": 180 }, + "facing=south,half=bottom,shape=straight": { "model": "betterend:block/smaragdant_stairs", "y": 90 }, + "facing=north,half=bottom,shape=straight": { "model": "betterend:block/smaragdant_stairs", "y": 270 }, + "facing=east,half=bottom,shape=outer_right": { "model": "betterend:block/smaragdant_stairs_outer" }, + "facing=west,half=bottom,shape=outer_right": { "model": "betterend:block/smaragdant_stairs_outer", "y": 180 }, + "facing=south,half=bottom,shape=outer_right": { "model": "betterend:block/smaragdant_stairs_outer", "y": 90 }, + "facing=north,half=bottom,shape=outer_right": { "model": "betterend:block/smaragdant_stairs_outer", "y": 270 }, + "facing=east,half=bottom,shape=outer_left": { "model": "betterend:block/smaragdant_stairs_outer", "y": 270 }, + "facing=west,half=bottom,shape=outer_left": { "model": "betterend:block/smaragdant_stairs_outer", "y": 90 }, + "facing=south,half=bottom,shape=outer_left": { "model": "betterend:block/smaragdant_stairs_outer" }, + "facing=north,half=bottom,shape=outer_left": { "model": "betterend:block/smaragdant_stairs_outer", "y": 180 }, + "facing=east,half=bottom,shape=inner_right": { "model": "betterend:block/smaragdant_stairs_inner" }, + "facing=west,half=bottom,shape=inner_right": { "model": "betterend:block/smaragdant_stairs_inner", "y": 180 }, + "facing=south,half=bottom,shape=inner_right": { "model": "betterend:block/smaragdant_stairs_inner", "y": 90 }, + "facing=north,half=bottom,shape=inner_right": { "model": "betterend:block/smaragdant_stairs_inner", "y": 270 }, + "facing=east,half=bottom,shape=inner_left": { "model": "betterend:block/smaragdant_stairs_inner", "y": 270 }, + "facing=west,half=bottom,shape=inner_left": { "model": "betterend:block/smaragdant_stairs_inner", "y": 90 }, + "facing=south,half=bottom,shape=inner_left": { "model": "betterend:block/smaragdant_stairs_inner" }, + "facing=north,half=bottom,shape=inner_left": { "model": "betterend:block/smaragdant_stairs_inner", "y": 180 }, + "facing=east,half=top,shape=straight": { "model": "betterend:block/smaragdant_stairs", "x": 180 }, + "facing=west,half=top,shape=straight": { "model": "betterend:block/smaragdant_stairs", "x": 180, "y": 180 }, + "facing=south,half=top,shape=straight": { "model": "betterend:block/smaragdant_stairs", "x": 180, "y": 90 }, + "facing=north,half=top,shape=straight": { "model": "betterend:block/smaragdant_stairs", "x": 180, "y": 270 }, + "facing=east,half=top,shape=outer_right": { "model": "betterend:block/smaragdant_stairs_outer", "x": 180, "y": 90 }, + "facing=west,half=top,shape=outer_right": { "model": "betterend:block/smaragdant_stairs_outer", "x": 180, "y": 270 }, + "facing=south,half=top,shape=outer_right": { "model": "betterend:block/smaragdant_stairs_outer", "x": 180, "y": 180 }, + "facing=north,half=top,shape=outer_right": { "model": "betterend:block/smaragdant_stairs_outer", "x": 180 }, + "facing=east,half=top,shape=outer_left": { "model": "betterend:block/smaragdant_stairs_outer", "x": 180 }, + "facing=west,half=top,shape=outer_left": { "model": "betterend:block/smaragdant_stairs_outer", "x": 180, "y": 180 }, + "facing=south,half=top,shape=outer_left": { "model": "betterend:block/smaragdant_stairs_outer", "x": 180, "y": 90 }, + "facing=north,half=top,shape=outer_left": { "model": "betterend:block/smaragdant_stairs_outer", "x": 180, "y": 270 }, + "facing=east,half=top,shape=inner_right": { "model": "betterend:block/smaragdant_stairs_inner", "x": 180, "y": 90 }, + "facing=west,half=top,shape=inner_right": { "model": "betterend:block/smaragdant_stairs_inner", "x": 180, "y": 270 }, + "facing=south,half=top,shape=inner_right": { "model": "betterend:block/smaragdant_stairs_inner", "x": 180, "y": 180 }, + "facing=north,half=top,shape=inner_right": { "model": "betterend:block/smaragdant_stairs_inner", "x": 180 }, + "facing=east,half=top,shape=inner_left": { "model": "betterend:block/smaragdant_stairs_inner", "x": 180 }, + "facing=west,half=top,shape=inner_left": { "model": "betterend:block/smaragdant_stairs_inner", "x": 180, "y": 180 }, + "facing=south,half=top,shape=inner_left": { "model": "betterend:block/smaragdant_stairs_inner", "x": 180, "y": 90 }, + "facing=north,half=top,shape=inner_left": { "model": "betterend:block/smaragdant_stairs_inner", "x": 180, "y": 270 } + } +} diff --git a/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_wall.json b/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_wall.json new file mode 100644 index 00000000..3232369d --- /dev/null +++ b/src/main/resources/assets/betterend/blockstates/smaragdant_crystal_wall.json @@ -0,0 +1,90 @@ +{ + "multipart": [ + { + "when": { + "up": "true" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_wall_post" + } + }, + { + "when": { + "north": "low" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_wall_side", + "uvlock": true + } + }, + { + "when": { + "east": "low" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_wall_side", + "y": 90, + "uvlock": true + } + }, + { + "when": { + "south": "low" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_wall_side", + "y": 180, + "uvlock": true + } + }, + { + "when": { + "west": "low" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_wall_side", + "y": 270, + "uvlock": true + } + }, + { + "when": { + "north": "tall" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_wall_side_tall", + "uvlock": true + } + }, + { + "when": { + "east": "tall" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_wall_side_tall", + "y": 90, + "uvlock": true + } + }, + { + "when": { + "south": "tall" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_wall_side_tall", + "y": 180, + "uvlock": true + } + }, + { + "when": { + "west": "tall" + }, + "apply": { + "model": "betterend:block/smaragdant_crystal_wall_side_tall", + "y": 270, + "uvlock": true + } + } + ] +} diff --git a/src/main/resources/assets/betterend/blockstates/umbralith.json b/src/main/resources/assets/betterend/blockstates/umbralith.json new file mode 100644 index 00000000..98e6b27a --- /dev/null +++ b/src/main/resources/assets/betterend/blockstates/umbralith.json @@ -0,0 +1,13 @@ +{ + "variants": { + "": [ + { "model": "betterend:block/umbralith_1", "weight": 10 }, + { "model": "betterend:block/umbralith_2", "weight": 10 }, + { "model": "betterend:block/umbralith_6", "weight": 10 }, + { "model": "betterend:block/umbralith_7", "weight": 10 }, + { "model": "betterend:block/umbralith_3", "weight": 1 }, + { "model": "betterend:block/umbralith_4", "weight": 1 }, + { "model": "betterend:block/umbralith_5", "weight": 1 } + ] + } +} diff --git a/src/main/resources/assets/betterend/icon.png b/src/main/resources/assets/betterend/icon.png index 95bc2e64..408be2ca 100644 Binary files a/src/main/resources/assets/betterend/icon.png and b/src/main/resources/assets/betterend/icon.png differ diff --git a/src/main/resources/assets/betterend/icon_updater.png b/src/main/resources/assets/betterend/icon_updater.png new file mode 100644 index 00000000..8f696087 Binary files /dev/null and b/src/main/resources/assets/betterend/icon_updater.png differ diff --git a/src/main/resources/assets/betterend/lang/de_de.json b/src/main/resources/assets/betterend/lang/de_de.json index 7341d5c0..237da7d9 100644 --- a/src/main/resources/assets/betterend/lang/de_de.json +++ b/src/main/resources/assets/betterend/lang/de_de.json @@ -1,698 +1,660 @@ { - "itemGroup.betterend.end_items": "Better End: Items", - "itemGroup.betterend.end_blocks": "Better End: Blöcke", - - "item.betterend.guidebook": "Das Ende für Idioten", - "book.betterend.landing": "Eine kurze Anleitung zum Überleben unter den extremen Bedingungen im End.", - "book.betterend.subtitle": "Überlebe im End", - - "category.rei.damage.amount&dmg": "Werkzeugschaden: %s", - "category.rei.infusion.time&val": "Zeit: %s", - - "biome.betterend.foggy_mushroomland": "Nebeliges Pilzland", - "biome.betterend.dust_wastelands": "Staubiges Ödland", - "biome.betterend.chorus_forest": "Choruswald", - "biome.betterend.megalake": "Riesensee", - "biome.betterend.crystal_mountains": "Kristallberge", - - "entity.betterend.dragonfly": "Libelle", - "item.betterend.spawn_egg_dragonfly": "Libellen-Spawn-Ei", - - "entity.betterend.end_slime": "Endschleim", - "item.betterend.spawn_egg_end_slime": "Endschleim-Spawn-Ei", - - "block.betterend.end_mycelium": "End-Myzel", - "block.betterend.end_moss": "End-Moos", - "block.betterend.endstone_dust": "Endsteinstaub", - - "block.betterend.end_mycelium_path": "End-Myzelpfad", - "block.betterend.end_moss_path": "End-Moospfad", - - "block.betterend.ender_ore": "Endererz", - "block.betterend.terminite_block": "Terminitblock", - "block.betterend.aeternium_block": "Ätherblock", - "block.betterend.ender_block": "Enderblock", - "block.betterend.end_stone_smelter": "Endsteinschmelzofen", - - "item.betterend.ender_dust": "Enderstaub", - "item.betterend.ender_shard": "Enderscherbe", - "item.betterend.terminite_ingot": "Terminitbarren", - "item.betterend.aeternium_ingot": "Ätherbarren", - "item.betterend.terminite_helmet": "Terminithelm", - "item.betterend.terminite_chestplate": "Terminitharnisch", - "item.betterend.terminite_leggings": "Terminitbeinschutz", - "item.betterend.terminite_boots": "Terminitstiefel", - "item.betterend.terminite_shovel": "Terminitschaufel", - "item.betterend.terminite_sword": "Terminitschwert", - "item.betterend.terminite_pickaxe": "Terminitspitzhacke", - "item.betterend.terminite_axe": "Terminitaxt", - "item.betterend.terminite_hoe": "Terminithacke", - "item.betterend.terminite_hammer": "Terminitschmiedehammer", - "item.betterend.aeternium_helmet": "Ätherhelm", - "item.betterend.aeternium_chestplate": "Ätherharnisch", - "item.betterend.aeternium_leggings": "Ätherbeinschutz", - "item.betterend.aeternium_boots": "Ätherstiefel", - "item.betterend.aeternium_shovel": "Ätherschaufel", - "item.betterend.aeternium_sword": "Ätherschwert", - "item.betterend.aeternium_pickaxe": "Ätherspitzhacke", - "item.betterend.aeternium_axe": "Ätheraxt", - "item.betterend.aeternium_hoe": "Ätherhacke", - "item.betterend.aeternium_hammer": "Ätherschmiedehammer", - "item.betterend.iron_hammer": "Eisenschmiedehammer", - "item.betterend.golden_hammer": "Goldschmiedehammer", - "item.betterend.diamond_hammer": "Diamantschmiedehammer", - "item.betterend.netherite_hammer": "Netheritschmiedehammer", - "item.betterend.crystalite_boots": "Kristallitstiefel", - "item.betterend.crystalite_chestplate": "Kristallitharnisch", - "item.betterend.crystalite_helmet": "Kristallithelm", - "item.betterend.crystalite_leggings": "Kristallitbeinschutz", - "item.betterend.aeternium_axe_head": "Ätheraxtkopf", - "item.betterend.aeternium_hammer_head": "Ätherhammerkopf", - "item.betterend.aeternium_hoe_head": "Ätherhackenkopf", - "item.betterend.aeternium_pickaxe_head": "Ätherspitzhackenkopf", - "item.betterend.aeternium_shovel_head": "Ätherschaufelkopf", - "item.betterend.aeternium_sword_blade": "Ätherschwertklinge", - "item.betterend.aeternium_sword_handle": "Ätherschwertgriff", - "item.betterend.leather_stripe": "Lederband", - "item.betterend.leather_wrapped_stick": "Leder-umwickelter Stock", - - "effect.betterend.end_veil": "Endschleier", - "enchantment.betterend.end_veil": "Endschleier", - "item.minecraft.potion.effect.end_veil": "Trank des Endschleiers", - "item.minecraft.potion.effect.long_end_veil": "Trank des Endschleiers", - "item.minecraft.splash_potion.effect.end_veil": "Wurftrank des Endschleiers", - "item.minecraft.splash_potion.effect.long_end_veil": "Wurftrank des Endschleiers", - "item.minecraft.lingering_potion.effect.end_veil": "Verweiltrank des Endschleiers", - "item.minecraft.lingering_potion.effect.long_end_veil": "Verweiltrank des Endschleiers", - "item.minecraft.tipped_arrow.effect.end_veil": "Pfeil des Endschleiers", - "item.minecraft.tipped_arrow.effect.long_end_veil": "Pfeil des Endschleiers", - - "block.betterend.mossy_glowshroom_sapling": "Bemooster Glühpilzsetzling", - "block.betterend.mossy_glowshroom_cap": "Bemooste Glühpilzkappe", - "block.betterend.mossy_glowshroom_fur": "Bemoostes Glühpilzfell", - "block.betterend.mossy_glowshroom_hymenophore": "Bemoostes Glühpilzhymenophor", - "block.betterend.mossy_glowshroom_bark": "Bemoostes Glühpilzholz", - "block.betterend.mossy_glowshroom_barrel": "Bemoostes Glühpilzfass", - "block.betterend.mossy_glowshroom_button": "Bemooster Glühpilzknopf", - "block.betterend.mossy_glowshroom_chest": "Bemooste Glühpilztruhe", - "block.betterend.mossy_glowshroom_crafting_table": "Bemooste Glühpilzwerkbank", - "block.betterend.mossy_glowshroom_door": "Bemooste Glühpilztür", - "block.betterend.mossy_glowshroom_fence": "Bemooster Glühpilzzaun", - "block.betterend.mossy_glowshroom_gate": "Bemoostes Glühpilzzauntor", - "block.betterend.mossy_glowshroom_ladder": "Bemooste Glühpilzleiter", - "block.betterend.mossy_glowshroom_log": "Bemooster Glühpilzstamm", - "block.betterend.mossy_glowshroom_planks": "Bemooste Glühpilzbretter", - "block.betterend.mossy_glowshroom_plate": "Bemooste Glühpilzdruckplatte", - "block.betterend.mossy_glowshroom_sign": "Bemoostes Glühpilzschild", - "block.betterend.mossy_glowshroom_slab": "Bemooste Glühpilzstufe", - "block.betterend.mossy_glowshroom_stairs": "Bemooste Glühpilztreppe", - "block.betterend.mossy_glowshroom_stripped_bark": "Entrindetes bemoostes Glühpilzholz", - "block.betterend.mossy_glowshroom_stripped_log": "Entrindeter bemooster Glühpilzstamm", - "block.betterend.mossy_glowshroom_trapdoor": "Bemooste Glühpilzfalltür", - - "block.betterend.umbrella_moss": "Schirmmoos", - "block.betterend.umbrella_moss_tall": "Großes Schirmmoos", - "block.betterend.creeping_moss": "Kriechendes Moos", - - "block.betterend.blue_vine_seed": "Blaurankensamen", - "block.betterend.blue_vine": "Blauranke", - "block.betterend.blue_vine_lantern": "Blaurankenlaterne", - "block.betterend.blue_vine_fur": "Blaurankenfell", - - "block.betterend.dense_vine": "Dichte Ranke", - "block.betterend.bubble_coral": "Blasenkoralle", - "block.betterend.aurora_crystal": "Aurorakristall", - "item.betterend.crystal_shards": "Kristallscherben", - - "block.betterend.pythadendron_sapling": "Pythadendronsetzling", - "block.betterend.pythadendron_bark": "Pythadendronholz", - "block.betterend.pythadendron_barrel": "Pythadendronfass", - "block.betterend.pythadendron_button": "Pythadendronknopf", - "block.betterend.pythadendron_chest": "Pythadendrontruhe", - "block.betterend.pythadendron_crafting_table": "Pythadendronwerkbank", - "block.betterend.pythadendron_door": "Pythadendrontür", - "block.betterend.pythadendron_fence": "Pythadendronzaun", - "block.betterend.pythadendron_gate": "Pythadendronzauntor", - "block.betterend.pythadendron_ladder": "Pythadendronleiter", - "block.betterend.pythadendron_log": "Pythadendronstamm", - "block.betterend.pythadendron_planks": "Pythadendronbretter", - "block.betterend.pythadendron_plate": "Pythadendrondruckplatte", - "block.betterend.pythadendron_sign": "Pythadendronschild", - "block.betterend.pythadendron_slab": "Pythadendronstufe", - "block.betterend.pythadendron_stairs": "Pythadendrontreppe", - "block.betterend.pythadendron_stripped_bark": "Entrindetes Pythadendronholz", - "block.betterend.pythadendron_stripped_log": "Entrindeter Pythadendronstamm", - "block.betterend.pythadendron_trapdoor": "Pythadendronfalltür", - - "block.betterend.chorus_nylium": "Chorus-Nezel", - "block.betterend.chorus_nylium_path": "Chorus-Nezelpfad", - "block.betterend.chorus_grass": "Chorusgras", - - "block.betterend.end_lily": "Endlilie", - "block.betterend.end_lily_seed": "Endliliensamen", - "item.betterend.end_lily_leaf": "Endlilienblatt", - "item.betterend.end_lily_leaf_dried": "Trockenes Endlilienblatt", - - "block.betterend.violecite": "Violezit", - "block.betterend.violecite_bricks": "Violezitziegel", - "block.betterend.violecite_bricks_slab": "Violezitziegelstufe", - "block.betterend.violecite_bricks_stairs": "Violezitziegeltreppe", - "block.betterend.violecite_bricks_wall": "Violezitziegelmauer", - "block.betterend.violecite_button": "Violezitknopf", - "block.betterend.violecite_pillar": "Violezitsäule", - "block.betterend.violecite_plate": "Violezitdruckplatte", - "block.betterend.violecite_slab": "Violezitstufe", - "block.betterend.violecite_tiles": "Violezitfliesen", - "block.betterend.violecite_stairs": "Violezittreppe", - "block.betterend.violecite_polished": "Polierter Violezit", - "block.betterend.violecite_wall": "Violezitmauer", - "block.betterend.violecite_pedestal": "Violezitsockel", - - "block.betterend.flavolite": "Flavolit", - "block.betterend.flavolite_bricks": "Flavolitziegel", - "block.betterend.flavolite_bricks_slab": "Flavolitziegelstufe", - "block.betterend.flavolite_bricks_stairs": "Flavolitziegeltreppe", - "block.betterend.flavolite_bricks_wall": "Flavolitziegelmauer", - "block.betterend.flavolite_button": "Flavolitknopf", - "block.betterend.flavolite_pillar": "Flavolitsäule", - "block.betterend.flavolite_plate": "Flavolitdruckplatte", - "block.betterend.flavolite_slab": "Flavolitstufe", - "block.betterend.flavolite_tiles": "Flavolitfliesen", - "block.betterend.flavolite_stairs": "Flavolittreppe", - "block.betterend.flavolite_polished": "Polierter Flavolit", - "block.betterend.flavolite_wall": "Flavolitmauer", - "block.betterend.flavolite_pedestal": "Flavolitsockel", - - "block.betterend.andesite_pedestal": "Andesitsockel", - "block.betterend.diorite_pedestal": "Dioritsockel", - "block.betterend.granite_pedestal": "Granitsockel", - "block.betterend.purpur_pedestal": "Purpursockel", - "block.betterend.quartz_pedestal": "Quarzsockel", - "block.betterend.infusion_pedestal": "Infusionssockel", - - "block.betterend.end_lotus_seed": "Endlotussamen", - "block.betterend.end_lotus_stem": "Endlotusstamm", - "block.betterend.end_lotus_leaf": "Endlotusblatt", - "block.betterend.end_lotus_flower": "Endlotusblume", - - "block.betterend.end_lotus_bark": "Endlotusholz", - "block.betterend.end_lotus_barrel": "Endlotusfass", - "block.betterend.end_lotus_button": "Endlotusknopf", - "block.betterend.end_lotus_chest": "Endlotustruhe", - "block.betterend.end_lotus_crafting_table": "Endlotuswerkbank", - "block.betterend.end_lotus_door": "Endlotustür", - "block.betterend.end_lotus_fence": "Endlotuszaun", - "block.betterend.end_lotus_gate": "Endlotuszauntor", - "block.betterend.end_lotus_ladder": "Endlotusleiter", - "block.betterend.end_lotus_log": "Endlotusstamm", - "block.betterend.end_lotus_planks": "Endlotusbretter", - "block.betterend.end_lotus_plate": "Endlotusdruckplatte", - "block.betterend.end_lotus_sign": "Endlotusschild", - "block.betterend.end_lotus_slab": "Endlotusstufe", - "block.betterend.end_lotus_stairs": "Endlotustreppe", - "block.betterend.end_lotus_stripped_bark": "Entrindetes Endlotusholz", - "block.betterend.end_lotus_stripped_log": "Entrindeter Endlotusstamm", - "block.betterend.end_lotus_trapdoor": "Endlotusfalltür", - - "block.betterend.cave_moss": "Höhlenmoos", - "block.betterend.cave_grass": "Höhlengras", - "block.betterend.cave_bush": "Höhlenbusch", - - "block.betterend.cave_moss_path": "Höhlenmoospfad", - "block.betterend.crystal_moss": "Kristallmoos", - "block.betterend.crystal_moss_path": "Kristallmoospfad", - "block.betterend.pythadendron_leaves": "Pythadendronlaub", - "item.betterend.spawn_egg_end_fish": "Endfisch-Spawn-Ei", - "block.betterend.crystal_grass": "Kristallgras", - - "block.betterend.flavolite_runed": "Flavolitrune", - "block.betterend.end_portal_block": "Endportal", - "block.betterend.eternal_pedestal": "Ewiges Sockel", - "block.betterend.flavolite_runed_eternal": "Ewige Flavolitrune", - "item.betterend.eternal_crystal": "Ewiger Kristall", - - "block.betterend.lacugrove_bark": "Seemangrovenholz", - "block.betterend.lacugrove_barrel": "Seemangrovenfass", - "block.betterend.lacugrove_button": "Seemangrovenknopf", - "block.betterend.lacugrove_chest": "Seemangroventruhe", - "block.betterend.lacugrove_crafting_table": "Seemangrovenwerkbank", - "block.betterend.lacugrove_door": "Seemangroventür", - "block.betterend.lacugrove_fence": "Seemangrovenzaun", - "block.betterend.lacugrove_gate": "Seemangrovenzauntor", - "block.betterend.lacugrove_ladder": "Seemangrovenleiter", - "block.betterend.lacugrove_log": "Seemangrovenstamm", - "block.betterend.lacugrove_planks": "Seemangrovenbretter", - "block.betterend.lacugrove_plate": "Seemangrovendruckplatte", - "block.betterend.lacugrove_sign": "Seemangrovenschild", - "block.betterend.lacugrove_slab": "Seemangrovenstufe", - "block.betterend.lacugrove_stairs": "Seemangroventreppe", - "block.betterend.lacugrove_stripped_bark": "Entrindetes Seemangrovenholz", - "block.betterend.lacugrove_stripped_log": "Entrindeter Seemangrovenstamm", - "block.betterend.lacugrove_trapdoor": "Seemangrovenfalltür", - - "block.betterend.lacugrove_leaves": "Seemangrovenlaub", - "block.betterend.lacugrove_sapling": "Seemangrovensetzling", - - "biome.betterend.megalake_grove": "Riesenseemangrove", - "biome.betterend.painted_mountains": "Bemalte Berge", - - "block.betterend.dragon_tree_bark": "Drachenbaumholz", - "block.betterend.dragon_tree_barrel": "Drachenbaumfass", - "block.betterend.dragon_tree_button": "Drachenbaumknopf", - "block.betterend.dragon_tree_chest": "Drachenbaumtruhe", - "block.betterend.dragon_tree_crafting_table": "Drachenbaumwerkbank", - "block.betterend.dragon_tree_door": "Drachenbaumtür", - "block.betterend.dragon_tree_fence": "Drachenbaumzaun", - "block.betterend.dragon_tree_gate": "Drachenbaumzauntor", - "block.betterend.dragon_tree_ladder": "Drachenbaumleiter", - "block.betterend.dragon_tree_log": "Drachenbaumstamm", - "block.betterend.dragon_tree_planks": "Drachenbaumbretter", - "block.betterend.dragon_tree_plate": "Drachenbaumdruckplatte", - "block.betterend.dragon_tree_sign": "Drachenbaumschild", - "block.betterend.dragon_tree_slab": "Drachenbaumstufe", - "block.betterend.dragon_tree_stairs": "Drachenbaumtreppe", - "block.betterend.dragon_tree_stripped_bark": "Entrindetes Drachenbaumholz", - "block.betterend.dragon_tree_stripped_log": "Entrindeter Drachenbaumstamm", - "block.betterend.dragon_tree_trapdoor": "Drachenbaumfalltür", - - "biome.betterend.shadow_forest": "Schattenwald", - "block.betterend.dragon_tree_leaves": "Drachenbaumlaub", - "block.betterend.dragon_tree_sapling": "Drachenbaumsetzling", - "block.betterend.shadow_grass": "Schattengras", - "block.betterend.shadow_grass_path": "Schattengraspfad", - "block.betterend.shadow_plant": "Schattenpflanze", - - "block.betterend.dragon_tree_bookshelf": "Drachenbaumbücherregal", - "block.betterend.end_lotus_bookshelf": "Endlotusbücherregal", - "block.betterend.lacugrove_bookshelf": "Seemangrovenbücherregal", - "block.betterend.mossy_glowshroom_bookshelf": "Bemoostes Glühpilzbücherregal", - "block.betterend.pythadendron_bookshelf": "Pythadendronbücherregal", - - "block.betterend.murkweed": "Trübkraut", - "block.betterend.needlegrass": "Nadelgras", - "block.betterend.twisted_vine": "Zwirbelranke", - - "block.betterend.shadow_berry": "Schattenbeersamen", - "item.betterend.shadow_berry_cooked": "Gebratene Schattenbeere", - "item.betterend.shadow_berry_raw": "Schattenbeere", - "block.betterend.purple_polypore": "Violetter Porling", - - "block.betterend.cyan_moss": "Türkises Moos", - "block.betterend.tail_moss": "Schweifmoos", - - "block.betterend.flavolite_lantern": "Flavolitlaterne", - "block.betterend.end_stone_lantern": "Endsteinlaterne", - "block.betterend.violecite_lantern": "Violezitlaterne", - - "entity.betterend.end_fish": "Endfisch", - "entity.betterend.shadow_walker": "Schattenwanderer", - "item.betterend.spawn_egg_shadow_walker": "Schattenwanderer-Spawn-Ei", - - "block.betterend.andesite_lantern": "Andesitlaterne", - "block.betterend.blackstone_lantern": "Schwarzsteinlaterne", - "block.betterend.diorite_lantern": "Dioritlaterne", - "block.betterend.granite_lantern": "Granitlaterne", - "block.betterend.purpur_lantern": "Purpurlaterne", - "block.betterend.quartz_lantern": "Quarzlaterne", - - "item.betterend.bucket_end_fish": "Endfischeimer", - "item.betterend.end_fish_cooked": "Gebratener Endfisch", - "item.betterend.end_fish_raw": "Endfisch", - - "biome.betterend.amber_land": "Bernsteinland", - "biome.betterend.blossoming_spires": "Blühende Türme", - "block.betterend.amber_grass": "Bernsteingras", - "block.betterend.amber_grass_path": "Bernsteingraspfad", - "block.betterend.tenanea_bark": "Tenaneaholz", - "block.betterend.tenanea_barrel": "Tenaneafass", - "block.betterend.tenanea_bookshelf": "Tenaneabücherregal", - "block.betterend.tenanea_button": "Tenaneaknopf", - "block.betterend.tenanea_chest": "Tenaneatruhe", - "block.betterend.tenanea_crafting_table": "Tenaneawerkbank", - "block.betterend.tenanea_door": "Tenaneatür", - "block.betterend.tenanea_fence": "Tenaneazaun", - "block.betterend.tenanea_gate": "Tenaneazauntor", - "block.betterend.tenanea_ladder": "Tenanealeiter", - "block.betterend.tenanea_leaves": "Tenanealaub", - "block.betterend.tenanea_log": "Tenaneastamm", - "block.betterend.tenanea_planks": "Tenaneabretter", - "block.betterend.tenanea_plate": "Tenaneadruckplatte", - "block.betterend.tenanea_sapling": "Tenaneasetzling", - "block.betterend.tenanea_sign": "Tenaneaschild", - "block.betterend.tenanea_slab": "Tenaneastufe", - "block.betterend.tenanea_stairs": "Tenaneatreppe", - "block.betterend.tenanea_stripped_bark": "Entrindetes Tenaneaholz", - "block.betterend.tenanea_stripped_log": "Entrindeter Tenaneastamm", - "block.betterend.tenanea_trapdoor": "Tenaneafalltür", - - "block.betterend.amber_block": "Bernsteinblock", - "block.betterend.amber_ore": "Bernsteinerz", - "item.betterend.amber_gem": "Bernsteinjuwel", - "item.betterend.raw_amber": "Roher Bernstein", - "block.betterend.tenanea_flowers": "Tenaneablumen", - "block.betterend.tenanea_outer_leaves": "Äußeres Tenanealaub", - - "block.betterend.pink_moss": "Pinkes Moos", - "block.betterend.pink_moss_path": "Pinker Moospfad", - - "block.betterend.twisted_moss": "Zwirbelmoos", - - "block.betterend.bulb_vine": "Knollenranke", - "block.betterend.bulb_vine_seed": "Knollenrankensamen", - "item.betterend.glowing_bulb": "Glühende Knolle", - - "block.betterend.iron_bulb_lantern": "Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_black": "Schwarze Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_blue": "Blaue Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_brown": "Braune Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_cyan": "Türkise Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_gray": "Graue Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_green": "Grüne Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_light_blue": "Hellblaue Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_light_gray": "Hellgraue Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_lime": "Hellgrüne Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_magenta": "Magenta Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_orange": "Orangene Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_pink": "Pinke Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_purple": "Violette Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_red": "Rote Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_white": "Weiße Eisenknollenlaterne", - "block.betterend.iron_bulb_lantern_yellow": "Gelbe Eisenknollenlaterne", - - "block.betterend.gold_bulb_lantern": "Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_black": "Schwarze Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_blue": "Blaue Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_brown": "Braune Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_cyan": "Türkise Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_gray": "Graue Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_green": "Grüne Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_light_blue": "Hellblaue Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_light_gray": "Hellgraue Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_lime": "Hellgrüne Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_magenta": "Magenta Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_orange": "Orangene Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_pink": "Pinke Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_purple": "Violette Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_red": "Rote Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_white": "Weiße Goldknollenlaterne", - "block.betterend.gold_bulb_lantern_yellow": "Gelbe Goldknollenlaterne", - - "block.betterend.thallasium_bulb_lantern": "Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_black": "Schwarze Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_blue": "Blaue Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_brown": "Braune Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_cyan": "Türkise Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_gray": "Graue Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_green": "Grüne Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_light_blue": "Hellblaue Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_light_gray": "Hellgraue Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_lime": "Hellgrüne Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_magenta": "Magenta Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_orange": "Orangene Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_pink": "Pinke Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_purple": "Violette Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_red": "Rote Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_white": "Weiße Thallasiumknollenlaterne", - "block.betterend.thallasium_bulb_lantern_yellow": "Gelbe Thallasiumknollenlaterne", - - "block.betterend.bushy_grass": "Buschiges Gras", - - "block.betterend.brimstone": "Schwefelrandstein", - "block.betterend.sulphuric_rock": "Schwefelgestein", - "block.betterend.sulphuric_rock_bricks": "Schwefelsteinziegel", - "block.betterend.sulphuric_rock_bricks_slab": "Schwefelsteinziegelstufe", - "block.betterend.sulphuric_rock_bricks_stairs": "Schwefelsteinziegeltreppe", - "block.betterend.sulphuric_rock_bricks_wall": "Schwefelsteinziegelmauer", - "block.betterend.sulphuric_rock_button": "Schwefelsteinknopf", - "block.betterend.sulphuric_rock_lantern": "Schwefelsteinlaterne", - "block.betterend.sulphuric_rock_pedestal": "Schwefelsteinsockel", - "block.betterend.sulphuric_rock_pillar": "Schwefelsteinsäule", - "block.betterend.sulphuric_rock_plate": "Schwefelsteindruckplatte", - "block.betterend.sulphuric_rock_polished": "Poliertes Schwefelgestein", - "block.betterend.sulphuric_rock_slab": "Schwefelsteinstufe", - "block.betterend.sulphuric_rock_stairs": "Schwefelsteintreppe", - "block.betterend.sulphuric_rock_tiles": "Schwefelsteinfliesen", - "block.betterend.sulphuric_rock_wall": "Schwefelsteinmauer", - "block.betterend.sulphur_crystal": "Schwefelkristall", - "item.betterend.crystalline_sulphur": "Schwefel", - - "biome.betterend.sulphur_springs": "Schwefelquellen", - "block.betterend.hydralux_petal_block": "Hydraluxblüttenblattblock", - "block.betterend.hydralux_petal_block_black": "Schwarzer Blüttenblattblock", - "block.betterend.hydralux_petal_block_blue": "Blauer Blüttenblattblock", - "block.betterend.hydralux_petal_block_brown": "Brauner Blüttenblattblock", - "block.betterend.hydralux_petal_block_cyan": "Türkiser Blüttenblattblock", - "block.betterend.hydralux_petal_block_gray": "Grauer Blüttenblattblock", - "block.betterend.hydralux_petal_block_green": "Grüner Blüttenblattblock", - "block.betterend.hydralux_petal_block_light_blue": "Hellblauer Blüttenblattblock", - "block.betterend.hydralux_petal_block_light_gray": "Hellgrauer Blüttenblattblock", - "block.betterend.hydralux_petal_block_lime": "Hellgrüner Blüttenblattblock", - "block.betterend.hydralux_petal_block_magenta": "Magenta Blüttenblattblock", - "block.betterend.hydralux_petal_block_orange": "Orangener Blüttenblattblock", - "block.betterend.hydralux_petal_block_pink": "Pinker Blüttenblattblock", - "block.betterend.hydralux_petal_block_purple": "Violetter Blüttenblattblock", - "block.betterend.hydralux_petal_block_red": "Roter Blüttenblattblock", - "block.betterend.hydralux_petal_block_white": "Weißer Blüttenblattblock", - "block.betterend.hydralux_petal_block_yellow": "Gelber Blüttenblattblock", - "block.betterend.hydralux_sapling": "Hydraluxsetzling", - "block.betterend.hydrothermal_vent": "Hydrothermalquelle", - "item.betterend.hydralux_petal": "Hydraluxblütenblatt", - "item.betterend.enchanted_petal": "Verzaubertes Blütenblatt", - - "block.betterend.menger_sponge": "Mengerschwamm", - "block.betterend.menger_sponge_wet": "Nasser Mengerschwamm", - "block.betterend.tube_worm": "Röhrenwurm", - - "block.betterend.charnia_cyan": "Türkises Charnia", - "block.betterend.charnia_light_blue": "Hellblaues Charnia", - "block.betterend.charnia_orange": "Orangenes Charnia", - "block.betterend.charnia_purple": "Violettes Charnia", - "block.betterend.charnia_red": "Rotes Charnia", - - "entity.betterend.cubozoa": "Cubozoa", - "item.betterend.spawn_egg_cubozoa": "Cubozoa-Spawn-Ei", - - "item.betterend.gelatine": "Gelatine", - "item.betterend.sweet_berry_jelly": "Süßbeerengelee", - "item.betterend.shadow_berry_jelly": "Schwarzbeerengelee", - - "block.betterend.amber_moss": "Bernsteinmoos", - "block.betterend.amber_moss_path": "Bernsteinmoospfad", - "block.betterend.helix_tree_bark": "Spiralbaumholz", - "block.betterend.helix_tree_barrel": "Spiralbaumfass", - "block.betterend.helix_tree_bookshelf": "Spiralbaumbücherregal", - "block.betterend.helix_tree_button": "Spiralbaumknopf", - "block.betterend.helix_tree_chest": "Spiralbaumtruhe", - "block.betterend.helix_tree_crafting_table": "Spiralbaumwerkbank", - "block.betterend.helix_tree_door": "Spiralbaumtür", - "block.betterend.helix_tree_fence": "Spiralbaumzaun", - "block.betterend.helix_tree_gate": "Spiralbaumzauntor", - "block.betterend.helix_tree_ladder": "Spiralbaumleiter", - "block.betterend.helix_tree_leaves": "Spiralbaumlaub", - "block.betterend.helix_tree_log": "Spiralbaumstamm", - "block.betterend.helix_tree_planks": "Spiralbaumbretter", - "block.betterend.helix_tree_plate": "Spiralbaumdruckplatte", - "block.betterend.helix_tree_sapling": "Spiralbaumsetzling", - "block.betterend.helix_tree_sign": "Spiralbaumschild", - "block.betterend.helix_tree_slab": "Spiralbaumstufe", - "block.betterend.helix_tree_stairs": "Spiralbaumtreppe", - "block.betterend.helix_tree_stripped_bark": "Entrindetes Spiralbaumholz", - "block.betterend.helix_tree_stripped_log": "Entrindeter Spiralbaumstamm", - "block.betterend.helix_tree_trapdoor": "Spiralbaumfalltür", - "block.betterend.lanceleaf": "Lanzenblatt", - "block.betterend.lanceleaf_seed": "Lanzenblattsamen", - "block.betterend.hydralux": "Hydralux", - "block.betterend.helix_tree_luminophor": "Spiralbaumluminophor", - - "block.betterend.glowing_pillar_leaves": "Glühsäulenlaub", - "block.betterend.glowing_pillar_luminophor": "Glühsäulenluminophor", - "block.betterend.glowing_pillar_roots": "Glühsäulenwurzeln", - "block.betterend.glowing_pillar_seed": "Glühsäulensamen", - - "biome.betterend.ice_starfield": "Eissternfeld", - - "block.betterend.ancient_emerald_ice": "Antikes Smaragdeis", - "block.betterend.dense_emerald_ice": "Dichtes Smaragdeis", - "block.betterend.dense_snow": "Dichter Schnee", - "block.betterend.emerald_ice": "Smaragdeis", - - "block.betterend.bulb_moss": "Knollenmoos", - - "block.betterend.charnia_green": "Grünes Charnia", - "block.betterend.vent_bubble_column": "Blasenquellensäule", - "block.betterend.respawn_obelisk": "Rücksetzobelisk", - "message.betterend.set_spawn": "\u00A7b\u00A7lWiedereinstiegspunkt gesetzt", - "message.betterend.fail_spawn": "\u00A7c\u00A7lDu musst 6 Bernsteinjuwele in der Hand halten, um deinen Einstiegspunkt zu setzen.", - - "block.betterend.dragon_tree_composter": "Drachenbaumkomposter", - "block.betterend.end_lotus_composter": "Endlotuskomposter", - "block.betterend.helix_tree_composter": "Spiralbaumkomposter", - "block.betterend.lacugrove_composter": "Seemangrovenkomposter", - "block.betterend.mossy_glowshroom_composter": "Bemooster Glühpilzkomposter", - "block.betterend.pythadendron_composter": "Pythadendronkomposter", - "block.betterend.tenanea_composter": "Tenaneakomposter", - - "biome.betterend.old_bulbis_gardens": "Alte Knollengärten", - "block.betterend.ivis_moss": "Efeumoos", - "block.betterend.ivis_vine": "Efeuranke", - "block.betterend.silk_moth_nest": "Seidenmottennest", - - "block.betterend.umbrella_tree_bark": "Schirmbaumholz", - "block.betterend.umbrella_tree_barrel": "Schirmbaumfass", - "block.betterend.umbrella_tree_bookshelf": "Schirmbaumbücherregal", - "block.betterend.umbrella_tree_button": "Schirmbaumknopf", - "block.betterend.umbrella_tree_chest": "Schirmbaumtruhe", - "block.betterend.umbrella_tree_composter": "Schirmbaumkomposter", - "block.betterend.umbrella_tree_crafting_table": "Schirmbaumwerkbank", - "block.betterend.umbrella_tree_door": "Schirmbaumtür", - "block.betterend.umbrella_tree_fence": "Schirmbaumzaun", - "block.betterend.umbrella_tree_gate": "Schirmbaumzauntor", - "block.betterend.umbrella_tree_ladder": "Schirmbaumleiter", - "block.betterend.umbrella_tree_log": "Schirmbaumstamm", - "block.betterend.umbrella_tree_planks": "Schirmbaumbretter", - "block.betterend.umbrella_tree_plate": "Schirmbaumdruckplatte", - "block.betterend.umbrella_tree_sign": "Schirmbaumschild", - "block.betterend.umbrella_tree_slab": "Schirmbaumstufe", - "block.betterend.umbrella_tree_stairs": "Schirmbaumtreppe", - "block.betterend.umbrella_tree_stripped_bark": "Entrindetes Schirmbaumholz", - "block.betterend.umbrella_tree_stripped_log": "Entrindeter Schirmbaumstamm", - "block.betterend.umbrella_tree_trapdoor": "Schirmbaumfalltür", - "block.betterend.umbrella_tree_membrane": "Schirmbaummembran", - - "biome.betterend.umbrella_jungle": "Schirmdschungel", - "block.betterend.jungle_grass": "Dschungelgras", - "block.betterend.jungle_moss": "Dschungelmoos", - "block.betterend.jungle_moss_path": "Dschungelmoospfad", - "block.betterend.small_jellyshroom": "Kleiner Geleepilz", - "block.betterend.twisted_umbrella_moss": "Zwirbelschirmmoos", - "block.betterend.twisted_umbrella_moss_tall": "Großes Zwirbelschirmmoos", - "block.betterend.umbrella_tree_cluster": "Schirmtraube", - "block.betterend.umbrella_tree_cluster_empty": "Leere Schirmtrauben", - "block.betterend.jungle_vine": "Dschungelranke", - "block.betterend.jungle_fern": "Dschungelfarn", - - "block.betterend.jellyshroom_bark": "Geleepilzholz", - "block.betterend.jellyshroom_barrel": "Geleepilzfass", - "block.betterend.jellyshroom_bookshelf": "Geleepilzbücherregal", - "block.betterend.jellyshroom_button": "Geleepilzknopf", - "block.betterend.jellyshroom_cap_purple": "Violette Geleepilzkappe", - "block.betterend.jellyshroom_chest": "Geleepilztruhe", - "block.betterend.jellyshroom_composter": "Geleepilzkomposter", - "block.betterend.jellyshroom_crafting_table": "Geleepilzwerkbank", - "block.betterend.jellyshroom_door": "Geleepilztür", - "block.betterend.jellyshroom_fence": "Geleepilzzaun", - "block.betterend.jellyshroom_gate": "Geleepilzzauntor", - "block.betterend.jellyshroom_ladder": "Geleepilzleiter", - "block.betterend.jellyshroom_log": "Geleepilzstamm", - "block.betterend.jellyshroom_planks": "Geleepilzbretter", - "block.betterend.jellyshroom_plate": "Geleepilzdruckplatte", - "block.betterend.jellyshroom_sign": "Geleepilzschild", - "block.betterend.jellyshroom_slab": "Geleepilzstufe", - "block.betterend.jellyshroom_stairs": "Geleepilztreppe", - "block.betterend.jellyshroom_stripped_bark": "Entrindetes Geleepilzholz", - "block.betterend.jellyshroom_stripped_log": "Entrindeter Geleepilzstamm", - "block.betterend.jellyshroom_trapdoor": "Geleepilzfalltür", - - "biome.betterend.eterial_grove": "Äthermangrove", - "block.betterend.umbrella_tree_sapling": "Schirmbaumsetzling", - "item.betterend.umbrella_cluster_juice": "Schirmtraubensaft", - "block.betterend.blossom_berry_seed": "Blütenbeerensamen", - "item.betterend.blossom_berry": "Blütenbeere", - - "biome.betterend.nightshade_redwoods": "Nachtschattenrotwald", - "block.betterend.nightshade_moss": "Nachtschattenmoos", - - "biome.betterend.glowing_grasslands": "Glühende Wiesen", - "block.betterend.blooming_cooksonia": "Blühende Cooksonia", - "block.betterend.fracturn": "Fraktur", - "block.betterend.lumecorn": "Maislicht", - "block.betterend.salteago": "Salzeago", - "block.betterend.vaiolush_fern": "Vaiosatt Farn", - "entity.betterend.silk_moth": "Seidenmotte", - "item.betterend.silk_fiber": "Seidenfaser", - "item.betterend.spawn_egg_silk_moth": "Seidenmotten-Spawn-Ei", - - "block.betterend.thallasium_ore": "Thallasiumerz", - "item.betterend.thallasium_axe": "Thallasiumaxt", - "item.betterend.thallasium_hoe": "Thallasiumhacke", - "item.betterend.thallasium_ingot": "Thallasiumbarren", - "item.betterend.thallasium_pickaxe": "Thallasiumspitzhacke", - "item.betterend.thallasium_shovel": "Thallasiumschaufel", - "item.betterend.thallasium_sword": "Thallasiumschwert", - "block.betterend.thallasium_block": "Thallasiumblock", - - "block.betterend.thallasium_bars": "Thallasiumgitter", - "block.betterend.thallasium_door": "Thallasiumtür", - "block.betterend.thallasium_plate": "Thallasiumdruckplatte", - "block.betterend.thallasium_tile": "Thallasiumfliesen", - "block.betterend.thallasium_trapdoor": "Thallasiumfalltür", - - "block.betterend.lumecorn_seed": "Maislichtsamen", - "item.betterend.lumecorn_rod": "Maislichtstange", - "block.betterend.thallasium_chandelier": "Thallasiumkronleuchter", - - "block.betterend.thallasium_anvil": "Thallasiumamboss", - "block.betterend.thallasium_chain": "Thallasiumkette", - "block.betterend.thallasium_slab": "Thallasiumstufe", - "block.betterend.thallasium_stairs": "Thallasiumtreppe", - - "block.betterend.gold_chandelier": "Goldkronleuchter", - "block.betterend.iron_chandelier": "Eisenkronleuchter", - "item.betterend.thallasium_nugget": "Thallasiumklumpen", - - "block.betterend.terminite_anvil": "Terminitamboss", - "block.betterend.terminite_bars": "Terminitgitter", - - "block.betterend.terminite_bulb_lantern": "Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_black": "Schwarze Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_blue": "Blaue Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_brown": "Braune Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_cyan": "Türkise Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_gray": "Graue Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_green": "Green Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_light_blue": "Hellblaue Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_light_gray": "Hellgraue Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_lime": "Hellgrüne Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_magenta": "Magenta Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_orange": "Orangene Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_pink": "Pinke Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_purple": "Violette Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_red": "Rote Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_white": "Weiße Terminitknollenlaterne", - "block.betterend.terminite_bulb_lantern_yellow": "Gelbe Terminitknollenlaterne", - - "block.betterend.terminite_chain": "Terminitkette", - "block.betterend.terminite_chandelier": "Terminitkronleuchter", - "block.betterend.terminite_door": "Terminittür", - "block.betterend.terminite_plate": "Terminitdruckplatte", - "block.betterend.terminite_slab": "Terminitstufe", - "block.betterend.terminite_stairs": "Terminittreppe", - "block.betterend.terminite_tile": "Terminitfliesen", - "block.betterend.terminite_trapdoor": "Terminitfalltür", - "item.betterend.terminite_nugget": "Terminitklumpen", - "item.betterend.thallasium_boots": "Thallasiumstiefel", - "item.betterend.thallasium_chestplate": "Thallasiumharnisch", - "item.betterend.thallasium_hammer": "Thallasiumschmiedehammer", - "item.betterend.thallasium_helmet": "Thallasiumhelm", - "item.betterend.thallasium_leggings": "Thallasiumbeinschutz", - "block.betterend.missing_tile": "Fehlende Fliesen", - "block.betterend.charcoal_block": "Holzkohleblock", - "block.betterend.end_stone_furnace": "Endsteinofen", - "block.betterend.flavolite_furnace": "Flavolitofen", - "block.betterend.sulphuric_rock_furnace": "Schwefelsteinofen", - "block.betterend.violecite_furnace": "Violezitofen", - - "item.betterend.terminite_axe_head": "Terminitaxtkopf", - "item.betterend.terminite_hoe_head": "Terminithackenkopf", - "item.betterend.terminite_pickaxe_head": "Terminitspitzhackenkopf", - "item.betterend.terminite_shovel_head": "Terminitschaufelkopf", - "item.betterend.terminite_sword_blade": "Terminitschwertklinge", - "item.betterend.terminite_sword_handle": "Terminitschwertgriff", - "item.betterend.thallasium_axe_head": "Thallasiumaxtkopf", - "item.betterend.thallasium_hoe_head": "Thallasiumhackenkopf", - "item.betterend.thallasium_pickaxe_head": "Thallasiumspitzhackenkopf", - "item.betterend.thallasium_shovel_head": "Thallasiumschaufelkopf", - "item.betterend.thallasium_sword_blade": "Thallasiumschwertklinge", - "item.betterend.thallasium_sword_handle": "Thallasiumschwertgriff", - "block.betterend.aeternium_anvil": "Ätheramboss" + "itemGroup.betterend.end_items": "Better End: Items", + "itemGroup.betterend.end_blocks": "Better End: Blöcke", + "item.betterend.guidebook": "Das Ende für Idioten", + "book.betterend.landing": "Eine kurze Anleitung zum Überleben unter den extremen Bedingungen im End.", + "book.betterend.subtitle": "Überlebe im End", + "category.rei.damage.amount&dmg": "Werkzeugschaden: %s", + "category.rei.infusion.time&val": "Zeit: %s", + "biome.betterend.foggy_mushroomland": "Nebeliges Pilzland", + "biome.betterend.dust_wastelands": "Staubiges Ödland", + "biome.betterend.chorus_forest": "Choruswald", + "biome.betterend.megalake": "Riesensee", + "biome.betterend.crystal_mountains": "Kristallberge", + "entity.betterend.dragonfly": "Libelle", + "item.betterend.spawn_egg_dragonfly": "Libellen-Spawn-Ei", + "entity.betterend.end_slime": "Endschleim", + "item.betterend.spawn_egg_end_slime": "Endschleim-Spawn-Ei", + "block.betterend.end_mycelium": "End-Myzel", + "block.betterend.end_moss": "End-Moos", + "block.betterend.endstone_dust": "Endsteinstaub", + "block.betterend.end_mycelium_path": "End-Myzelpfad", + "block.betterend.end_moss_path": "End-Moospfad", + "block.betterend.ender_ore": "Endererz", + "block.betterend.terminite_block": "Terminitblock", + "block.betterend.aeternium_block": "Ätherblock", + "block.betterend.ender_block": "Enderblock", + "block.betterend.end_stone_smelter": "Endsteinschmelzofen", + "item.betterend.ender_dust": "Enderstaub", + "item.betterend.ender_shard": "Enderscherbe", + "item.betterend.terminite_ingot": "Terminitbarren", + "item.betterend.aeternium_ingot": "Ätherbarren", + "item.betterend.terminite_helmet": "Terminithelm", + "item.betterend.terminite_chestplate": "Terminitharnisch", + "item.betterend.terminite_leggings": "Terminitbeinschutz", + "item.betterend.terminite_boots": "Terminitstiefel", + "item.betterend.terminite_shovel": "Terminitschaufel", + "item.betterend.terminite_sword": "Terminitschwert", + "item.betterend.terminite_pickaxe": "Terminitspitzhacke", + "item.betterend.terminite_axe": "Terminitaxt", + "item.betterend.terminite_hoe": "Terminithacke", + "item.betterend.terminite_hammer": "Terminitschmiedehammer", + "item.betterend.aeternium_helmet": "Ätherhelm", + "item.betterend.aeternium_chestplate": "Ätherharnisch", + "item.betterend.aeternium_leggings": "Ätherbeinschutz", + "item.betterend.aeternium_boots": "Ätherstiefel", + "item.betterend.aeternium_shovel": "Ätherschaufel", + "item.betterend.aeternium_sword": "Ätherschwert", + "item.betterend.aeternium_pickaxe": "Ätherspitzhacke", + "item.betterend.aeternium_axe": "Ätheraxt", + "item.betterend.aeternium_hoe": "Ätherhacke", + "item.betterend.aeternium_hammer": "Ätherschmiedehammer", + "item.betterend.iron_hammer": "Eisenschmiedehammer", + "item.betterend.golden_hammer": "Goldschmiedehammer", + "item.betterend.diamond_hammer": "Diamantschmiedehammer", + "item.betterend.netherite_hammer": "Netheritschmiedehammer", + "item.betterend.crystalite_boots": "Kristallitstiefel", + "item.betterend.crystalite_chestplate": "Kristallitharnisch", + "item.betterend.crystalite_helmet": "Kristallithelm", + "item.betterend.crystalite_leggings": "Kristallitbeinschutz", + "item.betterend.aeternium_axe_head": "Ätheraxtkopf", + "item.betterend.aeternium_hammer_head": "Ätherhammerkopf", + "item.betterend.aeternium_hoe_head": "Ätherhackenkopf", + "item.betterend.aeternium_pickaxe_head": "Ätherspitzhackenkopf", + "item.betterend.aeternium_shovel_head": "Ätherschaufelkopf", + "item.betterend.aeternium_sword_blade": "Ätherschwertklinge", + "item.betterend.aeternium_sword_handle": "Ätherschwertgriff", + "item.betterend.leather_stripe": "Lederband", + "item.betterend.leather_wrapped_stick": "Leder-umwickelter Stock", + "effect.betterend.end_veil": "Endschleier", + "enchantment.betterend.end_veil": "Endschleier", + "item.minecraft.potion.effect.end_veil": "Trank des Endschleiers", + "item.minecraft.potion.effect.long_end_veil": "Trank des Endschleiers", + "item.minecraft.splash_potion.effect.end_veil": "Wurftrank des Endschleiers", + "item.minecraft.splash_potion.effect.long_end_veil": "Wurftrank des Endschleiers", + "item.minecraft.lingering_potion.effect.end_veil": "Verweiltrank des Endschleiers", + "item.minecraft.lingering_potion.effect.long_end_veil": "Verweiltrank des Endschleiers", + "item.minecraft.tipped_arrow.effect.end_veil": "Pfeil des Endschleiers", + "item.minecraft.tipped_arrow.effect.long_end_veil": "Pfeil des Endschleiers", + "block.betterend.mossy_glowshroom_sapling": "Bemooster Glühpilzsetzling", + "block.betterend.mossy_glowshroom_cap": "Bemooste Glühpilzkappe", + "block.betterend.mossy_glowshroom_fur": "Bemoostes Glühpilzfell", + "block.betterend.mossy_glowshroom_hymenophore": "Bemoostes Glühpilzhymenophor", + "block.betterend.mossy_glowshroom_bark": "Bemoostes Glühpilzholz", + "block.betterend.mossy_glowshroom_barrel": "Bemoostes Glühpilzfass", + "block.betterend.mossy_glowshroom_button": "Bemooster Glühpilzknopf", + "block.betterend.mossy_glowshroom_chest": "Bemooste Glühpilztruhe", + "block.betterend.mossy_glowshroom_crafting_table": "Bemooste Glühpilzwerkbank", + "block.betterend.mossy_glowshroom_door": "Bemooste Glühpilztür", + "block.betterend.mossy_glowshroom_fence": "Bemooster Glühpilzzaun", + "block.betterend.mossy_glowshroom_gate": "Bemoostes Glühpilzzauntor", + "block.betterend.mossy_glowshroom_ladder": "Bemooste Glühpilzleiter", + "block.betterend.mossy_glowshroom_log": "Bemooster Glühpilzstamm", + "block.betterend.mossy_glowshroom_planks": "Bemooste Glühpilzbretter", + "block.betterend.mossy_glowshroom_plate": "Bemooste Glühpilzdruckplatte", + "block.betterend.mossy_glowshroom_sign": "Bemoostes Glühpilzschild", + "block.betterend.mossy_glowshroom_slab": "Bemooste Glühpilzstufe", + "block.betterend.mossy_glowshroom_stairs": "Bemooste Glühpilztreppe", + "block.betterend.mossy_glowshroom_stripped_bark": "Entrindetes bemoostes Glühpilzholz", + "block.betterend.mossy_glowshroom_stripped_log": "Entrindeter bemooster Glühpilzstamm", + "block.betterend.mossy_glowshroom_trapdoor": "Bemooste Glühpilzfalltür", + "block.betterend.umbrella_moss": "Schirmmoos", + "block.betterend.umbrella_moss_tall": "Großes Schirmmoos", + "block.betterend.creeping_moss": "Kriechendes Moos", + "block.betterend.blue_vine_seed": "Blaurankensamen", + "block.betterend.blue_vine": "Blauranke", + "block.betterend.blue_vine_lantern": "Blaurankenlaterne", + "block.betterend.blue_vine_fur": "Blaurankenfell", + "block.betterend.dense_vine": "Dichte Ranke", + "block.betterend.bubble_coral": "Blasenkoralle", + "block.betterend.aurora_crystal": "Aurorakristall", + "item.betterend.crystal_shards": "Kristallscherben", + "block.betterend.pythadendron_sapling": "Pythadendronsetzling", + "block.betterend.pythadendron_bark": "Pythadendronholz", + "block.betterend.pythadendron_barrel": "Pythadendronfass", + "block.betterend.pythadendron_button": "Pythadendronknopf", + "block.betterend.pythadendron_chest": "Pythadendrontruhe", + "block.betterend.pythadendron_crafting_table": "Pythadendronwerkbank", + "block.betterend.pythadendron_door": "Pythadendrontür", + "block.betterend.pythadendron_fence": "Pythadendronzaun", + "block.betterend.pythadendron_gate": "Pythadendronzauntor", + "block.betterend.pythadendron_ladder": "Pythadendronleiter", + "block.betterend.pythadendron_log": "Pythadendronstamm", + "block.betterend.pythadendron_planks": "Pythadendronbretter", + "block.betterend.pythadendron_plate": "Pythadendrondruckplatte", + "block.betterend.pythadendron_sign": "Pythadendronschild", + "block.betterend.pythadendron_slab": "Pythadendronstufe", + "block.betterend.pythadendron_stairs": "Pythadendrontreppe", + "block.betterend.pythadendron_stripped_bark": "Entrindetes Pythadendronholz", + "block.betterend.pythadendron_stripped_log": "Entrindeter Pythadendronstamm", + "block.betterend.pythadendron_trapdoor": "Pythadendronfalltür", + "block.betterend.chorus_nylium": "Chorus-Nezel", + "block.betterend.chorus_nylium_path": "Chorus-Nezelpfad", + "block.betterend.chorus_grass": "Chorusgras", + "block.betterend.end_lily": "Endlilie", + "block.betterend.end_lily_seed": "Endliliensamen", + "item.betterend.end_lily_leaf": "Endlilienblatt", + "item.betterend.end_lily_leaf_dried": "Trockenes Endlilienblatt", + "block.betterend.violecite": "Violezit", + "block.betterend.violecite_bricks": "Violezitziegel", + "block.betterend.violecite_bricks_slab": "Violezitziegelstufe", + "block.betterend.violecite_bricks_stairs": "Violezitziegeltreppe", + "block.betterend.violecite_bricks_wall": "Violezitziegelmauer", + "block.betterend.violecite_button": "Violezitknopf", + "block.betterend.violecite_pillar": "Violezitsäule", + "block.betterend.violecite_plate": "Violezitdruckplatte", + "block.betterend.violecite_slab": "Violezitstufe", + "block.betterend.violecite_tiles": "Violezitfliesen", + "block.betterend.violecite_stairs": "Violezittreppe", + "block.betterend.violecite_polished": "Polierter Violezit", + "block.betterend.violecite_wall": "Violezitmauer", + "block.betterend.violecite_pedestal": "Violezitsockel", + "block.betterend.flavolite": "Flavolit", + "block.betterend.flavolite_bricks": "Flavolitziegel", + "block.betterend.flavolite_bricks_slab": "Flavolitziegelstufe", + "block.betterend.flavolite_bricks_stairs": "Flavolitziegeltreppe", + "block.betterend.flavolite_bricks_wall": "Flavolitziegelmauer", + "block.betterend.flavolite_button": "Flavolitknopf", + "block.betterend.flavolite_pillar": "Flavolitsäule", + "block.betterend.flavolite_plate": "Flavolitdruckplatte", + "block.betterend.flavolite_slab": "Flavolitstufe", + "block.betterend.flavolite_tiles": "Flavolitfliesen", + "block.betterend.flavolite_stairs": "Flavolittreppe", + "block.betterend.flavolite_polished": "Polierter Flavolit", + "block.betterend.flavolite_wall": "Flavolitmauer", + "block.betterend.flavolite_pedestal": "Flavolitsockel", + "block.betterend.andesite_pedestal": "Andesitsockel", + "block.betterend.diorite_pedestal": "Dioritsockel", + "block.betterend.granite_pedestal": "Granitsockel", + "block.betterend.purpur_pedestal": "Purpursockel", + "block.betterend.quartz_pedestal": "Quarzsockel", + "block.betterend.infusion_pedestal": "Elementarsockel", + "block.betterend.end_lotus_seed": "Endlotussamen", + "block.betterend.end_lotus_stem": "Endlotusstamm", + "block.betterend.end_lotus_leaf": "Endlotusblatt", + "block.betterend.end_lotus_flower": "Endlotusblume", + "block.betterend.end_lotus_bark": "Endlotusholz", + "block.betterend.end_lotus_barrel": "Endlotusfass", + "block.betterend.end_lotus_button": "Endlotusknopf", + "block.betterend.end_lotus_chest": "Endlotustruhe", + "block.betterend.end_lotus_crafting_table": "Endlotuswerkbank", + "block.betterend.end_lotus_door": "Endlotustür", + "block.betterend.end_lotus_fence": "Endlotuszaun", + "block.betterend.end_lotus_gate": "Endlotuszauntor", + "block.betterend.end_lotus_ladder": "Endlotusleiter", + "block.betterend.end_lotus_log": "Endlotusstamm", + "block.betterend.end_lotus_planks": "Endlotusbretter", + "block.betterend.end_lotus_plate": "Endlotusdruckplatte", + "block.betterend.end_lotus_sign": "Endlotusschild", + "block.betterend.end_lotus_slab": "Endlotusstufe", + "block.betterend.end_lotus_stairs": "Endlotustreppe", + "block.betterend.end_lotus_stripped_bark": "Entrindetes Endlotusholz", + "block.betterend.end_lotus_stripped_log": "Entrindeter Endlotusstamm", + "block.betterend.end_lotus_trapdoor": "Endlotusfalltür", + "block.betterend.cave_moss": "Höhlenmoos", + "block.betterend.cave_grass": "Höhlengras", + "block.betterend.cave_bush": "Höhlenbusch", + "block.betterend.cave_moss_path": "Höhlenmoospfad", + "block.betterend.crystal_moss": "Kristallmoos", + "block.betterend.crystal_moss_path": "Kristallmoospfad", + "block.betterend.crystal_moss_cover": "Cristallmoosteppich", + "block.betterend.pythadendron_leaves": "Pythadendronlaub", + "item.betterend.spawn_egg_end_fish": "Endfisch-Spawn-Ei", + "block.betterend.crystal_grass": "Kristallgras", + "block.betterend.flavolite_runed": "Flavolitrune", + "block.betterend.end_portal_block": "Endportal", + "block.betterend.eternal_pedestal": "Ewiger Sockel", + "block.betterend.flavolite_runed_eternal": "Ewige Flavolitrune", + "item.betterend.eternal_crystal": "Ewiger Kristall", + "block.betterend.lacugrove_bark": "Seemangrovenholz", + "block.betterend.lacugrove_barrel": "Seemangrovenfass", + "block.betterend.lacugrove_button": "Seemangrovenknopf", + "block.betterend.lacugrove_chest": "Seemangroventruhe", + "block.betterend.lacugrove_crafting_table": "Seemangrovenwerkbank", + "block.betterend.lacugrove_door": "Seemangroventür", + "block.betterend.lacugrove_fence": "Seemangrovenzaun", + "block.betterend.lacugrove_gate": "Seemangrovenzauntor", + "block.betterend.lacugrove_ladder": "Seemangrovenleiter", + "block.betterend.lacugrove_log": "Seemangrovenstamm", + "block.betterend.lacugrove_planks": "Seemangrovenbretter", + "block.betterend.lacugrove_plate": "Seemangrovendruckplatte", + "block.betterend.lacugrove_sign": "Seemangrovenschild", + "block.betterend.lacugrove_slab": "Seemangrovenstufe", + "block.betterend.lacugrove_stairs": "Seemangroventreppe", + "block.betterend.lacugrove_stripped_bark": "Entrindetes Seemangrovenholz", + "block.betterend.lacugrove_stripped_log": "Entrindeter Seemangrovenstamm", + "block.betterend.lacugrove_trapdoor": "Seemangrovenfalltür", + "block.betterend.lacugrove_leaves": "Seemangrovenlaub", + "block.betterend.lacugrove_sapling": "Seemangrovensetzling", + "biome.betterend.megalake_grove": "Riesenseemangrove", + "biome.betterend.painted_mountains": "Bemalte Berge", + "block.betterend.dragon_tree_bark": "Drachenbaumholz", + "block.betterend.dragon_tree_barrel": "Drachenbaumfass", + "block.betterend.dragon_tree_button": "Drachenbaumknopf", + "block.betterend.dragon_tree_chest": "Drachenbaumtruhe", + "block.betterend.dragon_tree_crafting_table": "Drachenbaumwerkbank", + "block.betterend.dragon_tree_door": "Drachenbaumtür", + "block.betterend.dragon_tree_fence": "Drachenbaumzaun", + "block.betterend.dragon_tree_gate": "Drachenbaumzauntor", + "block.betterend.dragon_tree_ladder": "Drachenbaumleiter", + "block.betterend.dragon_tree_log": "Drachenbaumstamm", + "block.betterend.dragon_tree_planks": "Drachenbaumbretter", + "block.betterend.dragon_tree_plate": "Drachenbaumdruckplatte", + "block.betterend.dragon_tree_sign": "Drachenbaumschild", + "block.betterend.dragon_tree_slab": "Drachenbaumstufe", + "block.betterend.dragon_tree_stairs": "Drachenbaumtreppe", + "block.betterend.dragon_tree_stripped_bark": "Entrindetes Drachenbaumholz", + "block.betterend.dragon_tree_stripped_log": "Entrindeter Drachenbaumstamm", + "block.betterend.dragon_tree_trapdoor": "Drachenbaumfalltür", + "biome.betterend.shadow_forest": "Schattenwald", + "block.betterend.dragon_tree_leaves": "Drachenbaumlaub", + "block.betterend.dragon_tree_sapling": "Drachenbaumsetzling", + "block.betterend.shadow_grass": "Schattengras", + "block.betterend.shadow_grass_path": "Schattengraspfad", + "block.betterend.shadow_plant": "Schattenpflanze", + "block.betterend.dragon_tree_bookshelf": "Drachenbaumbücherregal", + "block.betterend.end_lotus_bookshelf": "Endlotusbücherregal", + "block.betterend.lacugrove_bookshelf": "Seemangrovenbücherregal", + "block.betterend.mossy_glowshroom_bookshelf": "Bemoostes Glühpilzbücherregal", + "block.betterend.pythadendron_bookshelf": "Pythadendronbücherregal", + "block.betterend.murkweed": "Trübkraut", + "block.betterend.needlegrass": "Nadelgras", + "block.betterend.twisted_vine": "Zwirbelranke", + "block.betterend.shadow_berry": "Schattenbeersamen", + "item.betterend.shadow_berry_cooked": "Gebratene Schattenbeere", + "item.betterend.shadow_berry_raw": "Schattenbeere", + "block.betterend.purple_polypore": "Violetter Porling", + "block.betterend.cyan_moss": "Türkises Moos", + "block.betterend.tail_moss": "Schweifmoos", + "block.betterend.flavolite_lantern": "Flavolitlaterne", + "block.betterend.end_stone_lantern": "Endsteinlaterne", + "block.betterend.violecite_lantern": "Violezitlaterne", + "entity.betterend.end_fish": "Endfisch", + "entity.betterend.shadow_walker": "Schattenwanderer", + "item.betterend.spawn_egg_shadow_walker": "Schattenwanderer-Spawn-Ei", + "block.betterend.andesite_lantern": "Andesitlaterne", + "block.betterend.blackstone_lantern": "Schwarzsteinlaterne", + "block.betterend.diorite_lantern": "Dioritlaterne", + "block.betterend.granite_lantern": "Granitlaterne", + "block.betterend.purpur_lantern": "Purpurlaterne", + "block.betterend.quartz_lantern": "Quarzlaterne", + "item.betterend.bucket_end_fish": "Endfischeimer", + "item.betterend.end_fish_cooked": "Gebratener Endfisch", + "item.betterend.end_fish_raw": "Endfisch", + "biome.betterend.amber_land": "Bernsteinland", + "biome.betterend.blossoming_spires": "Blühende Türme", + "block.betterend.amber_grass": "Bernsteingras", + "block.betterend.amber_grass_path": "Bernsteingraspfad", + "block.betterend.tenanea_bark": "Tenaneaholz", + "block.betterend.tenanea_barrel": "Tenaneafass", + "block.betterend.tenanea_bookshelf": "Tenaneabücherregal", + "block.betterend.tenanea_button": "Tenaneaknopf", + "block.betterend.tenanea_chest": "Tenaneatruhe", + "block.betterend.tenanea_crafting_table": "Tenaneawerkbank", + "block.betterend.tenanea_door": "Tenaneatür", + "block.betterend.tenanea_fence": "Tenaneazaun", + "block.betterend.tenanea_gate": "Tenaneazauntor", + "block.betterend.tenanea_ladder": "Tenanealeiter", + "block.betterend.tenanea_leaves": "Tenanealaub", + "block.betterend.tenanea_log": "Tenaneastamm", + "block.betterend.tenanea_planks": "Tenaneabretter", + "block.betterend.tenanea_plate": "Tenaneadruckplatte", + "block.betterend.tenanea_sapling": "Tenaneasetzling", + "block.betterend.tenanea_sign": "Tenaneaschild", + "block.betterend.tenanea_slab": "Tenaneastufe", + "block.betterend.tenanea_stairs": "Tenaneatreppe", + "block.betterend.tenanea_stripped_bark": "Entrindetes Tenaneaholz", + "block.betterend.tenanea_stripped_log": "Entrindeter Tenaneastamm", + "block.betterend.tenanea_trapdoor": "Tenaneafalltür", + "block.betterend.amber_block": "Bernsteinblock", + "block.betterend.amber_ore": "Bernsteinerz", + "item.betterend.amber_gem": "Bernsteinjuwel", + "item.betterend.raw_amber": "Roher Bernstein", + "block.betterend.tenanea_flowers": "Tenaneablumen", + "block.betterend.tenanea_outer_leaves": "Äußeres Tenanealaub", + "block.betterend.pink_moss": "Pinkes Moos", + "block.betterend.pink_moss_path": "Pinker Moospfad", + "block.betterend.twisted_moss": "Zwirbelmoos", + "block.betterend.bulb_vine": "Knollenranke", + "block.betterend.bulb_vine_seed": "Knollenrankensamen", + "item.betterend.glowing_bulb": "Glühende Knolle", + "block.betterend.iron_bulb_lantern": "Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_black": "Schwarze Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_blue": "Blaue Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_brown": "Braune Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_cyan": "Türkise Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_gray": "Graue Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_green": "Grüne Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_light_blue": "Hellblaue Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_light_gray": "Hellgraue Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_lime": "Hellgrüne Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_magenta": "Magenta Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_orange": "Orangene Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_pink": "Pinke Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_purple": "Violette Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_red": "Rote Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_white": "Weiße Eisenknollenlaterne", + "block.betterend.iron_bulb_lantern_yellow": "Gelbe Eisenknollenlaterne", + "block.betterend.gold_bulb_lantern": "Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_black": "Schwarze Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_blue": "Blaue Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_brown": "Braune Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_cyan": "Türkise Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_gray": "Graue Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_green": "Grüne Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_light_blue": "Hellblaue Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_light_gray": "Hellgraue Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_lime": "Hellgrüne Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_magenta": "Magenta Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_orange": "Orangene Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_pink": "Pinke Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_purple": "Violette Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_red": "Rote Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_white": "Weiße Goldknollenlaterne", + "block.betterend.gold_bulb_lantern_yellow": "Gelbe Goldknollenlaterne", + "block.betterend.thallasium_bulb_lantern": "Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_black": "Schwarze Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_blue": "Blaue Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_brown": "Braune Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_cyan": "Türkise Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_gray": "Graue Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_green": "Grüne Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_light_blue": "Hellblaue Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_light_gray": "Hellgraue Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_lime": "Hellgrüne Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_magenta": "Magenta Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_orange": "Orangene Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_pink": "Pinke Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_purple": "Violette Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_red": "Rote Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_white": "Weiße Thallasiumknollenlaterne", + "block.betterend.thallasium_bulb_lantern_yellow": "Gelbe Thallasiumknollenlaterne", + "block.betterend.bushy_grass": "Buschiges Gras", + "block.betterend.brimstone": "Schwefelrandstein", + "block.betterend.sulphuric_rock": "Schwefelgestein", + "block.betterend.sulphuric_rock_bricks": "Schwefelsteinziegel", + "block.betterend.sulphuric_rock_bricks_slab": "Schwefelsteinziegelstufe", + "block.betterend.sulphuric_rock_bricks_stairs": "Schwefelsteinziegeltreppe", + "block.betterend.sulphuric_rock_bricks_wall": "Schwefelsteinziegelmauer", + "block.betterend.sulphuric_rock_button": "Schwefelsteinknopf", + "block.betterend.sulphuric_rock_lantern": "Schwefelsteinlaterne", + "block.betterend.sulphuric_rock_pedestal": "Schwefelsteinsockel", + "block.betterend.sulphuric_rock_pillar": "Schwefelsteinsäule", + "block.betterend.sulphuric_rock_plate": "Schwefelsteindruckplatte", + "block.betterend.sulphuric_rock_polished": "Poliertes Schwefelgestein", + "block.betterend.sulphuric_rock_slab": "Schwefelsteinstufe", + "block.betterend.sulphuric_rock_stairs": "Schwefelsteintreppe", + "block.betterend.sulphuric_rock_tiles": "Schwefelsteinfliesen", + "block.betterend.sulphuric_rock_wall": "Schwefelsteinmauer", + "block.betterend.sulphur_crystal": "Schwefelkristall", + "item.betterend.crystalline_sulphur": "Schwefel", + "biome.betterend.sulphur_springs": "Schwefelquellen", + "block.betterend.hydralux_petal_block": "Hydraluxblüttenblattblock", + "block.betterend.hydralux_petal_block_black": "Schwarzer Blüttenblattblock", + "block.betterend.hydralux_petal_block_blue": "Blauer Blüttenblattblock", + "block.betterend.hydralux_petal_block_brown": "Brauner Blüttenblattblock", + "block.betterend.hydralux_petal_block_cyan": "Türkiser Blüttenblattblock", + "block.betterend.hydralux_petal_block_gray": "Grauer Blüttenblattblock", + "block.betterend.hydralux_petal_block_green": "Grüner Blüttenblattblock", + "block.betterend.hydralux_petal_block_light_blue": "Hellblauer Blüttenblattblock", + "block.betterend.hydralux_petal_block_light_gray": "Hellgrauer Blüttenblattblock", + "block.betterend.hydralux_petal_block_lime": "Hellgrüner Blüttenblattblock", + "block.betterend.hydralux_petal_block_magenta": "Magenta Blüttenblattblock", + "block.betterend.hydralux_petal_block_orange": "Orangener Blüttenblattblock", + "block.betterend.hydralux_petal_block_pink": "Pinker Blüttenblattblock", + "block.betterend.hydralux_petal_block_purple": "Violetter Blüttenblattblock", + "block.betterend.hydralux_petal_block_red": "Roter Blüttenblattblock", + "block.betterend.hydralux_petal_block_white": "Weißer Blüttenblattblock", + "block.betterend.hydralux_petal_block_yellow": "Gelber Blüttenblattblock", + "block.betterend.hydralux_sapling": "Hydraluxsetzling", + "block.betterend.hydrothermal_vent": "Hydrothermalquelle", + "item.betterend.hydralux_petal": "Hydraluxblütenblatt", + "item.betterend.enchanted_petal": "Verzaubertes Blütenblatt", + "block.betterend.menger_sponge": "Mengerschwamm", + "block.betterend.menger_sponge_wet": "Nasser Mengerschwamm", + "block.betterend.tube_worm": "Röhrenwurm", + "block.betterend.charnia_cyan": "Türkises Charnia", + "block.betterend.charnia_light_blue": "Hellblaues Charnia", + "block.betterend.charnia_orange": "Orangenes Charnia", + "block.betterend.charnia_purple": "Violettes Charnia", + "block.betterend.charnia_red": "Rotes Charnia", + "entity.betterend.cubozoa": "Cubozoa", + "item.betterend.spawn_egg_cubozoa": "Cubozoa-Spawn-Ei", + "item.betterend.gelatine": "Gelatine", + "item.betterend.sweet_berry_jelly": "Süßbeerengelee", + "item.betterend.shadow_berry_jelly": "Schwarzbeerengelee", + "block.betterend.amber_moss": "Bernsteinmoos", + "block.betterend.amber_moss_path": "Bernsteinmoospfad", + "block.betterend.helix_tree_bark": "Spiralbaumholz", + "block.betterend.helix_tree_barrel": "Spiralbaumfass", + "block.betterend.helix_tree_bookshelf": "Spiralbaumbücherregal", + "block.betterend.helix_tree_button": "Spiralbaumknopf", + "block.betterend.helix_tree_chest": "Spiralbaumtruhe", + "block.betterend.helix_tree_crafting_table": "Spiralbaumwerkbank", + "block.betterend.helix_tree_door": "Spiralbaumtür", + "block.betterend.helix_tree_fence": "Spiralbaumzaun", + "block.betterend.helix_tree_gate": "Spiralbaumzauntor", + "block.betterend.helix_tree_ladder": "Spiralbaumleiter", + "block.betterend.helix_tree_leaves": "Spiralbaumlaub", + "block.betterend.helix_tree_log": "Spiralbaumstamm", + "block.betterend.helix_tree_planks": "Spiralbaumbretter", + "block.betterend.helix_tree_plate": "Spiralbaumdruckplatte", + "block.betterend.helix_tree_sapling": "Spiralbaumsetzling", + "block.betterend.helix_tree_sign": "Spiralbaumschild", + "block.betterend.helix_tree_slab": "Spiralbaumstufe", + "block.betterend.helix_tree_stairs": "Spiralbaumtreppe", + "block.betterend.helix_tree_stripped_bark": "Entrindetes Spiralbaumholz", + "block.betterend.helix_tree_stripped_log": "Entrindeter Spiralbaumstamm", + "block.betterend.helix_tree_trapdoor": "Spiralbaumfalltür", + "block.betterend.lanceleaf": "Lanzenblatt", + "block.betterend.lanceleaf_seed": "Lanzenblattsamen", + "block.betterend.hydralux": "Hydralux", + "block.betterend.helix_tree_luminophor": "Spiralbaumluminophor", + "block.betterend.glowing_pillar_leaves": "Glühsäulenlaub", + "block.betterend.glowing_pillar_luminophor": "Glühsäulenluminophor", + "block.betterend.glowing_pillar_roots": "Glühsäulenwurzeln", + "block.betterend.glowing_pillar_seed": "Glühsäulensamen", + "biome.betterend.ice_starfield": "Eissternfeld", + "block.betterend.ancient_emerald_ice": "Antikes Smaragdeis", + "block.betterend.dense_emerald_ice": "Dichtes Smaragdeis", + "block.betterend.dense_snow": "Dichter Schnee", + "block.betterend.emerald_ice": "Smaragdeis", + "block.betterend.bulb_moss": "Knollenmoos", + "block.betterend.charnia_green": "Grünes Charnia", + "block.betterend.vent_bubble_column": "Blasenquellensäule", + "block.betterend.respawn_obelisk": "Rücksetzobelisk", + "message.betterend.set_spawn": "\u00A7b\u00A7lWiedereinstiegspunkt gesetzt", + "message.betterend.fail_spawn": "\u00A7c\u00A7lDu musst 6 Bernsteinjuwele in der Hand halten, um deinen Einstiegspunkt zu setzen.", + "block.betterend.dragon_tree_composter": "Drachenbaumkomposter", + "block.betterend.end_lotus_composter": "Endlotuskomposter", + "block.betterend.helix_tree_composter": "Spiralbaumkomposter", + "block.betterend.lacugrove_composter": "Seemangrovenkomposter", + "block.betterend.mossy_glowshroom_composter": "Bemooster Glühpilzkomposter", + "block.betterend.pythadendron_composter": "Pythadendronkomposter", + "block.betterend.tenanea_composter": "Tenaneakomposter", + "biome.betterend.old_bulbis_gardens": "Alte Knollengärten", + "block.betterend.ivis_moss": "Efeumoos", + "block.betterend.ivis_vine": "Efeuranke", + "block.betterend.silk_moth_nest": "Seidenmottennest", + "block.betterend.umbrella_tree_bark": "Schirmbaumholz", + "block.betterend.umbrella_tree_barrel": "Schirmbaumfass", + "block.betterend.umbrella_tree_bookshelf": "Schirmbaumbücherregal", + "block.betterend.umbrella_tree_button": "Schirmbaumknopf", + "block.betterend.umbrella_tree_chest": "Schirmbaumtruhe", + "block.betterend.umbrella_tree_composter": "Schirmbaumkomposter", + "block.betterend.umbrella_tree_crafting_table": "Schirmbaumwerkbank", + "block.betterend.umbrella_tree_door": "Schirmbaumtür", + "block.betterend.umbrella_tree_fence": "Schirmbaumzaun", + "block.betterend.umbrella_tree_gate": "Schirmbaumzauntor", + "block.betterend.umbrella_tree_ladder": "Schirmbaumleiter", + "block.betterend.umbrella_tree_log": "Schirmbaumstamm", + "block.betterend.umbrella_tree_planks": "Schirmbaumbretter", + "block.betterend.umbrella_tree_plate": "Schirmbaumdruckplatte", + "block.betterend.umbrella_tree_sign": "Schirmbaumschild", + "block.betterend.umbrella_tree_slab": "Schirmbaumstufe", + "block.betterend.umbrella_tree_stairs": "Schirmbaumtreppe", + "block.betterend.umbrella_tree_stripped_bark": "Entrindetes Schirmbaumholz", + "block.betterend.umbrella_tree_stripped_log": "Entrindeter Schirmbaumstamm", + "block.betterend.umbrella_tree_trapdoor": "Schirmbaumfalltür", + "block.betterend.umbrella_tree_membrane": "Schirmbaummembran", + "biome.betterend.umbrella_jungle": "Schirmdschungel", + "block.betterend.jungle_grass": "Dschungelgras", + "block.betterend.jungle_moss": "Dschungelmoos", + "block.betterend.jungle_moss_path": "Dschungelmoospfad", + "block.betterend.small_jellyshroom": "Kleiner Geleepilz", + "block.betterend.twisted_umbrella_moss": "Zwirbelschirmmoos", + "block.betterend.twisted_umbrella_moss_tall": "Großes Zwirbelschirmmoos", + "block.betterend.umbrella_tree_cluster": "Schirmtraube", + "block.betterend.umbrella_tree_cluster_empty": "Leere Schirmtrauben", + "block.betterend.jungle_vine": "Dschungelranke", + "block.betterend.jungle_fern": "Dschungelfarn", + "block.betterend.jellyshroom_bark": "Geleepilzholz", + "block.betterend.jellyshroom_barrel": "Geleepilzfass", + "block.betterend.jellyshroom_bookshelf": "Geleepilzbücherregal", + "block.betterend.jellyshroom_button": "Geleepilzknopf", + "block.betterend.jellyshroom_cap_purple": "Violette Geleepilzkappe", + "block.betterend.jellyshroom_chest": "Geleepilztruhe", + "block.betterend.jellyshroom_composter": "Geleepilzkomposter", + "block.betterend.jellyshroom_crafting_table": "Geleepilzwerkbank", + "block.betterend.jellyshroom_door": "Geleepilztür", + "block.betterend.jellyshroom_fence": "Geleepilzzaun", + "block.betterend.jellyshroom_gate": "Geleepilzzauntor", + "block.betterend.jellyshroom_ladder": "Geleepilzleiter", + "block.betterend.jellyshroom_log": "Geleepilzstamm", + "block.betterend.jellyshroom_planks": "Geleepilzbretter", + "block.betterend.jellyshroom_plate": "Geleepilzdruckplatte", + "block.betterend.jellyshroom_sign": "Geleepilzschild", + "block.betterend.jellyshroom_slab": "Geleepilzstufe", + "block.betterend.jellyshroom_stairs": "Geleepilztreppe", + "block.betterend.jellyshroom_stripped_bark": "Entrindetes Geleepilzholz", + "block.betterend.jellyshroom_stripped_log": "Entrindeter Geleepilzstamm", + "block.betterend.jellyshroom_trapdoor": "Geleepilzfalltür", + "biome.betterend.eterial_grove": "Äthermangrove", + "block.betterend.umbrella_tree_sapling": "Schirmbaumsetzling", + "item.betterend.umbrella_cluster_juice": "Schirmtraubensaft", + "block.betterend.blossom_berry_seed": "Blütenbeerensamen", + "item.betterend.blossom_berry": "Blütenbeere", + "biome.betterend.nightshade_redwoods": "Nachtschattenrotwald", + "block.betterend.nightshade_moss": "Nachtschattenmoos", + "biome.betterend.glowing_grasslands": "Glühende Wiesen", + "block.betterend.blooming_cooksonia": "Blühende Cooksonia", + "block.betterend.fracturn": "Fraktur", + "block.betterend.lumecorn": "Maislicht", + "block.betterend.salteago": "Salzeago", + "block.betterend.vaiolush_fern": "Vaiosatt Farn", + "entity.betterend.silk_moth": "Seidenmotte", + "item.betterend.silk_fiber": "Seidenfaser", + "item.betterend.spawn_egg_silk_moth": "Seidenmotten-Spawn-Ei", + "block.betterend.thallasium_ore": "Thallasiumerz", + "item.betterend.thallasium_axe": "Thallasiumaxt", + "item.betterend.thallasium_hoe": "Thallasiumhacke", + "item.betterend.thallasium_ingot": "Thallasiumbarren", + "item.betterend.thallasium_pickaxe": "Thallasiumspitzhacke", + "item.betterend.thallasium_shovel": "Thallasiumschaufel", + "item.betterend.thallasium_sword": "Thallasiumschwert", + "block.betterend.thallasium_block": "Thallasiumblock", + "block.betterend.thallasium_bars": "Thallasiumgitter", + "block.betterend.thallasium_door": "Thallasiumtür", + "block.betterend.thallasium_plate": "Thallasiumdruckplatte", + "block.betterend.thallasium_tile": "Thallasiumfliesen", + "block.betterend.thallasium_trapdoor": "Thallasiumfalltür", + "block.betterend.lumecorn_seed": "Maislichtsamen", + "item.betterend.lumecorn_rod": "Maislichtstange", + "block.betterend.thallasium_chandelier": "Thallasiumkronleuchter", + "block.betterend.thallasium_anvil": "Thallasiumamboss", + "block.betterend.thallasium_chain": "Thallasiumkette", + "block.betterend.thallasium_slab": "Thallasiumstufe", + "block.betterend.thallasium_stairs": "Thallasiumtreppe", + "block.betterend.gold_chandelier": "Goldkronleuchter", + "block.betterend.iron_chandelier": "Eisenkronleuchter", + "item.betterend.thallasium_nugget": "Thallasiumklumpen", + "block.betterend.terminite_anvil": "Terminitamboss", + "block.betterend.terminite_bars": "Terminitgitter", + "block.betterend.terminite_bulb_lantern": "Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_black": "Schwarze Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_blue": "Blaue Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_brown": "Braune Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_cyan": "Türkise Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_gray": "Graue Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_green": "Green Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_light_blue": "Hellblaue Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_light_gray": "Hellgraue Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_lime": "Hellgrüne Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_magenta": "Magenta Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_orange": "Orangene Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_pink": "Pinke Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_purple": "Violette Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_red": "Rote Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_white": "Weiße Terminitknollenlaterne", + "block.betterend.terminite_bulb_lantern_yellow": "Gelbe Terminitknollenlaterne", + "block.betterend.terminite_chain": "Terminitkette", + "block.betterend.terminite_chandelier": "Terminitkronleuchter", + "block.betterend.terminite_door": "Terminittür", + "block.betterend.terminite_plate": "Terminitdruckplatte", + "block.betterend.terminite_slab": "Terminitstufe", + "block.betterend.terminite_stairs": "Terminittreppe", + "block.betterend.terminite_tile": "Terminitfliesen", + "block.betterend.terminite_trapdoor": "Terminitfalltür", + "item.betterend.terminite_nugget": "Terminitklumpen", + "item.betterend.thallasium_boots": "Thallasiumstiefel", + "item.betterend.thallasium_chestplate": "Thallasiumharnisch", + "item.betterend.thallasium_hammer": "Thallasiumschmiedehammer", + "item.betterend.thallasium_helmet": "Thallasiumhelm", + "item.betterend.thallasium_leggings": "Thallasiumbeinschutz", + "block.betterend.missing_tile": "Fehlende Fliesen", + "block.betterend.charcoal_block": "Holzkohleblock", + "block.betterend.end_stone_furnace": "Endsteinofen", + "block.betterend.flavolite_furnace": "Flavolitofen", + "block.betterend.sulphuric_rock_furnace": "Schwefelsteinofen", + "block.betterend.violecite_furnace": "Violezitofen", + "item.betterend.terminite_axe_head": "Terminitaxtkopf", + "item.betterend.terminite_hoe_head": "Terminithackenkopf", + "item.betterend.terminite_pickaxe_head": "Terminitspitzhackenkopf", + "item.betterend.terminite_shovel_head": "Terminitschaufelkopf", + "item.betterend.terminite_sword_blade": "Terminitschwertklinge", + "item.betterend.terminite_sword_handle": "Terminitschwertgriff", + "item.betterend.thallasium_axe_head": "Thallasiumaxtkopf", + "item.betterend.thallasium_hoe_head": "Thallasiumhackenkopf", + "item.betterend.thallasium_pickaxe_head": "Thallasiumspitzhackenkopf", + "item.betterend.thallasium_shovel_head": "Thallasiumschaufelkopf", + "item.betterend.thallasium_sword_blade": "Thallasiumschwertklinge", + "item.betterend.thallasium_sword_handle": "Thallasiumschwertgriff", + "block.betterend.aeternium_anvil": "Ätheramboss", + "tag.betterend.alloying_iron": "Eisenerze", + "tag.betterend.alloying_copper": "Kupfererze", + "tag.betterend.alloying_gold": "Golderze", + "tag.betterend.thallasium_alloying": "Thallasiumerze", + "tag.betterend.jellyshroom_logs": "Geleepilzstämme", + "tag.betterend.umbrella_tree_logs": "Schirmbaumstämme", + "tag.betterend.lacugrove_logs": "Seemangrovenstämme", + "tag.betterend.end_lotus_logs": "End-Lotusstämme", + "tag.betterend.pythadendron_logs": "Pythadendronstämme", + "tag.betterend.helix_tree_logs": "Helix-Baumstämme", + "tag.betterend.lucernia_logs": "Lucerniastäme", + "tag.betterend.dragon_tree_logs": "Drachenbaumstämme", + "tag.betterend.mossy_glowshroom_logs": "Bemooste Glühpilzstämme", + "tag.betterend.tenanea_logs": "Tenaneastämme", + "emi.category.betterend.infusion": "Elementarrituale", + "betterend.infusion.north": "Nördlicher Sockel", + "betterend.infusion.north_west": "Nordwestlicher Sockel", + "betterend.infusion.west": "Westlicher Sockel", + "betterend.infusion.south_west": "Südwestlicher Sockel", + "betterend.infusion.south": "Südlicher Sockel", + "betterend.infusion.south_east": "Südöstlicher Sockel", + "betterend.infusion.east": "Östlicher Sockel", + "betterend.infusion.north_east": "Nordöstlicher Sockel", + "advancements.betterend.root.title": "BetterEnd", + "advancements.betterend.root.description": "Pfad der Eweigkeit", + "advancements.betterend.portal.title": "Die Ewigkeit und zurück", + "advancements.betterend.portal.description": "Entdecke ein verlorenes seit Ewigkeiten verlorenes Portal", + "advancements.betterend.portal_on.title": "Wege der Ewigkeit", + "advancements.betterend.portal_on.description": "Entfache ein ewiges Portal", + "advancements.betterend.all_the_biomes.title": "Ein Neues Ende", + "advancements.betterend.all_the_biomes.description": "Besuche alle BetterEnd Biome", + "advancements.betterend.all_elytras.title": "Flugshow", + "advancements.betterend.all_elytras.description": "Besitze alle Elytra Varianten", + "advancements.betterend.infusion.title": "Elementarmagie", + "advancements.betterend.infusion.description": "Erhalte eine Elementarsockel", + "advancements.betterend.infusion_finished.title": "Unendliche Möglichkeiten", + "advancements.betterend.infusion_finished.description": "Sei dabei wenn ein Elementarritual abgeschlossen wird." } diff --git a/src/main/resources/assets/betterend/lang/en_us.json b/src/main/resources/assets/betterend/lang/en_us.json index 32e011b0..44f31405 100644 --- a/src/main/resources/assets/betterend/lang/en_us.json +++ b/src/main/resources/assets/betterend/lang/en_us.json @@ -1,877 +1,860 @@ { - "itemGroup.betterend.end_items": "Better End: Items", - "itemGroup.betterend.end_blocks": "Better End: Blocks", - - "item.betterend.guidebook": "The End for Dummies", - "book.betterend.landing": "A short guide about surviving in the extreme conditions of The End.", - "book.betterend.subtitle": "Survive in The End", - - "category.rei.damage.amount&dmg": "Tool damage: %s", - "category.rei.infusion.time&val": "Time: %s", - - "biome.betterend.foggy_mushroomland": "Foggy Mushroomland", - "biome.betterend.dust_wastelands": "Dust Wastelands", - "biome.betterend.chorus_forest": "Chorus Forest", - "biome.betterend.megalake": "Megalake", - "biome.betterend.crystal_mountains": "Crystal Mountains", - - "entity.betterend.dragonfly": "Dragonfly", - "item.betterend.spawn_egg_dragonfly": "Dragonfly Spawn Egg", - - "entity.betterend.end_slime": "End Slime", - "item.betterend.spawn_egg_end_slime": "End Slime Spawn Egg", - - "block.betterend.end_mycelium": "End Mycelium", - "block.betterend.end_moss": "End Moss", - "block.betterend.endstone_dust": "End Stone Dust", - - "block.betterend.end_mycelium_path": "End Mycelium Path", - "block.betterend.end_moss_path": "End Moss Path", - - "block.betterend.ender_ore": "Ender Ore", - "block.betterend.terminite_block": "Terminite Block", - "block.betterend.aeternium_block": "Aeternium Block", - "block.betterend.ender_block": "Ender Block", - "block.betterend.end_stone_smelter": "End Stone Smelter", - - "item.betterend.ender_dust": "Ender Dust", - "item.betterend.ender_shard": "Ender Shard", - "item.betterend.terminite_ingot": "Terminite Ingot", - "item.betterend.aeternium_ingot": "Aeternium Ingot", - "item.betterend.terminite_helmet": "Terminite Helmet", - "item.betterend.terminite_chestplate": "Terminite Chestplate", - "item.betterend.terminite_leggings": "Terminite Leggings", - "item.betterend.terminite_boots": "Terminite Boots", - "item.betterend.terminite_shovel": "Terminite Shovel", - "item.betterend.terminite_sword": "Terminite Sword", - "item.betterend.terminite_pickaxe": "Terminite Pickaxe", - "item.betterend.terminite_axe": "Terminite Axe", - "item.betterend.terminite_hoe": "Terminite Hoe", - "item.betterend.terminite_hammer": "Terminite Smith Hammer", - "item.betterend.aeternium_helmet": "Aeternium Helmet", - "item.betterend.aeternium_chestplate": "Aeternium Chestplate", - "item.betterend.aeternium_leggings": "Aeternium Leggings", - "item.betterend.aeternium_boots": "Aeternium Boots", - "item.betterend.aeternium_shovel": "Aeternium Shovel", - "item.betterend.aeternium_sword": "Aeternium Sword", - "item.betterend.aeternium_pickaxe": "Aeternium Pickaxe", - "item.betterend.aeternium_axe": "Aeternium Axe", - "item.betterend.aeternium_hoe": "Aeternium Hoe", - "item.betterend.aeternium_hammer": "Aeternium Smith Hammer", - "item.betterend.iron_hammer": "Iron Smith Hammer", - "item.betterend.golden_hammer": "Golden Smith Hammer", - "item.betterend.diamond_hammer": "Diamond Smith Hammer", - "item.betterend.netherite_hammer": "Netherite Smith Hammer", - "item.betterend.crystalite_boots": "Crystalite Boots", - "item.betterend.crystalite_chestplate": "Crystalite Chestplate", - "item.betterend.crystalite_helmet": "Crystalite Helmet", - "item.betterend.crystalite_leggings": "Crystalite Leggings", - "item.betterend.aeternium_axe_head": "Aeternium Axe Head", - "item.betterend.aeternium_hammer_head": "Aeternium Hammer Head", - "item.betterend.aeternium_hoe_head": "Aeternium Hoe Head", - "item.betterend.aeternium_pickaxe_head": "Aeternium Pickaxe Head", - "item.betterend.aeternium_shovel_head": "Aeternium Shovel Head", - "item.betterend.aeternium_sword_blade": "Aeternium Sword Blade", - "item.betterend.aeternium_sword_handle": "Aeternium Sword Handle", - "item.betterend.leather_stripe": "Leather Stripe", - "item.betterend.leather_wrapped_stick": "Leather Wrapped Stick", - "item.betterend.elytra_armored": "Armored Elytra", - "item.betterend.elytra_crystalite": "Elytra Crystalite", - "item.betterend.enchanted_membrane": "Enchanted Membrane", - - "effect.betterend.end_veil": "End Veil", - "enchantment.betterend.end_veil": "End Veil", - "item.minecraft.potion.effect.end_veil": "Potion Of End Veil", - "item.minecraft.potion.effect.long_end_veil": "Potion Of End Veil", - "item.minecraft.splash_potion.effect.end_veil": "Splash Potion Of End Veil", - "item.minecraft.splash_potion.effect.long_end_veil": "Splash Potion Of End Veil", - "item.minecraft.lingering_potion.effect.end_veil": "Lingering Potion Of End Veil", - "item.minecraft.lingering_potion.effect.long_end_veil": "Lingering Potion Of End Veil", - "item.minecraft.tipped_arrow.effect.end_veil": "Arrow Of End Veil", - "item.minecraft.tipped_arrow.effect.long_end_veil": "Arrow Of End Veil", - - "block.betterend.mossy_glowshroom_sapling": "Mossy Glowshroom Sapling", - "block.betterend.mossy_glowshroom_cap": "Mossy Glowshroom Cap", - "block.betterend.mossy_glowshroom_fur": "Mossy Glowshroom Fur", - "block.betterend.mossy_glowshroom_hymenophore": "Mossy Glowshroom Hymenophore", - "block.betterend.mossy_glowshroom_bark": "Mossy Glowshroom Bark", - "block.betterend.mossy_glowshroom_barrel": "Mossy Glowshroom Barrel", - "block.betterend.mossy_glowshroom_button": "Mossy Glowshroom Button", - "block.betterend.mossy_glowshroom_chest": "Mossy Glowshroom Chest", - "block.betterend.mossy_glowshroom_crafting_table": "Mossy Glowshroom Crafting Table", - "block.betterend.mossy_glowshroom_door": "Mossy Glowshroom Door", - "block.betterend.mossy_glowshroom_fence": "Mossy Glowshroom Fence", - "block.betterend.mossy_glowshroom_gate": "Mossy Glowshroom Gate", - "block.betterend.mossy_glowshroom_ladder": "Mossy Glowshroom Ladder", - "block.betterend.mossy_glowshroom_log": "Mossy Glowshroom Log", - "block.betterend.mossy_glowshroom_planks": "Mossy Glowshroom Planks", - "block.betterend.mossy_glowshroom_plate": "Mossy Glowshroom Pressure Plate", - "block.betterend.mossy_glowshroom_sign": "Mossy Glowshroom Sign", - "block.betterend.mossy_glowshroom_slab": "Mossy Glowshroom Slab", - "block.betterend.mossy_glowshroom_stairs": "Mossy Glowshroom Stairs", - "block.betterend.mossy_glowshroom_stripped_bark": "Stripped Mossy Glowshroom Bark", - "block.betterend.mossy_glowshroom_stripped_log": "Stripped Mossy Glowshroom Log", - "block.betterend.mossy_glowshroom_trapdoor": "Mossy Glowshroom Trapdoor", - - "block.betterend.umbrella_moss": "Umbrella Moss", - "block.betterend.umbrella_moss_tall": "Tall Umbrella Moss", - "block.betterend.creeping_moss": "Creeping Moss", - - "block.betterend.blue_vine_seed": "Blue Vine Seed", - "block.betterend.blue_vine": "Blue Vine", - "block.betterend.blue_vine_lantern": "Blue Vine Lantern", - "block.betterend.blue_vine_fur": "Blue Vine Fur", - - "block.betterend.dense_vine": "Dense Vine", - "block.betterend.bubble_coral": "Bubble Coral", - "block.betterend.aurora_crystal": "Aurora Crystal", - "item.betterend.crystal_shards": "Crystal Shards", - - "block.betterend.pythadendron_sapling": "Pythadendron Sapling", - "block.betterend.pythadendron_bark": "Pythadendron Bark", - "block.betterend.pythadendron_barrel": "Pythadendron Barrel", - "block.betterend.pythadendron_button": "Pythadendron Button", - "block.betterend.pythadendron_chest": "Pythadendron Chest", - "block.betterend.pythadendron_crafting_table": "Pythadendron Crafting Table", - "block.betterend.pythadendron_door": "Pythadendron Door", - "block.betterend.pythadendron_fence": "Pythadendron Fence", - "block.betterend.pythadendron_gate": "Pythadendron Gate", - "block.betterend.pythadendron_ladder": "Pythadendron Ladder", - "block.betterend.pythadendron_log": "Pythadendron Log", - "block.betterend.pythadendron_planks": "Pythadendron Planks", - "block.betterend.pythadendron_plate": "Pythadendron Pressure Plate", - "block.betterend.pythadendron_sign": "Pythadendron Sign", - "block.betterend.pythadendron_slab": "Pythadendron Slab", - "block.betterend.pythadendron_stairs": "Pythadendron Stairs", - "block.betterend.pythadendron_stripped_bark": "Stripped Pythadendron Bark", - "block.betterend.pythadendron_stripped_log": "Stripped Pythadendron Log", - "block.betterend.pythadendron_trapdoor": "Pythadendron Trapdoor", - - "block.betterend.chorus_nylium": "Chorus Nylium", - "block.betterend.chorus_nylium_path": "Chorus Nylium Path", - "block.betterend.chorus_grass": "Chorus Grass", - - "block.betterend.end_lily": "End Lily", - "block.betterend.end_lily_seed": "End Lily Seed", - "item.betterend.end_lily_leaf": "End Lily Leaf", - "item.betterend.end_lily_leaf_dried": "End Lily Leaf Dried", - - "block.betterend.violecite": "Violecite", - "block.betterend.violecite_bricks": "Violecite Bricks", - "block.betterend.violecite_bricks_slab": "Violecite Brick Slab", - "block.betterend.violecite_bricks_stairs": "Violecite Brick Stairs", - "block.betterend.violecite_bricks_wall": "Violecite Brick Wall", - "block.betterend.violecite_button": "Violecite Button", - "block.betterend.violecite_pillar": "Violecite Pillar", - "block.betterend.violecite_plate": "Violecite Pressure Plate", - "block.betterend.violecite_slab": "Violecite Slab", - "block.betterend.violecite_tiles": "Violecite Tiles", - "block.betterend.violecite_stairs": "Violecite Stairs", - "block.betterend.violecite_polished": "Polished Violecite", - "block.betterend.violecite_wall": "Violecite Wall", - "block.betterend.violecite_pedestal": "Violecite Pedestal", - - "block.betterend.flavolite": "Flavolite", - "block.betterend.flavolite_bricks": "Flavolite Bricks", - "block.betterend.flavolite_bricks_slab": "Flavolite Brick Slab", - "block.betterend.flavolite_bricks_stairs": "Flavolite Brick Stairs", - "block.betterend.flavolite_bricks_wall": "Flavolite Brick Wall", - "block.betterend.flavolite_button": "Flavolite Button", - "block.betterend.flavolite_pillar": "Flavolite Pillar", - "block.betterend.flavolite_plate": "Flavolite Pressure Plate", - "block.betterend.flavolite_slab": "Flavolite Slab", - "block.betterend.flavolite_tiles": "Flavolite Tiles", - "block.betterend.flavolite_stairs": "Flavolite Stairs", - "block.betterend.flavolite_polished": "Polished Flavolite", - "block.betterend.flavolite_wall": "Flavolite Wall", - "block.betterend.flavolite_pedestal": "Flavolite Pedestal", - - "block.betterend.andesite_pedestal": "Andesite Pedestal", - "block.betterend.diorite_pedestal": "Diorite Pedestal", - "block.betterend.granite_pedestal": "Granite Pedestal", - "block.betterend.purpur_pedestal": "Purpur Pedestal", - "block.betterend.quartz_pedestal": "Quartz Pedestal", - "block.betterend.infusion_pedestal": "Infusion Pedestal", - - "block.betterend.end_lotus_seed": "End Lotus Seed", - "block.betterend.end_lotus_stem": "End Lotus Stem", - "block.betterend.end_lotus_leaf": "End Lotus Leaf", - "block.betterend.end_lotus_flower": "End Lotus Flower", - - "block.betterend.end_lotus_bark": "End Lotus Bark", - "block.betterend.end_lotus_barrel": "End Lotus Barrel", - "block.betterend.end_lotus_button": "End Lotus Button", - "block.betterend.end_lotus_chest": "End Lotus Chest", - "block.betterend.end_lotus_crafting_table": "End Lotus Crafting Table", - "block.betterend.end_lotus_door": "End Lotus Door", - "block.betterend.end_lotus_fence": "End Lotus Fence", - "block.betterend.end_lotus_gate": "End Lotus Gate", - "block.betterend.end_lotus_ladder": "End Lotus Ladder", - "block.betterend.end_lotus_log": "End Lotus Log", - "block.betterend.end_lotus_planks": "End Lotus Planks", - "block.betterend.end_lotus_plate": "End Lotus Pressure Plate", - "block.betterend.end_lotus_sign": "End Lotus Sign", - "block.betterend.end_lotus_slab": "End Lotus Slab", - "block.betterend.end_lotus_stairs": "End Lotus Stairs", - "block.betterend.end_lotus_stripped_bark": "Stripped End Lotus Bark", - "block.betterend.end_lotus_stripped_log": "Stripped End Lotus Log", - "block.betterend.end_lotus_trapdoor": "End Lotus Trapdoor", - - "block.betterend.cave_moss": "Cave Moss", - "block.betterend.cave_grass": "Cave Grass", - "block.betterend.cave_bush": "Cave Bush", - - "block.betterend.cave_moss_path": "Cave Moss Path", - "block.betterend.crystal_moss": "Crystal Moss", - "block.betterend.crystal_moss_path": "Crystal Moss Path", - "block.betterend.pythadendron_leaves": "Pythadendron Leaves", - "item.betterend.spawn_egg_end_fish": "End Fish Spawn Egg", - "block.betterend.crystal_grass": "Crystal Grass", - - "block.betterend.flavolite_runed": "Runed Flavolite", - "block.betterend.end_portal_block": "End Portal", - "block.betterend.eternal_pedestal": "Eternal Pedestal", - "block.betterend.flavolite_runed_eternal": "Eternal Runed Flavolite", - "item.betterend.eternal_crystal": "Eternal Crystal", - - "block.betterend.lacugrove_bark": "Lacugrove Bark", - "block.betterend.lacugrove_barrel": "Lacugrove Barrel", - "block.betterend.lacugrove_button": "Lacugrove Button", - "block.betterend.lacugrove_chest": "Lacugrove Chest", - "block.betterend.lacugrove_crafting_table": "Lacugrove Crafting Table", - "block.betterend.lacugrove_door": "Lacugrove Door", - "block.betterend.lacugrove_fence": "Lacugrove Fence", - "block.betterend.lacugrove_gate": "Lacugrove Gate", - "block.betterend.lacugrove_ladder": "Lacugrove Ladder", - "block.betterend.lacugrove_log": "Lacugrove Log", - "block.betterend.lacugrove_planks": "Lacugrove Planks", - "block.betterend.lacugrove_plate": "Lacugrove Pressure Plate", - "block.betterend.lacugrove_sign": "Lacugrove Sign", - "block.betterend.lacugrove_slab": "Lacugrove Slab", - "block.betterend.lacugrove_stairs": "Lacugrove Stairs", - "block.betterend.lacugrove_stripped_bark": "Stripped Lacugrove Bark", - "block.betterend.lacugrove_stripped_log": "Stripped Lacugrove Log", - "block.betterend.lacugrove_trapdoor": "Lacugrove Trapdoor", - - "block.betterend.lacugrove_leaves": "Lacugrove Leaves", - "block.betterend.lacugrove_sapling": "Lacugrove Sapling", - - "biome.betterend.megalake_grove": "Megalake Grove", - "biome.betterend.painted_mountains": "Painted Mountains", - - "block.betterend.dragon_tree_bark": "Dragon Tree Bark", - "block.betterend.dragon_tree_barrel": "Dragon Tree Barrel", - "block.betterend.dragon_tree_button": "Dragon Tree Button", - "block.betterend.dragon_tree_chest": "Dragon Tree Chest", - "block.betterend.dragon_tree_crafting_table": "Dragon Tree Crafting Table", - "block.betterend.dragon_tree_door": "Dragon Tree Door", - "block.betterend.dragon_tree_fence": "Dragon Tree Fence", - "block.betterend.dragon_tree_gate": "Dragon Tree Gate", - "block.betterend.dragon_tree_ladder": "Dragon Tree Ladder", - "block.betterend.dragon_tree_log": "Dragon Tree Log", - "block.betterend.dragon_tree_planks": "Dragon Tree Planks", - "block.betterend.dragon_tree_plate": "Dragon Tree Pressure Plate", - "block.betterend.dragon_tree_sign": "Dragon Tree Sign", - "block.betterend.dragon_tree_slab": "Dragon Tree Slab", - "block.betterend.dragon_tree_stairs": "Dragon Tree Stairs", - "block.betterend.dragon_tree_stripped_bark": "Stripped Dragon Tree Bark", - "block.betterend.dragon_tree_stripped_log": "Stripped Dragon Tree Log", - "block.betterend.dragon_tree_trapdoor": "Dragon Tree Trapdoor", - - "biome.betterend.shadow_forest": "Shadow Forest", - "block.betterend.dragon_tree_leaves": "Dragon Tree Leaves", - "block.betterend.dragon_tree_sapling": "Dragon Tree Sapling", - "block.betterend.shadow_grass": "Shadow Grass", - "block.betterend.shadow_grass_path": "Shadow Grass Path", - "block.betterend.shadow_plant": "Shadow Plant", - - "block.betterend.dragon_tree_bookshelf": "Dragon Tree Bookshelf", - "block.betterend.end_lotus_bookshelf": "End Lotus Bookshelf", - "block.betterend.lacugrove_bookshelf": "Lacugrove Bookshelf", - "block.betterend.mossy_glowshroom_bookshelf": "Mossy Glowshroom Bookshelf", - "block.betterend.pythadendron_bookshelf": "Pythadendron Bookshelf", - - "block.betterend.murkweed": "Murkweed", - "block.betterend.needlegrass": "Needlegrass", - "block.betterend.twisted_vine": "Twisted Vine", - - "block.betterend.shadow_berry": "Shadow Berry Seeds", - "item.betterend.shadow_berry_cooked": "Shadow Berry Cooked", - "item.betterend.shadow_berry_raw": "Shadow Berry", - "block.betterend.purple_polypore": "Purple Polypore", - - "block.betterend.cyan_moss": "Cyan Moss", - "block.betterend.tail_moss": "Tail Moss", - - "block.betterend.flavolite_lantern": "Flavolite Lantern", - "block.betterend.end_stone_lantern": "End Stone Lantern", - "block.betterend.violecite_lantern": "Violecite Lantern", - - "entity.betterend.end_fish": "End Fish", - "entity.betterend.shadow_walker": "Shadow Walker", - "item.betterend.spawn_egg_shadow_walker": "Shadow Walker Spawn Egg", - - "block.betterend.andesite_lantern": "Andesite Lantern", - "block.betterend.blackstone_lantern": "Blackstone Lantern", - "block.betterend.diorite_lantern": "Diorite Lantern", - "block.betterend.granite_lantern": "Granite Lantern", - "block.betterend.purpur_lantern": "Purpur Lantern", - "block.betterend.quartz_lantern": "Quartz Lantern", - - "item.betterend.bucket_end_fish": "Bucket of End Fish", - "item.betterend.bucket_cubozoa": "Bucket of Cubozoa", - "item.betterend.end_fish_cooked": "Cooked End Fish", - "item.betterend.end_fish_raw": "End Fish", - - "biome.betterend.amber_land": "Amber Land", - "biome.betterend.blossoming_spires": "Blossoming Spires", - "block.betterend.amber_grass": "Amber Grass", - "block.betterend.amber_grass_path": "Amber Grass Path", - "block.betterend.tenanea_bark": "Tenanea Bark", - "block.betterend.tenanea_barrel": "Tenanea Barrel", - "block.betterend.tenanea_bookshelf": "Tenanea Bookshelf", - "block.betterend.tenanea_button": "Tenanea Button", - "block.betterend.tenanea_chest": "Tenanea Chest", - "block.betterend.tenanea_crafting_table": "Tenanea Crafting Table", - "block.betterend.tenanea_door": "Tenanea Door", - "block.betterend.tenanea_fence": "Tenanea Fence", - "block.betterend.tenanea_gate": "Tenanea Gate", - "block.betterend.tenanea_ladder": "Tenanea Ladder", - "block.betterend.tenanea_leaves": "Tenanea Leaves", - "block.betterend.tenanea_log": "Tenanea Log", - "block.betterend.tenanea_planks": "Tenanea Planks", - "block.betterend.tenanea_plate": "Tenanea Pressure Plate", - "block.betterend.tenanea_sapling": "Tenanea Sapling", - "block.betterend.tenanea_sign": "Tenanea Sign", - "block.betterend.tenanea_slab": "Tenanea Slab", - "block.betterend.tenanea_stairs": "Tenanea Stairs", - "block.betterend.tenanea_stripped_bark": "Stripped Tenanea Bark", - "block.betterend.tenanea_stripped_log": "Stripped Tenanea Log", - "block.betterend.tenanea_trapdoor": "Tenanea Trapdoor", - - "block.betterend.amber_block": "Amber Block", - "block.betterend.amber_ore": "Amber Ore", - "item.betterend.amber_gem": "Amber Gem", - "item.betterend.raw_amber": "Raw Amber", - "block.betterend.tenanea_flowers": "Tenanea Flowers", - "block.betterend.tenanea_outer_leaves": "Tenanea Outer Leaves", - - "block.betterend.pink_moss": "Pink Moss", - "block.betterend.pink_moss_path": "Pink Moss Path", - - "block.betterend.twisted_moss": "Twisted Moss", - - "block.betterend.bulb_vine": "Bulb Vine", - "block.betterend.bulb_vine_seed": "Bulb Vine Seed", - "item.betterend.glowing_bulb": "Glowing Bulb", - - "block.betterend.iron_bulb_lantern": "Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_black": "Black Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_blue": "Blue Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_brown": "Brown Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_cyan": "Cyan Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_gray": "Gray Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_green": "Green Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_light_blue": "Light Blue Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_light_gray": "Light Gray Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_lime": "Lime Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_magenta": "Magenta Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_orange": "Orange Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_pink": "Pink Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_purple": "Purple Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_red": "Red Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_white": "White Iron Bulb Lantern", - "block.betterend.iron_bulb_lantern_yellow": "Yellow Iron Bulb Lantern", - - "block.betterend.thallasium_bulb_lantern": "Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_black": "Black Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_blue": "Blue Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_brown": "Brown Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_cyan": "Cyan Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_gray": "Gray Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_green": "Green Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_light_blue": "Light Blue Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_light_gray": "Light Gray Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_lime": "Lime Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_magenta": "Magenta Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_orange": "Orange Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_pink": "Pink Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_purple": "Purple Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_red": "Red Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_white": "White Thallasium Bulb Lantern", - "block.betterend.thallasium_bulb_lantern_yellow": "Yellow Thallasium Bulb Lantern", - - "block.betterend.bushy_grass": "Bushy Grass", - - "block.betterend.brimstone": "Brimstone", - "block.betterend.sulphuric_rock": "Sulfuric Rock", - "block.betterend.sulphuric_rock_bricks": "Sulfuric Rock Bricks", - "block.betterend.sulphuric_rock_bricks_slab": "Sulfuric Rock Brick Slab", - "block.betterend.sulphuric_rock_bricks_stairs": "Sulfuric Rock Brick Stairs", - "block.betterend.sulphuric_rock_bricks_wall": "Sulfuric Rock Brick Wall", - "block.betterend.sulphuric_rock_button": "Sulfuric Rock Button", - "block.betterend.sulphuric_rock_lantern": "Sulfuric Rock Lantern", - "block.betterend.sulphuric_rock_pedestal": "Sulfuric Rock Pedestal", - "block.betterend.sulphuric_rock_pillar": "Sulfuric Rock Pillar", - "block.betterend.sulphuric_rock_plate": "Sulfuric Rock Pressure Plate", - "block.betterend.sulphuric_rock_polished": "Sulfuric Rock Polished", - "block.betterend.sulphuric_rock_slab": "Sulfuric Rock Slab", - "block.betterend.sulphuric_rock_stairs": "Sulfuric Rock Stairs", - "block.betterend.sulphuric_rock_tiles": "Sulfuric Rock Tiles", - "block.betterend.sulphuric_rock_wall": "Sulfuric Rock Wall", - "block.betterend.sulphur_crystal": "Sulfur Crystal", - "item.betterend.crystalline_sulphur": "Sulfur", - - "biome.betterend.sulphur_springs": "Sulfur Springs", - "block.betterend.hydralux_petal_block": "Hydralux Petal Block", - "block.betterend.hydralux_petal_block_black": "Black Petal Block", - "block.betterend.hydralux_petal_block_blue": "Blue Petal Block", - "block.betterend.hydralux_petal_block_brown": "Brown Petal Block", - "block.betterend.hydralux_petal_block_cyan": "Cyan Petal Block", - "block.betterend.hydralux_petal_block_gray": "Gray Petal Block", - "block.betterend.hydralux_petal_block_green": "Green Petal Block", - "block.betterend.hydralux_petal_block_light_blue": "Light Blue Petal Block", - "block.betterend.hydralux_petal_block_light_gray": "Light Gray Petal Block", - "block.betterend.hydralux_petal_block_lime": "Lime Petal Block", - "block.betterend.hydralux_petal_block_magenta": "Magenta Petal Block", - "block.betterend.hydralux_petal_block_orange": "Orange Petal Block", - "block.betterend.hydralux_petal_block_pink": "Pink Petal Block", - "block.betterend.hydralux_petal_block_purple": "Purple Petal Block", - "block.betterend.hydralux_petal_block_red": "Red Petal Block", - "block.betterend.hydralux_petal_block_white": "White Petal Block", - "block.betterend.hydralux_petal_block_yellow": "Yellow Petal Block", - "block.betterend.hydralux_sapling": "Hydralux Sapling", - "block.betterend.hydrothermal_vent": "Hydrothermal Vent", - "item.betterend.hydralux_petal": "Hydralux Petal", - "item.betterend.enchanted_petal": "Enchanted Petal", - - "block.betterend.menger_sponge": "Menger Sponge", - "block.betterend.menger_sponge_wet": "Wet Menger Sponge", - "block.betterend.tube_worm": "Tube Worm", - - "block.betterend.charnia_cyan": "Cyan Charnia", - "block.betterend.charnia_light_blue": "Light Blue Charnia", - "block.betterend.charnia_orange": "Orange Charnia", - "block.betterend.charnia_purple": "Purple Charnia", - "block.betterend.charnia_red": "Red Charnia", - - "entity.betterend.cubozoa": "Cubozoa", - "item.betterend.spawn_egg_cubozoa": "Cubozoa Spawn Egg", - - "item.betterend.gelatine": "Gelatine", - "item.betterend.sweet_berry_jelly": "Sweet Berry Jelly", - "item.betterend.shadow_berry_jelly": "Shadow Berry Jelly", - - "block.betterend.amber_moss": "Amber Moss", - "block.betterend.amber_moss_path": "Amber Moss Path", - "block.betterend.helix_tree_bark": "Helix Tree Bark", - "block.betterend.helix_tree_barrel": "Helix Tree Barrel", - "block.betterend.helix_tree_bookshelf": "Helix Tree Bookshelf", - "block.betterend.helix_tree_button": "Helix Tree Button", - "block.betterend.helix_tree_chest": "Helix Tree Chest", - "block.betterend.helix_tree_crafting_table": "Helix Tree Crafting Table", - "block.betterend.helix_tree_door": "Helix Tree Door", - "block.betterend.helix_tree_fence": "Helix Tree Fence", - "block.betterend.helix_tree_gate": "Helix Tree Gate", - "block.betterend.helix_tree_ladder": "Helix Tree Ladder", - "block.betterend.helix_tree_leaves": "Helix Tree Leaves", - "block.betterend.helix_tree_log": "Helix Tree Log", - "block.betterend.helix_tree_planks": "Helix Tree Planks", - "block.betterend.helix_tree_plate": "Helix Tree Pressure Plate", - "block.betterend.helix_tree_sapling": "Helix Tree Sapling", - "block.betterend.helix_tree_sign": "Helix Tree Sign", - "block.betterend.helix_tree_slab": "Helix Tree Slab", - "block.betterend.helix_tree_stairs": "Helix Tree Stairs", - "block.betterend.helix_tree_stripped_bark": "Stripped Helix Tree Bark", - "block.betterend.helix_tree_stripped_log": "Stripped Helix Tree Log", - "block.betterend.helix_tree_trapdoor": "Helix Tree Trapdoor", - "block.betterend.lanceleaf": "Lanceleaf", - "block.betterend.lanceleaf_seed": "Lanceleaf Seed", - "block.betterend.hydralux": "Hydralux", - "block.betterend.helix_tree_luminophor": "Helix Tree Luminophor", - - "block.betterend.glowing_pillar_leaves": "Glowing Pillar Leaves", - "block.betterend.glowing_pillar_luminophor": "Glowing Pillar Luminophor", - "block.betterend.glowing_pillar_roots": "Glowing Pillar Roots", - "block.betterend.glowing_pillar_seed": "Glowing Pillar Seed", - - "biome.betterend.ice_starfield": "Ice Starfield", - - "block.betterend.ancient_emerald_ice": "Ancient Emerald Ice", - "block.betterend.dense_emerald_ice": "Dense Emerald Ice", - "block.betterend.dense_snow": "Dense Snow", - "block.betterend.emerald_ice": "Emerald Ice", - - "block.betterend.bulb_moss": "Bulb Moss", - - "block.betterend.charnia_green": "Green Charnia", - "block.betterend.vent_bubble_column": "Vent Bubble Column", - "block.betterend.respawn_obelisk": "Respawn Obelisk", - "message.betterend.set_spawn": "\u00A7b\u00A7lYour spawn point is set here", - "message.betterend.fail_spawn": "\u00A7c\u00A7lYou need to hold 6 Amber Gems to set your spawn point", - - "block.betterend.dragon_tree_composter": "Dragon Tree Composter", - "block.betterend.end_lotus_composter": "End Lotus Composter", - "block.betterend.helix_tree_composter": "Helix Tree Composter", - "block.betterend.lacugrove_composter": "Lacugrove Composter", - "block.betterend.mossy_glowshroom_composter": "Mossy Glowshroom Composter", - "block.betterend.pythadendron_composter": "Pythadendron Composter", - "block.betterend.tenanea_composter": "Tenanea Composter", - - "biome.betterend.old_bulbis_gardens": "Old Bulbis Gardens", - "block.betterend.ivis_moss": "Ivis Moss", - "block.betterend.ivis_vine": "Ivis Vine", - "block.betterend.silk_moth_nest": "Silk Moth Nest", - - "block.betterend.umbrella_tree_bark": "Umbrella Tree Bark", - "block.betterend.umbrella_tree_barrel": "Umbrella Tree Barrel", - "block.betterend.umbrella_tree_bookshelf": "Umbrella Tree Bookshelf", - "block.betterend.umbrella_tree_button": "Umbrella Tree Button", - "block.betterend.umbrella_tree_chest": "Umbrella Tree Chest", - "block.betterend.umbrella_tree_composter": "Umbrella Tree Composter", - "block.betterend.umbrella_tree_crafting_table": "Umbrella Tree Crafting Table", - "block.betterend.umbrella_tree_door": "Umbrella Tree Door", - "block.betterend.umbrella_tree_fence": "Umbrella Tree Fence", - "block.betterend.umbrella_tree_gate": "Umbrella Tree Gate", - "block.betterend.umbrella_tree_ladder": "Umbrella Tree Ladder", - "block.betterend.umbrella_tree_log": "Umbrella Tree Log", - "block.betterend.umbrella_tree_planks": "Umbrella Tree Planks", - "block.betterend.umbrella_tree_plate": "Umbrella Tree Pressure Plate", - "block.betterend.umbrella_tree_sign": "Umbrella Tree Sign", - "block.betterend.umbrella_tree_slab": "Umbrella Tree Slab", - "block.betterend.umbrella_tree_stairs": "Umbrella Tree Stairs", - "block.betterend.umbrella_tree_stripped_bark": "Stripped Umbrella Tree Bark", - "block.betterend.umbrella_tree_stripped_log": "Stripped Umbrella Tree Log", - "block.betterend.umbrella_tree_trapdoor": "Umbrella Tree Trapdoor", - "block.betterend.umbrella_tree_membrane": "Umbrella Tree Membrane", - - "biome.betterend.umbrella_jungle": "Umbrella Jungle", - "block.betterend.jungle_grass": "Jungle Grass", - "block.betterend.jungle_moss": "Jungle Moss", - "block.betterend.jungle_moss_path": "Jungle Moss Path", - "block.betterend.small_jellyshroom": "Small Jellyshroom", - "block.betterend.twisted_umbrella_moss": "Twisted Umbrella Moss", - "block.betterend.twisted_umbrella_moss_tall": "Twisted Umbrella Moss Tall", - "block.betterend.umbrella_tree_cluster": "Umbrella Tree Cluster", - "block.betterend.umbrella_tree_cluster_empty": "Empty Umbrella Tree Cluster", - "block.betterend.jungle_vine": "Jungle Vine", - "block.betterend.jungle_fern": "Jungle Fern", - - "block.betterend.jellyshroom_bark": "Jellyshroom Bark", - "block.betterend.jellyshroom_barrel": "Jellyshroom Barrel", - "block.betterend.jellyshroom_bookshelf": "Jellyshroom Bookshelf", - "block.betterend.jellyshroom_button": "Jellyshroom Button", - "block.betterend.jellyshroom_cap_purple": "Purple Jellyshroom Cap", - "block.betterend.jellyshroom_chest": "Jellyshroom Chest", - "block.betterend.jellyshroom_composter": "Jellyshroom Composter", - "block.betterend.jellyshroom_crafting_table": "Jellyshroom Crafting Table", - "block.betterend.jellyshroom_door": "Jellyshroom Door", - "block.betterend.jellyshroom_fence": "Jellyshroom Fence", - "block.betterend.jellyshroom_gate": "Jellyshroom Gate", - "block.betterend.jellyshroom_ladder": "Jellyshroom Ladder", - "block.betterend.jellyshroom_log": "Jellyshroom Log", - "block.betterend.jellyshroom_planks": "Jellyshroom Planks", - "block.betterend.jellyshroom_plate": "Jellyshroom Pressure Plate", - "block.betterend.jellyshroom_sign": "Jellyshroom Sign", - "block.betterend.jellyshroom_slab": "Jellyshroom Slab", - "block.betterend.jellyshroom_stairs": "Jellyshroom Stairs", - "block.betterend.jellyshroom_stripped_bark": "Stripped Jellyshroom Bark", - "block.betterend.jellyshroom_stripped_log": "Stripped Jellyshroom Log", - "block.betterend.jellyshroom_trapdoor": "Jellyshroom Trapdoor", - - "biome.betterend.eterial_grove": "Eterial Grove", - "block.betterend.umbrella_tree_sapling": "Umbrella Tree Sapling", - "item.betterend.umbrella_cluster_juice": "Umbrella Cluster Juice", - "block.betterend.blossom_berry_seed": "Blossom Berry Seed", - "item.betterend.blossom_berry": "Blossom Berry", - - "biome.betterend.nightshade_redwoods": "Nightshade Redwoods", - "block.betterend.nightshade_moss": "Nightshade Moss", - - "biome.betterend.glowing_grasslands": "Glowing Grasslands", - "block.betterend.blooming_cooksonia": "Blooming Cooksonia", - "block.betterend.fracturn": "Fracturn", - "block.betterend.lumecorn": "Lumecorn", - "block.betterend.salteago": "Salteago", - "block.betterend.vaiolush_fern": "Vaiolush Fern", - "entity.betterend.silk_moth": "Silk Moth", - "item.betterend.silk_fiber": "Silk Fiber", - "item.betterend.spawn_egg_silk_moth": "Silk Moth Spawn Egg", - - "block.betterend.thallasium_ore": "Thallasium Ore", - "item.betterend.thallasium_axe": "Thallasium Axe", - "item.betterend.thallasium_hoe": "Thallasium Hoe", - "item.betterend.thallasium_ingot": "Thallasium Ingot", - "item.betterend.thallasium_pickaxe": "Thallasium Pickaxe", - "item.betterend.thallasium_shovel": "Thallasium Shovel", - "item.betterend.thallasium_sword": "Thallasium Sword", - "block.betterend.thallasium_block": "Thallasium Block", - - "block.betterend.thallasium_bars": "Thallasium Bars", - "block.betterend.thallasium_door": "Thallasium Door", - "block.betterend.thallasium_plate": "Thallasium Pressure Plate", - "block.betterend.thallasium_tile": "Thallasium Tile", - "block.betterend.thallasium_trapdoor": "Thallasium Trapdoor", - - "block.betterend.lumecorn_seed": "Lumecorn Seed", - "item.betterend.lumecorn_rod": "Lumecorn Rod", - "block.betterend.thallasium_chandelier": "Thallasium Chandelier", - - "block.betterend.thallasium_anvil": "Thallasium Anvil", - "block.betterend.thallasium_chain": "Thallasium Chain", - "block.betterend.thallasium_slab": "Thallasium Slab", - "block.betterend.thallasium_stairs": "Thallasium Stairs", - - "block.betterend.gold_chandelier": "Gold Chandelier", - "block.betterend.iron_chandelier": "Iron Chandelier", - "item.betterend.thallasium_nugget": "Thallasium Nugget", - - "block.betterend.terminite_anvil": "Terminite Anvil", - "block.betterend.terminite_bars": "Terminite Bars", - - "block.betterend.terminite_bulb_lantern": "Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_black": "Black Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_blue": "Blue Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_brown": "Brown Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_cyan": "Cyan Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_gray": "Gray Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_green": "Green Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_light_blue": "Light Blue Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_light_gray": "Light Gray Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_lime": "Lime Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_magenta": "Magenta Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_orange": "Orange Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_pink": "Pink Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_purple": "Purple Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_red": "Red Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_white": "White Terminite Bulb Lantern", - "block.betterend.terminite_bulb_lantern_yellow": "Yellow Terminite Bulb Lantern", - - "block.betterend.terminite_chain": "Terminite Chain", - "block.betterend.terminite_chandelier": "Terminite Chandelier", - "block.betterend.terminite_door": "Terminite Door", - "block.betterend.terminite_plate": "Terminite Pressure Plate", - "block.betterend.terminite_slab": "Terminite Slab", - "block.betterend.terminite_stairs": "Terminite Stairs", - "block.betterend.terminite_tile": "Terminite Tile", - "block.betterend.terminite_trapdoor": "Terminite Trapdoor", - "item.betterend.terminite_nugget": "Terminite Nugget", - "item.betterend.thallasium_boots": "Thallasium Boots", - "item.betterend.thallasium_chestplate": "Thallasium Chestplate", - "item.betterend.thallasium_hammer": "Thallasium Hammer", - "item.betterend.thallasium_helmet": "Thallasium Helmet", - "item.betterend.thallasium_leggings": "Thallasium Leggings", - "block.betterend.missing_tile": "Missing Tile", - "block.betterend.charcoal_block": "Charcoal Block", - "block.betterend.end_stone_furnace": "End Stone Furnace", - "block.betterend.flavolite_furnace": "Flavolite Furnace", - "block.betterend.sulphuric_rock_furnace": "Sulfuric Rock Furnace", - "block.betterend.violecite_furnace": "Violecite Furnace", - - "item.betterend.terminite_axe_head": "Terminite Axe Head", - "item.betterend.terminite_hoe_head": "Terminite Hoe Head", - "item.betterend.terminite_pickaxe_head": "Terminite Pickaxe Head", - "item.betterend.terminite_shovel_head": "Terminite Shovel Head", - "item.betterend.terminite_sword_blade": "Terminite Sword Blade", - "item.betterend.terminite_sword_handle": "Terminite Sword Handle", - "item.betterend.thallasium_axe_head": "Thallasium Axe Head", - "item.betterend.thallasium_hoe_head": "Thallasium Hoe Head", - "item.betterend.thallasium_pickaxe_head": "Thallasium Pickaxe Head", - "item.betterend.thallasium_shovel_head": "Thallasium Shovel Head", - "item.betterend.thallasium_sword_blade": "Thallasium Sword Blade", - "item.betterend.thallasium_sword_handle": "Thallasium Sword Handle", - "block.betterend.aeternium_anvil": "Aeternium Anvil", - - "biome.betterend.dragon_graveyards": "Dragon Graveyards", - "biome.betterend.dry_shrubland": "Dry Shrubland", - "block.betterend.aeridium": "Aeridium", - "block.betterend.amaranita_cap": "Amaranita Cap", - "block.betterend.amaranita_fur": "Amaranita Fur", - "block.betterend.amaranita_hymenophore": "Amaranita Hymenophore", - "block.betterend.amaranita_hyphae": "Amaranita Hyphae", - "block.betterend.amaranita_lantern": "Amaranita Lantern", - "block.betterend.amaranita_stem": "Amaranita Stem", - "block.betterend.clawfern": "Clawfern", - "block.betterend.globulagus": "Globulagus", - "block.betterend.lamellarium": "Lamellarium", - "block.betterend.large_amaranita_mushroom": "Large Amaranita Mushroom", - "block.betterend.lutebus": "Lutebus", - "block.betterend.mossy_bone": "Mossy Bone", - "block.betterend.mossy_obsidian": "Mossy Obsidian", - "block.betterend.orango": "Orango", - "block.betterend.rutiscus": "Rutiscus", - "block.betterend.rutiscus_path": "Rutiscus Path", - "block.betterend.sangnum": "Sangnum", - "block.betterend.sangnum_path": "Sangnum Path", - "block.betterend.small_amaranita_mushroom": "Small Amaranita Mushroom", - - "block.betterend.amber_root_seed": "Amber Root Seed", - "block.betterend.azure_jadestone": "Azure Jadestone", - "block.betterend.azure_jadestone_bricks": "Azure Jadestone Bricks", - "block.betterend.azure_jadestone_bricks_slab": "Azure Jadestone Brick Slab", - "block.betterend.azure_jadestone_bricks_stairs": "Azure Jadestone Brick Stairs", - "block.betterend.azure_jadestone_bricks_wall": "Azure Jadestone Brick Wall", - "block.betterend.azure_jadestone_button": "Azure Jadestone Button", - "block.betterend.azure_jadestone_furnace": "Azure Jadestone Furnace", - "block.betterend.azure_jadestone_lantern": "Azure Jadestone Lantern", - "block.betterend.azure_jadestone_pedestal": "Azure Jadestone Pedestal", - "block.betterend.azure_jadestone_pillar": "Azure Jadestone Pillar", - "block.betterend.azure_jadestone_plate": "Azure Jadestone Pressure Plate", - "block.betterend.azure_jadestone_polished": "Azure Jadestone Polished", - "block.betterend.azure_jadestone_slab": "Azure Jadestone Slab", - "block.betterend.azure_jadestone_stairs": "Azure Jadestone Stairs", - "block.betterend.azure_jadestone_tiles": "Azure Jadestone Tiles", - "block.betterend.azure_jadestone_wall": "Azure Jadestone Wall", - "block.betterend.chorus_mushroom_seed": "Chorus Mushroom Seed", - "block.betterend.end_stone_stalactite": "End Stone Stalactite", - "block.betterend.end_stone_stalactite_cavemoss": "Cave Moss Endstone Stalactite", - "block.betterend.pearlberry_seed": "Pearlberry Seed", - "block.betterend.rubinea": "Rubinea", - "block.betterend.sandy_jadestone": "Sandy Jadestone", - "block.betterend.sandy_jadestone_bricks": "Sandy Jadestone Bricks", - "block.betterend.sandy_jadestone_bricks_slab": "Sandy Jadestone Brick Slab", - "block.betterend.sandy_jadestone_bricks_stairs": "Sandy Jadestone Brick Stairs", - "block.betterend.sandy_jadestone_bricks_wall": "Sandy Jadestone Brick Wall", - "block.betterend.sandy_jadestone_button": "Sandy Jadestone Button", - "block.betterend.sandy_jadestone_furnace": "Sandy Jadestone Furnace", - "block.betterend.sandy_jadestone_lantern": "Sandy Jadestone Lantern", - "block.betterend.sandy_jadestone_pedestal": "Sandy Jadestone Pedestal", - "block.betterend.sandy_jadestone_pillar": "Sandy Jadestone Pillar", - "block.betterend.sandy_jadestone_plate": "Sandy Jadestone Pressure Plate", - "block.betterend.sandy_jadestone_polished": "Sandy Jadestone Polished", - "block.betterend.sandy_jadestone_slab": "Sandy Jadestone Slab", - "block.betterend.sandy_jadestone_stairs": "Sandy Jadestone Stairs", - "block.betterend.sandy_jadestone_tiles": "Sandy Jadestone Tiles", - "block.betterend.sandy_jadestone_wall": "Sandy Jadestone Wall", - "block.betterend.smaragdant_crystal": "Smaragdant Crystal", - "block.betterend.smaragdant_crystal_shard": "Smaragdant Crystal Shard", - "block.betterend.virid_jadestone": "Virid Jadestone", - "block.betterend.virid_jadestone_bricks": "Virid Jadestone Bricks", - "block.betterend.virid_jadestone_bricks_slab": "Virid Jadestone Brick Slab", - "block.betterend.virid_jadestone_bricks_stairs": "Virid Jadestone Brick Stairs", - "block.betterend.virid_jadestone_bricks_wall": "Virid Jadestone Brick Wall", - "block.betterend.virid_jadestone_button": "Virid Jadestone Button", - "block.betterend.virid_jadestone_furnace": "Virid Jadestone Furnace", - "block.betterend.virid_jadestone_lantern": "Virid Jadestone Lantern", - "block.betterend.virid_jadestone_pedestal": "Virid Jadestone Pedestal", - "block.betterend.virid_jadestone_pillar": "Virid Jadestone Pillar", - "block.betterend.virid_jadestone_plate": "Virid Jadestone Pressure Plate", - "block.betterend.virid_jadestone_polished": "Virid Jadestone Polished", - "block.betterend.virid_jadestone_slab": "Virid Jadestone Slab", - "block.betterend.virid_jadestone_stairs": "Virid Jadestone Stairs", - "block.betterend.virid_jadestone_tiles": "Virid Jadestone Tiles", - "block.betterend.virid_jadestone_wall": "Virid Jadestone Wall", - "item.betterend.amber_root_raw": "Raw Amber Root", - "item.betterend.chorus_mushroom_cooked": "Cooked Chorus Mushroom", - "item.betterend.chorus_mushroom_raw": "Raw Chorus Mushroom", - - "biome.betterend.empty_aurora_cave": "Empty Aurora Cave", - "biome.betterend.empty_end_cave": "Empty End Cave", - "biome.betterend.empty_smaragdant_cave": "Empty Smaragdant Cave", - "biome.betterend.lush_aurora_cave": "Lush Aurora Cave", - "biome.betterend.lush_smaragdant_cave": "Lush Smaragdant Cave", - - "block.betterend.dragon_bone_block": "Dragon Bone Block", - "block.betterend.dragon_bone_slab": "Dragon Bone Slab", - "block.betterend.dragon_bone_stairs": "Dragon Bone Stairs", - "block.betterend.mossy_dragon_bone": "Mossy Dragon Bone", - - "biome.betterend.lantern_woods": "Lantern Woods", - "block.betterend.filalux": "Filalux", - "block.betterend.filalux_lantern": "Filalux Lantern", - "block.betterend.filalux_wings": "Filalux Wings", - "block.betterend.lucernia_bark": "Lucernia Bark", - "block.betterend.lucernia_barrel": "Lucernia Barrel", - "block.betterend.lucernia_bookshelf": "Lucernia Bookshelf", - "block.betterend.lucernia_button": "Lucernia Button", - "block.betterend.lucernia_chest": "Lucernia Chest", - "block.betterend.lucernia_composter": "Lucernia Composter", - "block.betterend.lucernia_crafting_table": "Lucernia Crafting Table", - "block.betterend.lucernia_door": "Lucernia Door", - "block.betterend.lucernia_fence": "Lucernia Fence", - "block.betterend.lucernia_gate": "Lucernia Gate", - "block.betterend.lucernia_ladder": "Lucernia Ladder", - "block.betterend.lucernia_leaves": "Lucernia Leaves", - "block.betterend.lucernia_log": "Lucernia Log", - "block.betterend.lucernia_outer_leaves": "Lucernia Outer Leaves", - "block.betterend.lucernia_planks": "Lucernia Planks", - "block.betterend.lucernia_plate": "Lucernia Pressure Plate", - "block.betterend.lucernia_sapling": "Lucernia Sapling", - "block.betterend.lucernia_sign": "Lucernia Sign", - "block.betterend.lucernia_slab": "Lucernia Slab", - "block.betterend.lucernia_stairs": "Lucernia Stairs", - "block.betterend.lucernia_stripped_bark": "Stripped Lucernia Bark", - "block.betterend.lucernia_stripped_log": "Stripped Lucernia Log", - "block.betterend.lucernia_trapdoor": "Lucernia Trapdoor", - - "block.betterend.aurant_polypore": "Aurant Polypore", - "block.betterend.bolux_mushroom": "Bolux Mushroom", - "block.betterend.flamaea": "Flamaea", - "block.betterend.pond_anemone": "Pond Anemone", - "block.betterend.ruscus": "Ruscus", - "item.betterend.bolux_mushroom_cooked": "Cooked Bolux Mushroom", - - "block.betterend.silk_moth_hive": "Silk Moth Hive", - "item.betterend.silk_moth_matrix": "Silk Moth Matrix", - - "biome.betterend.neon_oasis": "Neon Oasis", - "block.betterend.cave_pumpkin": "Cave Pumpkin", - "block.betterend.cave_pumpkin_seed": "Cave Pumpkin Seed", - "block.betterend.magnula": "Magnula", - "block.betterend.neon_cactus": "Neon Cactus", - "item.betterend.cave_pumpkin_pie": "Cave Pumpkin Pie", - - "item.betterend.music_disc_strange_and_alien": "§bMusic Disc§r", - "item.betterend.music_disc_strange_and_alien.desc": "§5Firel§r - §fStrange And Alien§r", - "item.betterend.music_disc_grasping_at_stars": "§bMusic Disc§r", - "item.betterend.music_disc_grasping_at_stars.desc": "§5Firel§r - §fGrasping At Stars§r", - "item.betterend.music_disc_endseeker": "§bMusic Disc§r", - "item.betterend.music_disc_endseeker.desc": "§5Firel§r - §fEndseeker§r", - "item.betterend.music_disc_eo_dracona": "§bMusic Disc§r", - "item.betterend.music_disc_eo_dracona.desc": "§5Firel§r - §fEo Dracona§r", - - "block.betterend.hydralux_petal_block_amber": "Amber Petal Block", - "block.betterend.hydralux_petal_block_beige": "Beige Petal Block", - "block.betterend.hydralux_petal_block_cream": "Cream Petal Block", - "block.betterend.hydralux_petal_block_dark_green": "Dark Green Petal Block", - "block.betterend.hydralux_petal_block_forest_green": "Forest Green Petal Block", - "block.betterend.hydralux_petal_block_hot_pink": "Hot Pink Petal Block", - "block.betterend.hydralux_petal_block_indigo": "Indigo Petal Block", - "block.betterend.hydralux_petal_block_maroon": "Maroon Petal Block", - "block.betterend.hydralux_petal_block_navy": "Navy Petal Block", - "block.betterend.hydralux_petal_block_olive": "Olive Petal Block", - "block.betterend.hydralux_petal_block_pale_green": "Pale Green Petal Block", - "block.betterend.hydralux_petal_block_pale_pink": "Pale Pink Petal Block", - "block.betterend.hydralux_petal_block_pale_yellow": "Pale Yellow Petal Block", - "block.betterend.hydralux_petal_block_sky_blue": "Sky Blue Petal Block", - "block.betterend.hydralux_petal_block_slate_gray": "Slate Gray Petal Block", - "block.betterend.hydralux_petal_block_violet": "Violet Petal Block", - - "block.betterend.smaragdant_crystal_bricks": "Smaragdant Bricks", - "block.betterend.smaragdant_crystal_bricks_slab": "Smaragdant Brick Slab", - "block.betterend.smaragdant_crystal_bricks_stairs": "Smaragdant Brick Stairs", - "block.betterend.smaragdant_crystal_bricks_wall": "Smaragdant Brick Wall", - "block.betterend.smaragdant_crystal_pedestal": "Smaragdant Pedestal", - "block.betterend.smaragdant_crystal_pillar": "Smaragdant Pillar", - "block.betterend.smaragdant_crystal_polished": "Polished Smaragdant", - "block.betterend.smaragdant_crystal_slab": "Smaragdant Slab", - "block.betterend.smaragdant_crystal_stairs": "Smaragdant Stairs", - "block.betterend.smaragdant_crystal_tiles": "Smaragdant Tiles", - "block.betterend.smaragdant_crystal_wall": "Smaragdant Wall", - "message.betterend.anvil_damage": "§cDamage", - - "block.betterend.neon_cactus_block": "Neon Cactus Block", - "block.betterend.neon_cactus_slab": "Neon Cactus Slab", - "block.betterend.neon_cactus_stairs": "Neon Cactus Stairs", - "biome.betterend.jade_cave": "Jade Cave", - "item.betterend.blossom_berry_jelly": "Blossom Berry Jelly", - "item.betterend.aeternium_forged_plate": "Aeternium Forged Plate", - "item.betterend.terminite_forged_plate": "Terminite Forged Plate", - "item.betterend.thallasium_forged_plate": "Thallasium Forged Plate", - - "attribute.name.generic.blindness_resistance": "Blindness Resistance", - - "tooltip.armor.crystalite_set": "Set bonus: Regeneration I", - "tooltip.armor.crystalite_chest": "Effect: Dig Speed I", - "tooltip.armor.crystalite_boots": "Effect: Swiftness I" + "itemGroup.betterend.end_items": "Better End: Items", + "itemGroup.betterend.end_blocks": "Better End: Blocks", + "item.betterend.guidebook": "The End for Dummies", + "book.betterend.landing": "A short guide about surviving in the extreme conditions of The End.", + "book.betterend.subtitle": "Survive in The End", + "category.rei.damage.amount&dmg": "Tool damage: %s", + "category.rei.infusion.time&val": "Time: %s", + "biome.betterend.foggy_mushroomland": "Foggy Mushroomland", + "biome.betterend.dust_wastelands": "Dust Wastelands", + "biome.betterend.chorus_forest": "Chorus Forest", + "biome.betterend.megalake": "Megalake", + "biome.betterend.crystal_mountains": "Crystal Mountains", + "entity.betterend.dragonfly": "Dragonfly", + "item.betterend.spawn_egg_dragonfly": "Dragonfly Spawn Egg", + "entity.betterend.end_slime": "End Slime", + "item.betterend.spawn_egg_end_slime": "End Slime Spawn Egg", + "block.betterend.end_mycelium": "End Mycelium", + "block.betterend.end_moss": "End Moss", + "block.betterend.endstone_dust": "End Stone Dust", + "block.betterend.end_mycelium_path": "End Mycelium Path", + "block.betterend.end_moss_path": "End Moss Path", + "block.betterend.ender_ore": "Ender Ore", + "block.betterend.terminite_block": "Terminite Block", + "block.betterend.aeternium_block": "Aeternium Block", + "block.betterend.ender_block": "Ender Block", + "block.betterend.end_stone_smelter": "End Stone Smelter", + "item.betterend.ender_dust": "Ender Dust", + "item.betterend.ender_shard": "Ender Shard", + "item.betterend.terminite_ingot": "Terminite Ingot", + "item.betterend.aeternium_ingot": "Aeternium Ingot", + "item.betterend.terminite_helmet": "Terminite Helmet", + "item.betterend.terminite_chestplate": "Terminite Chestplate", + "item.betterend.terminite_leggings": "Terminite Leggings", + "item.betterend.terminite_boots": "Terminite Boots", + "item.betterend.terminite_shovel": "Terminite Shovel", + "item.betterend.terminite_sword": "Terminite Sword", + "item.betterend.terminite_pickaxe": "Terminite Pickaxe", + "item.betterend.terminite_axe": "Terminite Axe", + "item.betterend.terminite_hoe": "Terminite Hoe", + "item.betterend.terminite_hammer": "Terminite Smith Hammer", + "item.betterend.aeternium_helmet": "Aeternium Helmet", + "item.betterend.aeternium_chestplate": "Aeternium Chestplate", + "item.betterend.aeternium_leggings": "Aeternium Leggings", + "item.betterend.aeternium_boots": "Aeternium Boots", + "item.betterend.aeternium_shovel": "Aeternium Shovel", + "item.betterend.aeternium_sword": "Aeternium Sword", + "item.betterend.aeternium_pickaxe": "Aeternium Pickaxe", + "item.betterend.aeternium_axe": "Aeternium Axe", + "item.betterend.aeternium_hoe": "Aeternium Hoe", + "item.betterend.aeternium_hammer": "Aeternium Smith Hammer", + "item.betterend.iron_hammer": "Iron Smith Hammer", + "item.betterend.golden_hammer": "Golden Smith Hammer", + "item.betterend.diamond_hammer": "Diamond Smith Hammer", + "item.betterend.netherite_hammer": "Netherite Smith Hammer", + "item.betterend.crystalite_boots": "Crystalite Boots", + "item.betterend.crystalite_chestplate": "Crystalite Chestplate", + "item.betterend.crystalite_helmet": "Crystalite Helmet", + "item.betterend.crystalite_leggings": "Crystalite Leggings", + "item.betterend.aeternium_axe_head": "Aeternium Axe Head", + "item.betterend.aeternium_hammer_head": "Aeternium Hammer Head", + "item.betterend.aeternium_hoe_head": "Aeternium Hoe Head", + "item.betterend.aeternium_pickaxe_head": "Aeternium Pickaxe Head", + "item.betterend.aeternium_shovel_head": "Aeternium Shovel Head", + "item.betterend.aeternium_sword_blade": "Aeternium Sword Blade", + "item.betterend.aeternium_sword_handle": "Aeternium Sword Handle", + "item.betterend.leather_stripe": "Leather Stripe", + "item.betterend.leather_wrapped_stick": "Leather Wrapped Stick", + "item.betterend.elytra_armored": "Armored Elytra", + "item.betterend.elytra_crystalite": "Elytra Crystalite", + "item.betterend.enchanted_membrane": "Enchanted Membrane", + "effect.betterend.end_veil": "End Veil", + "enchantment.betterend.end_veil": "End Veil", + "item.minecraft.potion.effect.end_veil": "Potion Of End Veil", + "item.minecraft.potion.effect.long_end_veil": "Potion Of End Veil", + "item.minecraft.splash_potion.effect.end_veil": "Splash Potion Of End Veil", + "item.minecraft.splash_potion.effect.long_end_veil": "Splash Potion Of End Veil", + "item.minecraft.lingering_potion.effect.end_veil": "Lingering Potion Of End Veil", + "item.minecraft.lingering_potion.effect.long_end_veil": "Lingering Potion Of End Veil", + "item.minecraft.tipped_arrow.effect.end_veil": "Arrow Of End Veil", + "item.minecraft.tipped_arrow.effect.long_end_veil": "Arrow Of End Veil", + "block.betterend.mossy_glowshroom_sapling": "Mossy Glowshroom Sapling", + "block.betterend.mossy_glowshroom_cap": "Mossy Glowshroom Cap", + "block.betterend.mossy_glowshroom_fur": "Mossy Glowshroom Fur", + "block.betterend.mossy_glowshroom_hymenophore": "Mossy Glowshroom Hymenophore", + "block.betterend.mossy_glowshroom_bark": "Mossy Glowshroom Bark", + "block.betterend.mossy_glowshroom_barrel": "Mossy Glowshroom Barrel", + "block.betterend.mossy_glowshroom_button": "Mossy Glowshroom Button", + "block.betterend.mossy_glowshroom_chest": "Mossy Glowshroom Chest", + "block.betterend.mossy_glowshroom_crafting_table": "Mossy Glowshroom Crafting Table", + "block.betterend.mossy_glowshroom_door": "Mossy Glowshroom Door", + "block.betterend.mossy_glowshroom_fence": "Mossy Glowshroom Fence", + "block.betterend.mossy_glowshroom_gate": "Mossy Glowshroom Gate", + "block.betterend.mossy_glowshroom_ladder": "Mossy Glowshroom Ladder", + "block.betterend.mossy_glowshroom_log": "Mossy Glowshroom Log", + "block.betterend.mossy_glowshroom_planks": "Mossy Glowshroom Planks", + "block.betterend.mossy_glowshroom_plate": "Mossy Glowshroom Pressure Plate", + "block.betterend.mossy_glowshroom_sign": "Mossy Glowshroom Sign", + "block.betterend.mossy_glowshroom_slab": "Mossy Glowshroom Slab", + "block.betterend.mossy_glowshroom_stairs": "Mossy Glowshroom Stairs", + "block.betterend.mossy_glowshroom_stripped_bark": "Stripped Mossy Glowshroom Bark", + "block.betterend.mossy_glowshroom_stripped_log": "Stripped Mossy Glowshroom Log", + "block.betterend.mossy_glowshroom_trapdoor": "Mossy Glowshroom Trapdoor", + "block.betterend.umbrella_moss": "Umbrella Moss", + "block.betterend.umbrella_moss_tall": "Tall Umbrella Moss", + "block.betterend.creeping_moss": "Creeping Moss", + "block.betterend.blue_vine_seed": "Blue Vine Seed", + "block.betterend.blue_vine": "Blue Vine", + "block.betterend.blue_vine_lantern": "Blue Vine Lantern", + "block.betterend.blue_vine_fur": "Blue Vine Fur", + "block.betterend.dense_vine": "Dense Vine", + "block.betterend.bubble_coral": "Bubble Coral", + "block.betterend.aurora_crystal": "Aurora Crystal", + "item.betterend.crystal_shards": "Aurora Crystal Shards", + "block.betterend.pythadendron_sapling": "Pythadendron Sapling", + "block.betterend.pythadendron_bark": "Pythadendron Bark", + "block.betterend.pythadendron_barrel": "Pythadendron Barrel", + "block.betterend.pythadendron_button": "Pythadendron Button", + "block.betterend.pythadendron_chest": "Pythadendron Chest", + "block.betterend.pythadendron_crafting_table": "Pythadendron Crafting Table", + "block.betterend.pythadendron_door": "Pythadendron Door", + "block.betterend.pythadendron_fence": "Pythadendron Fence", + "block.betterend.pythadendron_gate": "Pythadendron Gate", + "block.betterend.pythadendron_ladder": "Pythadendron Ladder", + "block.betterend.pythadendron_log": "Pythadendron Log", + "block.betterend.pythadendron_planks": "Pythadendron Planks", + "block.betterend.pythadendron_plate": "Pythadendron Pressure Plate", + "block.betterend.pythadendron_sign": "Pythadendron Sign", + "block.betterend.pythadendron_slab": "Pythadendron Slab", + "block.betterend.pythadendron_stairs": "Pythadendron Stairs", + "block.betterend.pythadendron_stripped_bark": "Stripped Pythadendron Bark", + "block.betterend.pythadendron_stripped_log": "Stripped Pythadendron Log", + "block.betterend.pythadendron_trapdoor": "Pythadendron Trapdoor", + "block.betterend.chorus_nylium": "Chorus Nylium", + "block.betterend.chorus_nylium_path": "Chorus Nylium Path", + "block.betterend.chorus_grass": "Chorus Grass", + "block.betterend.end_lily": "End Lily", + "block.betterend.end_lily_seed": "End Lily Seed", + "item.betterend.end_lily_leaf": "End Lily Leaf", + "item.betterend.end_lily_leaf_dried": "End Lily Leaf Dried", + "block.betterend.violecite": "Violecite", + "block.betterend.violecite_bricks": "Violecite Bricks", + "block.betterend.violecite_bricks_slab": "Violecite Brick Slab", + "block.betterend.violecite_bricks_stairs": "Violecite Brick Stairs", + "block.betterend.violecite_bricks_wall": "Violecite Brick Wall", + "block.betterend.violecite_button": "Violecite Button", + "block.betterend.violecite_pillar": "Violecite Pillar", + "block.betterend.violecite_plate": "Violecite Pressure Plate", + "block.betterend.violecite_slab": "Violecite Slab", + "block.betterend.violecite_tiles": "Violecite Tiles", + "block.betterend.violecite_stairs": "Violecite Stairs", + "block.betterend.violecite_polished": "Polished Violecite", + "block.betterend.violecite_wall": "Violecite Wall", + "block.betterend.violecite_pedestal": "Violecite Pedestal", + "block.betterend.flavolite": "Flavolite", + "block.betterend.flavolite_bricks": "Flavolite Bricks", + "block.betterend.flavolite_bricks_slab": "Flavolite Brick Slab", + "block.betterend.flavolite_bricks_stairs": "Flavolite Brick Stairs", + "block.betterend.flavolite_bricks_wall": "Flavolite Brick Wall", + "block.betterend.flavolite_button": "Flavolite Button", + "block.betterend.flavolite_pillar": "Flavolite Pillar", + "block.betterend.flavolite_plate": "Flavolite Pressure Plate", + "block.betterend.flavolite_slab": "Flavolite Slab", + "block.betterend.flavolite_tiles": "Flavolite Tiles", + "block.betterend.flavolite_stairs": "Flavolite Stairs", + "block.betterend.flavolite_polished": "Polished Flavolite", + "block.betterend.flavolite_wall": "Flavolite Wall", + "block.betterend.flavolite_pedestal": "Flavolite Pedestal", + "block.betterend.andesite_pedestal": "Andesite Pedestal", + "block.betterend.diorite_pedestal": "Diorite Pedestal", + "block.betterend.granite_pedestal": "Granite Pedestal", + "block.betterend.purpur_pedestal": "Purpur Pedestal", + "block.betterend.quartz_pedestal": "Quartz Pedestal", + "block.betterend.infusion_pedestal": "Infusion Pedestal", + "block.betterend.end_lotus_seed": "End Lotus Seed", + "block.betterend.end_lotus_stem": "End Lotus Stem", + "block.betterend.end_lotus_leaf": "End Lotus Leaf", + "block.betterend.end_lotus_flower": "End Lotus Flower", + "block.betterend.end_lotus_bark": "End Lotus Bark", + "block.betterend.end_lotus_barrel": "End Lotus Barrel", + "block.betterend.end_lotus_button": "End Lotus Button", + "block.betterend.end_lotus_chest": "End Lotus Chest", + "block.betterend.end_lotus_crafting_table": "End Lotus Crafting Table", + "block.betterend.end_lotus_door": "End Lotus Door", + "block.betterend.end_lotus_fence": "End Lotus Fence", + "block.betterend.end_lotus_gate": "End Lotus Gate", + "block.betterend.end_lotus_ladder": "End Lotus Ladder", + "block.betterend.end_lotus_log": "End Lotus Log", + "block.betterend.end_lotus_planks": "End Lotus Planks", + "block.betterend.end_lotus_plate": "End Lotus Pressure Plate", + "block.betterend.end_lotus_sign": "End Lotus Sign", + "block.betterend.end_lotus_slab": "End Lotus Slab", + "block.betterend.end_lotus_stairs": "End Lotus Stairs", + "block.betterend.end_lotus_stripped_bark": "Stripped End Lotus Bark", + "block.betterend.end_lotus_stripped_log": "Stripped End Lotus Log", + "block.betterend.end_lotus_trapdoor": "End Lotus Trapdoor", + "block.betterend.cave_moss": "Cave Moss", + "block.betterend.cave_grass": "Cave Grass", + "block.betterend.cave_bush": "Cave Bush", + "block.betterend.cave_moss_path": "Cave Moss Path", + "block.betterend.crystal_moss": "Crystal Moss", + "block.betterend.crystal_moss_path": "Crystal Moss Path", + "block.betterend.crystal_moss_cover": "Crystal Moss Cover", + "block.betterend.pythadendron_leaves": "Pythadendron Leaves", + "item.betterend.spawn_egg_end_fish": "End Fish Spawn Egg", + "block.betterend.crystal_grass": "Crystal Grass", + "block.betterend.flavolite_runed": "Runed Flavolite", + "block.betterend.end_portal_block": "End Portal", + "block.betterend.eternal_pedestal": "Eternal Pedestal", + "block.betterend.flavolite_runed_eternal": "Eternal Runed Flavolite", + "item.betterend.eternal_crystal": "Eternal Crystal", + "block.betterend.lacugrove_bark": "Lacugrove Bark", + "block.betterend.lacugrove_barrel": "Lacugrove Barrel", + "block.betterend.lacugrove_button": "Lacugrove Button", + "block.betterend.lacugrove_chest": "Lacugrove Chest", + "block.betterend.lacugrove_crafting_table": "Lacugrove Crafting Table", + "block.betterend.lacugrove_door": "Lacugrove Door", + "block.betterend.lacugrove_fence": "Lacugrove Fence", + "block.betterend.lacugrove_gate": "Lacugrove Gate", + "block.betterend.lacugrove_ladder": "Lacugrove Ladder", + "block.betterend.lacugrove_log": "Lacugrove Log", + "block.betterend.lacugrove_planks": "Lacugrove Planks", + "block.betterend.lacugrove_plate": "Lacugrove Pressure Plate", + "block.betterend.lacugrove_sign": "Lacugrove Sign", + "block.betterend.lacugrove_slab": "Lacugrove Slab", + "block.betterend.lacugrove_stairs": "Lacugrove Stairs", + "block.betterend.lacugrove_stripped_bark": "Stripped Lacugrove Bark", + "block.betterend.lacugrove_stripped_log": "Stripped Lacugrove Log", + "block.betterend.lacugrove_trapdoor": "Lacugrove Trapdoor", + "block.betterend.lacugrove_leaves": "Lacugrove Leaves", + "block.betterend.lacugrove_sapling": "Lacugrove Sapling", + "biome.betterend.megalake_grove": "Megalake Grove", + "biome.betterend.painted_mountains": "Painted Mountains", + "block.betterend.dragon_tree_bark": "Dragon Tree Bark", + "block.betterend.dragon_tree_barrel": "Dragon Tree Barrel", + "block.betterend.dragon_tree_button": "Dragon Tree Button", + "block.betterend.dragon_tree_chest": "Dragon Tree Chest", + "block.betterend.dragon_tree_crafting_table": "Dragon Tree Crafting Table", + "block.betterend.dragon_tree_door": "Dragon Tree Door", + "block.betterend.dragon_tree_fence": "Dragon Tree Fence", + "block.betterend.dragon_tree_gate": "Dragon Tree Gate", + "block.betterend.dragon_tree_ladder": "Dragon Tree Ladder", + "block.betterend.dragon_tree_log": "Dragon Tree Log", + "block.betterend.dragon_tree_planks": "Dragon Tree Planks", + "block.betterend.dragon_tree_plate": "Dragon Tree Pressure Plate", + "block.betterend.dragon_tree_sign": "Dragon Tree Sign", + "block.betterend.dragon_tree_slab": "Dragon Tree Slab", + "block.betterend.dragon_tree_stairs": "Dragon Tree Stairs", + "block.betterend.dragon_tree_stripped_bark": "Stripped Dragon Tree Bark", + "block.betterend.dragon_tree_stripped_log": "Stripped Dragon Tree Log", + "block.betterend.dragon_tree_trapdoor": "Dragon Tree Trapdoor", + "biome.betterend.shadow_forest": "Shadow Forest", + "block.betterend.dragon_tree_leaves": "Dragon Tree Leaves", + "block.betterend.dragon_tree_sapling": "Dragon Tree Sapling", + "block.betterend.shadow_grass": "Shadow Grass", + "block.betterend.shadow_grass_path": "Shadow Grass Path", + "block.betterend.shadow_plant": "Shadow Plant", + "block.betterend.dragon_tree_bookshelf": "Dragon Tree Bookshelf", + "block.betterend.end_lotus_bookshelf": "End Lotus Bookshelf", + "block.betterend.lacugrove_bookshelf": "Lacugrove Bookshelf", + "block.betterend.mossy_glowshroom_bookshelf": "Mossy Glowshroom Bookshelf", + "block.betterend.pythadendron_bookshelf": "Pythadendron Bookshelf", + "block.betterend.murkweed": "Murkweed", + "block.betterend.needlegrass": "Needlegrass", + "block.betterend.twisted_vine": "Twisted Vine", + "block.betterend.shadow_berry": "Shadow Berry Seeds", + "item.betterend.shadow_berry_cooked": "Shadow Berry Cooked", + "item.betterend.shadow_berry_raw": "Shadow Berry", + "block.betterend.purple_polypore": "Purple Polypore", + "block.betterend.cyan_moss": "Cyan Moss", + "block.betterend.tail_moss": "Tail Moss", + "block.betterend.flavolite_lantern": "Flavolite Lantern", + "block.betterend.end_stone_lantern": "End Stone Lantern", + "block.betterend.violecite_lantern": "Violecite Lantern", + "entity.betterend.end_fish": "End Fish", + "entity.betterend.shadow_walker": "Shadow Walker", + "item.betterend.spawn_egg_shadow_walker": "Shadow Walker Spawn Egg", + "block.betterend.andesite_lantern": "Andesite Lantern", + "block.betterend.blackstone_lantern": "Blackstone Lantern", + "block.betterend.diorite_lantern": "Diorite Lantern", + "block.betterend.granite_lantern": "Granite Lantern", + "block.betterend.purpur_lantern": "Purpur Lantern", + "block.betterend.quartz_lantern": "Quartz Lantern", + "item.betterend.bucket_end_fish": "Bucket of End Fish", + "item.betterend.bucket_cubozoa": "Bucket of Cubozoa", + "item.betterend.end_fish_cooked": "Cooked End Fish", + "item.betterend.end_fish_raw": "End Fish", + "biome.betterend.amber_land": "Amber Land", + "biome.betterend.blossoming_spires": "Blossoming Spires", + "block.betterend.amber_grass": "Amber Grass", + "block.betterend.amber_grass_path": "Amber Grass Path", + "block.betterend.tenanea_bark": "Tenanea Bark", + "block.betterend.tenanea_barrel": "Tenanea Barrel", + "block.betterend.tenanea_bookshelf": "Tenanea Bookshelf", + "block.betterend.tenanea_button": "Tenanea Button", + "block.betterend.tenanea_chest": "Tenanea Chest", + "block.betterend.tenanea_crafting_table": "Tenanea Crafting Table", + "block.betterend.tenanea_door": "Tenanea Door", + "block.betterend.tenanea_fence": "Tenanea Fence", + "block.betterend.tenanea_gate": "Tenanea Gate", + "block.betterend.tenanea_ladder": "Tenanea Ladder", + "block.betterend.tenanea_leaves": "Tenanea Leaves", + "block.betterend.tenanea_log": "Tenanea Log", + "block.betterend.tenanea_planks": "Tenanea Planks", + "block.betterend.tenanea_plate": "Tenanea Pressure Plate", + "block.betterend.tenanea_sapling": "Tenanea Sapling", + "block.betterend.tenanea_sign": "Tenanea Sign", + "block.betterend.tenanea_slab": "Tenanea Slab", + "block.betterend.tenanea_stairs": "Tenanea Stairs", + "block.betterend.tenanea_stripped_bark": "Stripped Tenanea Bark", + "block.betterend.tenanea_stripped_log": "Stripped Tenanea Log", + "block.betterend.tenanea_trapdoor": "Tenanea Trapdoor", + "block.betterend.amber_block": "Amber Block", + "block.betterend.amber_ore": "Amber Ore", + "item.betterend.amber_gem": "Amber Gem", + "item.betterend.raw_amber": "Raw Amber", + "block.betterend.tenanea_flowers": "Tenanea Flowers", + "block.betterend.tenanea_outer_leaves": "Tenanea Outer Leaves", + "block.betterend.pink_moss": "Pink Moss", + "block.betterend.pink_moss_path": "Pink Moss Path", + "block.betterend.twisted_moss": "Twisted Moss", + "block.betterend.bulb_vine": "Bulb Vine", + "block.betterend.bulb_vine_seed": "Bulb Vine Seed", + "item.betterend.glowing_bulb": "Glowing Bulb", + "block.betterend.iron_bulb_lantern": "Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_black": "Black Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_blue": "Blue Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_brown": "Brown Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_cyan": "Cyan Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_gray": "Gray Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_green": "Green Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_light_blue": "Light Blue Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_light_gray": "Light Gray Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_lime": "Lime Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_magenta": "Magenta Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_orange": "Orange Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_pink": "Pink Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_purple": "Purple Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_red": "Red Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_white": "White Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_yellow": "Yellow Iron Bulb Lantern", + "block.betterend.thallasium_bulb_lantern": "Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_black": "Black Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_blue": "Blue Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_brown": "Brown Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_cyan": "Cyan Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_gray": "Gray Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_green": "Green Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_light_blue": "Light Blue Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_light_gray": "Light Gray Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_lime": "Lime Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_magenta": "Magenta Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_orange": "Orange Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_pink": "Pink Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_purple": "Purple Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_red": "Red Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_white": "White Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_yellow": "Yellow Thallasium Bulb Lantern", + "block.betterend.bushy_grass": "Bushy Grass", + "block.betterend.brimstone": "Brimstone", + "block.betterend.sulphuric_rock": "Sulfuric Rock", + "block.betterend.sulphuric_rock_bricks": "Sulfuric Rock Bricks", + "block.betterend.sulphuric_rock_bricks_slab": "Sulfuric Rock Brick Slab", + "block.betterend.sulphuric_rock_bricks_stairs": "Sulfuric Rock Brick Stairs", + "block.betterend.sulphuric_rock_bricks_wall": "Sulfuric Rock Brick Wall", + "block.betterend.sulphuric_rock_button": "Sulfuric Rock Button", + "block.betterend.sulphuric_rock_lantern": "Sulfuric Rock Lantern", + "block.betterend.sulphuric_rock_pedestal": "Sulfuric Rock Pedestal", + "block.betterend.sulphuric_rock_pillar": "Sulfuric Rock Pillar", + "block.betterend.sulphuric_rock_plate": "Sulfuric Rock Pressure Plate", + "block.betterend.sulphuric_rock_polished": "Sulfuric Rock Polished", + "block.betterend.sulphuric_rock_slab": "Sulfuric Rock Slab", + "block.betterend.sulphuric_rock_stairs": "Sulfuric Rock Stairs", + "block.betterend.sulphuric_rock_tiles": "Sulfuric Rock Tiles", + "block.betterend.sulphuric_rock_wall": "Sulfuric Rock Wall", + "block.betterend.sulphur_crystal": "Sulfur Crystal", + "item.betterend.crystalline_sulphur": "Sulfur", + "biome.betterend.sulphur_springs": "Sulfur Springs", + "block.betterend.hydralux_petal_block": "Hydralux Petal Block", + "block.betterend.hydralux_petal_block_black": "Black Petal Block", + "block.betterend.hydralux_petal_block_blue": "Blue Petal Block", + "block.betterend.hydralux_petal_block_brown": "Brown Petal Block", + "block.betterend.hydralux_petal_block_cyan": "Cyan Petal Block", + "block.betterend.hydralux_petal_block_gray": "Gray Petal Block", + "block.betterend.hydralux_petal_block_green": "Green Petal Block", + "block.betterend.hydralux_petal_block_light_blue": "Light Blue Petal Block", + "block.betterend.hydralux_petal_block_light_gray": "Light Gray Petal Block", + "block.betterend.hydralux_petal_block_lime": "Lime Petal Block", + "block.betterend.hydralux_petal_block_magenta": "Magenta Petal Block", + "block.betterend.hydralux_petal_block_orange": "Orange Petal Block", + "block.betterend.hydralux_petal_block_pink": "Pink Petal Block", + "block.betterend.hydralux_petal_block_purple": "Purple Petal Block", + "block.betterend.hydralux_petal_block_red": "Red Petal Block", + "block.betterend.hydralux_petal_block_white": "White Petal Block", + "block.betterend.hydralux_petal_block_yellow": "Yellow Petal Block", + "block.betterend.hydralux_sapling": "Hydralux Sapling", + "block.betterend.hydrothermal_vent": "Hydrothermal Vent", + "item.betterend.hydralux_petal": "Hydralux Petal", + "item.betterend.enchanted_petal": "Enchanted Petal", + "block.betterend.menger_sponge": "Menger Sponge", + "block.betterend.menger_sponge_wet": "Wet Menger Sponge", + "block.betterend.tube_worm": "Tube Worm", + "block.betterend.charnia_cyan": "Cyan Charnia", + "block.betterend.charnia_light_blue": "Light Blue Charnia", + "block.betterend.charnia_orange": "Orange Charnia", + "block.betterend.charnia_purple": "Purple Charnia", + "block.betterend.charnia_red": "Red Charnia", + "entity.betterend.cubozoa": "Cubozoa", + "item.betterend.spawn_egg_cubozoa": "Cubozoa Spawn Egg", + "item.betterend.gelatine": "Gelatine", + "item.betterend.sweet_berry_jelly": "Sweet Berry Jelly", + "item.betterend.shadow_berry_jelly": "Shadow Berry Jelly", + "block.betterend.amber_moss": "Amber Moss", + "block.betterend.amber_moss_path": "Amber Moss Path", + "block.betterend.helix_tree_bark": "Helix Tree Bark", + "block.betterend.helix_tree_barrel": "Helix Tree Barrel", + "block.betterend.helix_tree_bookshelf": "Helix Tree Bookshelf", + "block.betterend.helix_tree_button": "Helix Tree Button", + "block.betterend.helix_tree_chest": "Helix Tree Chest", + "block.betterend.helix_tree_crafting_table": "Helix Tree Crafting Table", + "block.betterend.helix_tree_door": "Helix Tree Door", + "block.betterend.helix_tree_fence": "Helix Tree Fence", + "block.betterend.helix_tree_gate": "Helix Tree Gate", + "block.betterend.helix_tree_ladder": "Helix Tree Ladder", + "block.betterend.helix_tree_leaves": "Helix Tree Leaves", + "block.betterend.helix_tree_log": "Helix Tree Log", + "block.betterend.helix_tree_planks": "Helix Tree Planks", + "block.betterend.helix_tree_plate": "Helix Tree Pressure Plate", + "block.betterend.helix_tree_sapling": "Helix Tree Sapling", + "block.betterend.helix_tree_sign": "Helix Tree Sign", + "block.betterend.helix_tree_slab": "Helix Tree Slab", + "block.betterend.helix_tree_stairs": "Helix Tree Stairs", + "block.betterend.helix_tree_stripped_bark": "Stripped Helix Tree Bark", + "block.betterend.helix_tree_stripped_log": "Stripped Helix Tree Log", + "block.betterend.helix_tree_trapdoor": "Helix Tree Trapdoor", + "block.betterend.lanceleaf": "Lanceleaf", + "block.betterend.lanceleaf_seed": "Lanceleaf Seed", + "block.betterend.hydralux": "Hydralux", + "block.betterend.helix_tree_luminophor": "Helix Tree Luminophor", + "block.betterend.glowing_pillar_leaves": "Glowing Pillar Leaves", + "block.betterend.glowing_pillar_luminophor": "Glowing Pillar Luminophor", + "block.betterend.glowing_pillar_roots": "Glowing Pillar Roots", + "block.betterend.glowing_pillar_seed": "Glowing Pillar Seed", + "biome.betterend.ice_starfield": "Ice Starfield", + "block.betterend.ancient_emerald_ice": "Ancient Emerald Ice", + "block.betterend.dense_emerald_ice": "Dense Emerald Ice", + "block.betterend.dense_snow": "Dense Snow", + "block.betterend.emerald_ice": "Emerald Ice", + "block.betterend.bulb_moss": "Bulb Moss", + "block.betterend.charnia_green": "Green Charnia", + "block.betterend.vent_bubble_column": "Vent Bubble Column", + "block.betterend.respawn_obelisk": "Respawn Obelisk", + "message.betterend.set_spawn": "\u00A7b\u00A7lYour spawn point is set here", + "message.betterend.fail_spawn": "\u00A7c\u00A7lYou need to hold 6 Amber Gems to set your spawn point", + "block.betterend.dragon_tree_composter": "Dragon Tree Composter", + "block.betterend.end_lotus_composter": "End Lotus Composter", + "block.betterend.helix_tree_composter": "Helix Tree Composter", + "block.betterend.lacugrove_composter": "Lacugrove Composter", + "block.betterend.mossy_glowshroom_composter": "Mossy Glowshroom Composter", + "block.betterend.pythadendron_composter": "Pythadendron Composter", + "block.betterend.tenanea_composter": "Tenanea Composter", + "biome.betterend.old_bulbis_gardens": "Old Bulbis Gardens", + "block.betterend.ivis_moss": "Ivis Moss", + "block.betterend.ivis_vine": "Ivis Vine", + "block.betterend.silk_moth_nest": "Silk Moth Nest", + "block.betterend.umbrella_tree_bark": "Umbrella Tree Bark", + "block.betterend.umbrella_tree_barrel": "Umbrella Tree Barrel", + "block.betterend.umbrella_tree_bookshelf": "Umbrella Tree Bookshelf", + "block.betterend.umbrella_tree_button": "Umbrella Tree Button", + "block.betterend.umbrella_tree_chest": "Umbrella Tree Chest", + "block.betterend.umbrella_tree_composter": "Umbrella Tree Composter", + "block.betterend.umbrella_tree_crafting_table": "Umbrella Tree Crafting Table", + "block.betterend.umbrella_tree_door": "Umbrella Tree Door", + "block.betterend.umbrella_tree_fence": "Umbrella Tree Fence", + "block.betterend.umbrella_tree_gate": "Umbrella Tree Gate", + "block.betterend.umbrella_tree_ladder": "Umbrella Tree Ladder", + "block.betterend.umbrella_tree_log": "Umbrella Tree Log", + "block.betterend.umbrella_tree_planks": "Umbrella Tree Planks", + "block.betterend.umbrella_tree_plate": "Umbrella Tree Pressure Plate", + "block.betterend.umbrella_tree_sign": "Umbrella Tree Sign", + "block.betterend.umbrella_tree_slab": "Umbrella Tree Slab", + "block.betterend.umbrella_tree_stairs": "Umbrella Tree Stairs", + "block.betterend.umbrella_tree_stripped_bark": "Stripped Umbrella Tree Bark", + "block.betterend.umbrella_tree_stripped_log": "Stripped Umbrella Tree Log", + "block.betterend.umbrella_tree_trapdoor": "Umbrella Tree Trapdoor", + "block.betterend.umbrella_tree_membrane": "Umbrella Tree Membrane", + "biome.betterend.umbrella_jungle": "Umbrella Jungle", + "block.betterend.jungle_grass": "Jungle Grass", + "block.betterend.jungle_moss": "Jungle Moss", + "block.betterend.jungle_moss_path": "Jungle Moss Path", + "block.betterend.small_jellyshroom": "Small Jellyshroom", + "block.betterend.twisted_umbrella_moss": "Twisted Umbrella Moss", + "block.betterend.twisted_umbrella_moss_tall": "Twisted Umbrella Moss Tall", + "block.betterend.umbrella_tree_cluster": "Umbrella Tree Cluster", + "block.betterend.umbrella_tree_cluster_empty": "Empty Umbrella Tree Cluster", + "block.betterend.jungle_vine": "Jungle Vine", + "block.betterend.jungle_fern": "Jungle Fern", + "block.betterend.jellyshroom_bark": "Jellyshroom Bark", + "block.betterend.jellyshroom_barrel": "Jellyshroom Barrel", + "block.betterend.jellyshroom_bookshelf": "Jellyshroom Bookshelf", + "block.betterend.jellyshroom_button": "Jellyshroom Button", + "block.betterend.jellyshroom_cap_purple": "Purple Jellyshroom Cap", + "block.betterend.jellyshroom_chest": "Jellyshroom Chest", + "block.betterend.jellyshroom_composter": "Jellyshroom Composter", + "block.betterend.jellyshroom_crafting_table": "Jellyshroom Crafting Table", + "block.betterend.jellyshroom_door": "Jellyshroom Door", + "block.betterend.jellyshroom_fence": "Jellyshroom Fence", + "block.betterend.jellyshroom_gate": "Jellyshroom Gate", + "block.betterend.jellyshroom_ladder": "Jellyshroom Ladder", + "block.betterend.jellyshroom_log": "Jellyshroom Log", + "block.betterend.jellyshroom_planks": "Jellyshroom Planks", + "block.betterend.jellyshroom_plate": "Jellyshroom Pressure Plate", + "block.betterend.jellyshroom_sign": "Jellyshroom Sign", + "block.betterend.jellyshroom_slab": "Jellyshroom Slab", + "block.betterend.jellyshroom_stairs": "Jellyshroom Stairs", + "block.betterend.jellyshroom_stripped_bark": "Stripped Jellyshroom Bark", + "block.betterend.jellyshroom_stripped_log": "Stripped Jellyshroom Log", + "block.betterend.jellyshroom_trapdoor": "Jellyshroom Trapdoor", + "biome.betterend.eterial_grove": "Eterial Grove", + "block.betterend.umbrella_tree_sapling": "Umbrella Tree Sapling", + "item.betterend.umbrella_cluster_juice": "Umbrella Cluster Juice", + "block.betterend.blossom_berry_seed": "Blossom Berry Seed", + "item.betterend.blossom_berry": "Blossom Berry", + "biome.betterend.nightshade_redwoods": "Nightshade Redwoods", + "block.betterend.nightshade_moss": "Nightshade Moss", + "biome.betterend.glowing_grasslands": "Glowing Grasslands", + "block.betterend.blooming_cooksonia": "Blooming Cooksonia", + "block.betterend.fracturn": "Fracturn", + "block.betterend.lumecorn": "Lumecorn", + "block.betterend.salteago": "Salteago", + "block.betterend.vaiolush_fern": "Vaiolush Fern", + "entity.betterend.silk_moth": "Silk Moth", + "item.betterend.silk_fiber": "Silk Fiber", + "item.betterend.spawn_egg_silk_moth": "Silk Moth Spawn Egg", + "item.betterend.thallasium_raw": "Raw Thallasium", + "block.betterend.thallasium_ore": "Thallasium Ore", + "item.betterend.thallasium_axe": "Thallasium Axe", + "item.betterend.thallasium_hoe": "Thallasium Hoe", + "item.betterend.thallasium_ingot": "Thallasium Ingot", + "item.betterend.thallasium_pickaxe": "Thallasium Pickaxe", + "item.betterend.thallasium_shovel": "Thallasium Shovel", + "item.betterend.thallasium_sword": "Thallasium Sword", + "block.betterend.thallasium_block": "Thallasium Block", + "block.betterend.thallasium_bars": "Thallasium Bars", + "block.betterend.thallasium_door": "Thallasium Door", + "block.betterend.thallasium_plate": "Thallasium Pressure Plate", + "block.betterend.thallasium_tile": "Thallasium Tile", + "block.betterend.thallasium_trapdoor": "Thallasium Trapdoor", + "block.betterend.lumecorn_seed": "Lumecorn Seed", + "item.betterend.lumecorn_rod": "Lumecorn Rod", + "block.betterend.thallasium_chandelier": "Thallasium Chandelier", + "block.betterend.thallasium_anvil": "Thallasium Anvil", + "block.betterend.thallasium_chain": "Thallasium Chain", + "block.betterend.thallasium_slab": "Thallasium Slab", + "block.betterend.thallasium_stairs": "Thallasium Stairs", + "block.betterend.gold_chandelier": "Gold Chandelier", + "block.betterend.iron_chandelier": "Iron Chandelier", + "item.betterend.thallasium_nugget": "Thallasium Nugget", + "block.betterend.terminite_anvil": "Terminite Anvil", + "block.betterend.terminite_bars": "Terminite Bars", + "block.betterend.terminite_bulb_lantern": "Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_black": "Black Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_blue": "Blue Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_brown": "Brown Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_cyan": "Cyan Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_gray": "Gray Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_green": "Green Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_light_blue": "Light Blue Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_light_gray": "Light Gray Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_lime": "Lime Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_magenta": "Magenta Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_orange": "Orange Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_pink": "Pink Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_purple": "Purple Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_red": "Red Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_white": "White Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_yellow": "Yellow Terminite Bulb Lantern", + "block.betterend.terminite_chain": "Terminite Chain", + "block.betterend.terminite_chandelier": "Terminite Chandelier", + "block.betterend.terminite_door": "Terminite Door", + "block.betterend.terminite_plate": "Terminite Pressure Plate", + "block.betterend.terminite_slab": "Terminite Slab", + "block.betterend.terminite_stairs": "Terminite Stairs", + "block.betterend.terminite_tile": "Terminite Tile", + "block.betterend.terminite_trapdoor": "Terminite Trapdoor", + "item.betterend.terminite_nugget": "Terminite Nugget", + "item.betterend.thallasium_boots": "Thallasium Boots", + "item.betterend.thallasium_chestplate": "Thallasium Chestplate", + "item.betterend.thallasium_hammer": "Thallasium Hammer", + "item.betterend.thallasium_helmet": "Thallasium Helmet", + "item.betterend.thallasium_leggings": "Thallasium Leggings", + "block.betterend.missing_tile": "Missing Tile", + "block.betterend.charcoal_block": "Charcoal Block", + "block.betterend.end_stone_furnace": "End Stone Furnace", + "block.betterend.flavolite_furnace": "Flavolite Furnace", + "block.betterend.sulphuric_rock_furnace": "Sulfuric Rock Furnace", + "block.betterend.violecite_furnace": "Violecite Furnace", + "item.betterend.terminite_axe_head": "Terminite Axe Head", + "item.betterend.terminite_hoe_head": "Terminite Hoe Head", + "item.betterend.terminite_pickaxe_head": "Terminite Pickaxe Head", + "item.betterend.terminite_shovel_head": "Terminite Shovel Head", + "item.betterend.terminite_sword_blade": "Terminite Sword Blade", + "item.betterend.terminite_sword_handle": "Terminite Sword Handle", + "item.betterend.thallasium_axe_head": "Thallasium Axe Head", + "item.betterend.thallasium_hoe_head": "Thallasium Hoe Head", + "item.betterend.thallasium_pickaxe_head": "Thallasium Pickaxe Head", + "item.betterend.thallasium_shovel_head": "Thallasium Shovel Head", + "item.betterend.thallasium_sword_blade": "Thallasium Sword Blade", + "item.betterend.thallasium_sword_handle": "Thallasium Sword Handle", + "block.betterend.aeternium_anvil": "Aeternium Anvil", + "biome.betterend.dragon_graveyards": "Dragon Graveyards", + "biome.betterend.dry_shrubland": "Dry Shrubland", + "block.betterend.aeridium": "Aeridium", + "block.betterend.amaranita_cap": "Amaranita Cap", + "block.betterend.amaranita_fur": "Amaranita Fur", + "block.betterend.amaranita_hymenophore": "Amaranita Hymenophore", + "block.betterend.amaranita_hyphae": "Amaranita Hyphae", + "block.betterend.amaranita_lantern": "Amaranita Lantern", + "block.betterend.amaranita_stem": "Amaranita Stem", + "block.betterend.clawfern": "Clawfern", + "block.betterend.globulagus": "Globulagus", + "block.betterend.lamellarium": "Lamellarium", + "block.betterend.large_amaranita_mushroom": "Large Amaranita Mushroom", + "block.betterend.lutebus": "Lutebus", + "block.betterend.mossy_bone": "Mossy Bone", + "block.betterend.mossy_obsidian": "Mossy Obsidian", + "block.betterend.orango": "Orango", + "block.betterend.rutiscus": "Rutiscus", + "block.betterend.rutiscus_path": "Rutiscus Path", + "block.betterend.sangnum": "Sangnum", + "block.betterend.sangnum_path": "Sangnum Path", + "block.betterend.small_amaranita_mushroom": "Small Amaranita Mushroom", + "block.betterend.amber_root_seed": "Amber Root Seed", + "block.betterend.azure_jadestone": "Azure Jadestone", + "block.betterend.azure_jadestone_bricks": "Azure Jadestone Bricks", + "block.betterend.azure_jadestone_bricks_slab": "Azure Jadestone Brick Slab", + "block.betterend.azure_jadestone_bricks_stairs": "Azure Jadestone Brick Stairs", + "block.betterend.azure_jadestone_bricks_wall": "Azure Jadestone Brick Wall", + "block.betterend.azure_jadestone_button": "Azure Jadestone Button", + "block.betterend.azure_jadestone_furnace": "Azure Jadestone Furnace", + "block.betterend.azure_jadestone_lantern": "Azure Jadestone Lantern", + "block.betterend.azure_jadestone_pedestal": "Azure Jadestone Pedestal", + "block.betterend.azure_jadestone_pillar": "Azure Jadestone Pillar", + "block.betterend.azure_jadestone_plate": "Azure Jadestone Pressure Plate", + "block.betterend.azure_jadestone_polished": "Azure Jadestone Polished", + "block.betterend.azure_jadestone_slab": "Azure Jadestone Slab", + "block.betterend.azure_jadestone_stairs": "Azure Jadestone Stairs", + "block.betterend.azure_jadestone_tiles": "Azure Jadestone Tiles", + "block.betterend.azure_jadestone_wall": "Azure Jadestone Wall", + "block.betterend.chorus_mushroom_seed": "Chorus Mushroom Seed", + "block.betterend.end_stone_stalactite": "End Stone Stalactite", + "block.betterend.end_stone_stalactite_cavemoss": "Cave Moss Endstone Stalactite", + "block.betterend.pearlberry_seed": "Pearlberry Seed", + "block.betterend.rubinea": "Rubinea", + "block.betterend.sandy_jadestone": "Sandy Jadestone", + "block.betterend.sandy_jadestone_bricks": "Sandy Jadestone Bricks", + "block.betterend.sandy_jadestone_bricks_slab": "Sandy Jadestone Brick Slab", + "block.betterend.sandy_jadestone_bricks_stairs": "Sandy Jadestone Brick Stairs", + "block.betterend.sandy_jadestone_bricks_wall": "Sandy Jadestone Brick Wall", + "block.betterend.sandy_jadestone_button": "Sandy Jadestone Button", + "block.betterend.sandy_jadestone_furnace": "Sandy Jadestone Furnace", + "block.betterend.sandy_jadestone_lantern": "Sandy Jadestone Lantern", + "block.betterend.sandy_jadestone_pedestal": "Sandy Jadestone Pedestal", + "block.betterend.sandy_jadestone_pillar": "Sandy Jadestone Pillar", + "block.betterend.sandy_jadestone_plate": "Sandy Jadestone Pressure Plate", + "block.betterend.sandy_jadestone_polished": "Sandy Jadestone Polished", + "block.betterend.sandy_jadestone_slab": "Sandy Jadestone Slab", + "block.betterend.sandy_jadestone_stairs": "Sandy Jadestone Stairs", + "block.betterend.sandy_jadestone_tiles": "Sandy Jadestone Tiles", + "block.betterend.sandy_jadestone_wall": "Sandy Jadestone Wall", + "block.betterend.smaragdant_crystal": "Smaragdant Crystal", + "block.betterend.smaragdant_crystal_shard": "Smaragdant Crystal Shard", + "block.betterend.virid_jadestone": "Virid Jadestone", + "block.betterend.virid_jadestone_bricks": "Virid Jadestone Bricks", + "block.betterend.virid_jadestone_bricks_slab": "Virid Jadestone Brick Slab", + "block.betterend.virid_jadestone_bricks_stairs": "Virid Jadestone Brick Stairs", + "block.betterend.virid_jadestone_bricks_wall": "Virid Jadestone Brick Wall", + "block.betterend.virid_jadestone_button": "Virid Jadestone Button", + "block.betterend.virid_jadestone_furnace": "Virid Jadestone Furnace", + "block.betterend.virid_jadestone_lantern": "Virid Jadestone Lantern", + "block.betterend.virid_jadestone_pedestal": "Virid Jadestone Pedestal", + "block.betterend.virid_jadestone_pillar": "Virid Jadestone Pillar", + "block.betterend.virid_jadestone_plate": "Virid Jadestone Pressure Plate", + "block.betterend.virid_jadestone_polished": "Virid Jadestone Polished", + "block.betterend.virid_jadestone_slab": "Virid Jadestone Slab", + "block.betterend.virid_jadestone_stairs": "Virid Jadestone Stairs", + "block.betterend.virid_jadestone_tiles": "Virid Jadestone Tiles", + "block.betterend.virid_jadestone_wall": "Virid Jadestone Wall", + "item.betterend.amber_root_raw": "Raw Amber Root", + "item.betterend.chorus_mushroom_cooked": "Cooked Chorus Mushroom", + "item.betterend.chorus_mushroom_raw": "Raw Chorus Mushroom", + "biome.betterend.empty_aurora_cave": "Empty Aurora Cave", + "biome.betterend.empty_end_cave": "Empty End Cave", + "biome.betterend.empty_smaragdant_cave": "Empty Smaragdant Cave", + "biome.betterend.lush_aurora_cave": "Lush Aurora Cave", + "biome.betterend.lush_smaragdant_cave": "Lush Smaragdant Cave", + "block.betterend.dragon_bone_block": "Dragon Bone Block", + "block.betterend.dragon_bone_slab": "Dragon Bone Slab", + "block.betterend.dragon_bone_stairs": "Dragon Bone Stairs", + "block.betterend.mossy_dragon_bone": "Mossy Dragon Bone", + "biome.betterend.lantern_woods": "Lantern Woods", + "block.betterend.filalux": "Filalux", + "block.betterend.filalux_lantern": "Filalux Lantern", + "block.betterend.filalux_wings": "Filalux Wings", + "block.betterend.lucernia_bark": "Lucernia Bark", + "block.betterend.lucernia_barrel": "Lucernia Barrel", + "block.betterend.lucernia_bookshelf": "Lucernia Bookshelf", + "block.betterend.lucernia_button": "Lucernia Button", + "block.betterend.lucernia_chest": "Lucernia Chest", + "block.betterend.lucernia_composter": "Lucernia Composter", + "block.betterend.lucernia_crafting_table": "Lucernia Crafting Table", + "block.betterend.lucernia_door": "Lucernia Door", + "block.betterend.lucernia_fence": "Lucernia Fence", + "block.betterend.lucernia_gate": "Lucernia Gate", + "block.betterend.lucernia_ladder": "Lucernia Ladder", + "block.betterend.lucernia_leaves": "Lucernia Leaves", + "block.betterend.lucernia_log": "Lucernia Log", + "block.betterend.lucernia_outer_leaves": "Lucernia Outer Leaves", + "block.betterend.lucernia_planks": "Lucernia Planks", + "block.betterend.lucernia_plate": "Lucernia Pressure Plate", + "block.betterend.lucernia_sapling": "Lucernia Sapling", + "block.betterend.lucernia_sign": "Lucernia Sign", + "block.betterend.lucernia_slab": "Lucernia Slab", + "block.betterend.lucernia_stairs": "Lucernia Stairs", + "block.betterend.lucernia_stripped_bark": "Stripped Lucernia Bark", + "block.betterend.lucernia_stripped_log": "Stripped Lucernia Log", + "block.betterend.lucernia_trapdoor": "Lucernia Trapdoor", + "block.betterend.aurant_polypore": "Aurant Polypore", + "block.betterend.bolux_mushroom": "Bolux Mushroom", + "block.betterend.flamaea": "Flamaea", + "block.betterend.pond_anemone": "Pond Anemone", + "block.betterend.ruscus": "Ruscus", + "item.betterend.bolux_mushroom_cooked": "Cooked Bolux Mushroom", + "block.betterend.silk_moth_hive": "Silk Moth Hive", + "item.betterend.silk_moth_matrix": "Silk Moth Matrix", + "biome.betterend.neon_oasis": "Neon Oasis", + "block.betterend.cave_pumpkin": "Cave Pumpkin", + "block.betterend.cave_pumpkin_seed": "Cave Pumpkin Seed", + "block.betterend.magnula": "Magnula", + "block.betterend.neon_cactus": "Neon Cactus", + "item.betterend.cave_pumpkin_pie": "Cave Pumpkin Pie", + "item.betterend.music_disc_strange_and_alien": "§bMusic Disc§r", + "item.betterend.music_disc_strange_and_alien.desc": "§5Firel§r - §fStrange And Alien§r", + "item.betterend.music_disc_grasping_at_stars": "§bMusic Disc§r", + "item.betterend.music_disc_grasping_at_stars.desc": "§5Firel§r - §fGrasping At Stars§r", + "item.betterend.music_disc_endseeker": "§bMusic Disc§r", + "item.betterend.music_disc_endseeker.desc": "§5Firel§r - §fEndseeker§r", + "item.betterend.music_disc_eo_dracona": "§bMusic Disc§r", + "item.betterend.music_disc_eo_dracona.desc": "§5Firel§r - §fEo Dracona§r", + "block.betterend.hydralux_petal_block_amber": "Amber Petal Block", + "block.betterend.hydralux_petal_block_beige": "Beige Petal Block", + "block.betterend.hydralux_petal_block_cream": "Cream Petal Block", + "block.betterend.hydralux_petal_block_dark_green": "Dark Green Petal Block", + "block.betterend.hydralux_petal_block_forest_green": "Forest Green Petal Block", + "block.betterend.hydralux_petal_block_hot_pink": "Hot Pink Petal Block", + "block.betterend.hydralux_petal_block_indigo": "Indigo Petal Block", + "block.betterend.hydralux_petal_block_maroon": "Maroon Petal Block", + "block.betterend.hydralux_petal_block_navy": "Navy Petal Block", + "block.betterend.hydralux_petal_block_olive": "Olive Petal Block", + "block.betterend.hydralux_petal_block_pale_green": "Pale Green Petal Block", + "block.betterend.hydralux_petal_block_pale_pink": "Pale Pink Petal Block", + "block.betterend.hydralux_petal_block_pale_yellow": "Pale Yellow Petal Block", + "block.betterend.hydralux_petal_block_sky_blue": "Sky Blue Petal Block", + "block.betterend.hydralux_petal_block_slate_gray": "Slate Gray Petal Block", + "block.betterend.hydralux_petal_block_violet": "Violet Petal Block", + "block.betterend.smaragdant_crystal_bricks": "Smaragdant Bricks", + "block.betterend.smaragdant_crystal_bricks_slab": "Smaragdant Brick Slab", + "block.betterend.smaragdant_crystal_bricks_stairs": "Smaragdant Brick Stairs", + "block.betterend.smaragdant_crystal_bricks_wall": "Smaragdant Brick Wall", + "block.betterend.smaragdant_crystal_pedestal": "Smaragdant Pedestal", + "block.betterend.smaragdant_crystal_pillar": "Smaragdant Pillar", + "block.betterend.smaragdant_crystal_polished": "Polished Smaragdant", + "block.betterend.smaragdant_crystal_slab": "Smaragdant Slab", + "block.betterend.smaragdant_crystal_stairs": "Smaragdant Stairs", + "block.betterend.smaragdant_crystal_tiles": "Smaragdant Tiles", + "block.betterend.smaragdant_crystal_wall": "Smaragdant Wall", + "message.betterend.anvil_damage": "§cDamage", + "block.betterend.neon_cactus_block": "Neon Cactus Block", + "block.betterend.neon_cactus_slab": "Neon Cactus Slab", + "block.betterend.neon_cactus_stairs": "Neon Cactus Stairs", + "biome.betterend.jade_cave": "Jade Cave", + "item.betterend.blossom_berry_jelly": "Blossom Berry Jelly", + "item.betterend.aeternium_forged_plate": "Aeternium Forged Plate", + "item.betterend.terminite_forged_plate": "Terminite Forged Plate", + "item.betterend.thallasium_forged_plate": "Thallasium Forged Plate", + "attribute.name.generic.blindness_resistance": "Blindness Resistance", + "tooltip.armor.crystalite_set": "Set bonus: Regeneration I", + "tooltip.armor.crystalite_chest": "Effect: Dig Speed I", + "tooltip.armor.crystalite_boots": "Effect: Swiftness I", + "block.betterend.azure_jadestone_flower_pot": "Azure Jadestone Flower Pot", + "block.betterend.endstone_flower_pot": "Endstone Flower Pot", + "block.betterend.flavolite_flower_pot": "Flavolite Flower Pot", + "block.betterend.sandy_jadestone_flower_pot": "Sandy Jadestone Flower Pot", + "block.betterend.sulphuric_rock_flower_pot": "Sulphuric Rock Flower Pot", + "block.betterend.violecite_flower_pot": "Violecite Flower Pot", + "block.betterend.virid_jadestone_flower_pot": "Virid Jadestone Flower Pot", + "block.betterend.umbralith": "Umbralith", + "block.betterend.umbralith_bricks": "Umbralith Bricks", + "block.betterend.umbralith_bricks_slab": "Umbralith Bricks Slab", + "block.betterend.umbralith_bricks_stairs": "Umbralith Bricks Stairs", + "block.betterend.umbralith_bricks_wall": "Umbralith Bricks Wall", + "block.betterend.umbralith_button": "Umbralith Button", + "block.betterend.umbralith_flower_pot": "Umbralith Flower Pot", + "block.betterend.umbralith_furnace": "Umbralith Furnace", + "block.betterend.umbralith_lantern": "Umbralith Lantern", + "block.betterend.umbralith_pedestal": "Umbralith Pedestal", + "block.betterend.umbralith_pillar": "Umbralith Pillar", + "block.betterend.umbralith_plate": "Umbralith Pressure Plate", + "block.betterend.umbralith_polished": "Umbralith Polished", + "block.betterend.umbralith_slab": "Umbralith Slab", + "block.betterend.umbralith_stairs": "Umbralith Stairs", + "block.betterend.umbralith_tiles": "Umbralith Tiles", + "block.betterend.umbralith_wall": "Umbralith Wall", + "biome.betterend.umbra_valley": "Umbra Valley", + "block.betterend.inflexia": "Inflexia", + "block.betterend.pallidium_full": "Pallidium (Full Cover)", + "block.betterend.pallidium_heavy": "Pallidium (Heavy Cover)", + "block.betterend.pallidium_thin": "Pallidium (Thin Cover)", + "block.betterend.pallidium_tiny": "Pallidium (Tiny Cover)", + "block.betterend.flammalix": "Flammalix", + "tag.betterend.alloying_iron": "Iron Ores", + "tag.betterend.alloying_copper": "Copper Ores", + "tag.betterend.alloying_gold": "Gold Ores", + "tag.betterend.thallasium_alloying": "Thallasium Ores", + "tag.betterend.jellyshroom_logs": "Jellyshroom Logs", + "tag.betterend.umbrella_tree_logs": "Umbrella Logs", + "tag.betterend.lacugrove_logs": "Lacugrove Logs", + "tag.betterend.end_lotus_logs": "End-Lotus Logs", + "tag.betterend.pythadendron_logs": "Pythadendron Logs", + "tag.betterend.helix_tree_logs": "Helix-Tree Logs", + "tag.betterend.lucernia_logs": "Lucernia Logs", + "tag.betterend.dragon_tree_logs": "Dragon-Tree Logs", + "tag.betterend.mossy_glowshroom_logs": "Mossy Glowshroom Logs", + "tag.betterend.tenanea_logs": "Tenanea Logs", + "emi.category.betterend.infusion": "Infusion Ritual", + "betterend.infusion.north": "Northern Pedestal", + "betterend.infusion.north_west": "North-West Pedestal", + "betterend.infusion.west": "Western Pedestal", + "betterend.infusion.south_west": "South-West Pedestal", + "betterend.infusion.south": "Southern Pedestal", + "betterend.infusion.south_east": "South-East Pedestal", + "betterend.infusion.east": "Eastern Pedestal", + "betterend.infusion.north_east": "North-East Pedestal", + "advancements.betterend.root.title": "BetterEnd", + "advancements.betterend.root.description": "Discover the BetterEnd", + "advancements.betterend.portal.title": "On Eternal Paths", + "advancements.betterend.portal.description": "Discover a portal lost for eternity", + "advancements.betterend.portal_on.title": "Eternal Light", + "advancements.betterend.portal_on.description": "Light an eternal Portal", + "advancements.betterend.portal_travel.title": "Eternal Ways", + "advancements.betterend.portal_travel.description": "Reise auf uralten Pfaden und benutze ein ewiges Portal", + "advancements.betterend.all_the_biomes.title": "A New Ending", + "advancements.betterend.all_the_biomes.description": "Visit all BetterEnd Biomes", + "advancements.betterend.all_elytras.title": "Airshow", + "advancements.betterend.all_elytras.description": "Own all Elytra variants", + "advancements.betterend.infusion.title": "Old Rituals", + "advancements.betterend.infusion.description": "Obtain an Infusion Pedestal", + "advancements.betterend.infusion_finished.title": "Neverending Magic", + "advancements.betterend.infusion_finished.description": "Be close to an Infusion Ritual when it is finished" } diff --git a/src/main/resources/assets/betterend/lang/es_es.json b/src/main/resources/assets/betterend/lang/es_es.json new file mode 100644 index 00000000..efae5e35 --- /dev/null +++ b/src/main/resources/assets/betterend/lang/es_es.json @@ -0,0 +1,877 @@ +{ + "itemGroup.betterend.end_items": "Better End: Objetos", + "itemGroup.betterend.end_blocks": "Better End: Bloques", + + "item.betterend.guidebook": "El End para Bobos", + "book.betterend.landing": "Una pequeña guía para sobrevivir en las condiciones exstremas del End.", + "book.betterend.subtitle": "Sobrevivir en el End", + + "category.rei.damage.amount&dmg": "Daño de la herramienta: %s", + "category.rei.infusion.time&val": "Tiempo: %s", + + "biome.betterend.foggy_mushroomland": "Tierra de Setas Nublada", + "biome.betterend.dust_wastelands": "Tierras de Desecho de Polvo", + "biome.betterend.chorus_forest": "Bosque Coral", + "biome.betterend.megalake": "Megalago", + "biome.betterend.crystal_mountains": "Montañas de Cristal", + + "entity.betterend.dragonfly": "Libélula", + "item.betterend.spawn_egg_dragonfly": "Huevo de Generación de Libélula", + + "entity.betterend.end_slime": "Slime del End", + "item.betterend.spawn_egg_end_slime": "Huevo de Generación de Slime del End", + + "block.betterend.end_mycelium": "Micelio del End", + "block.betterend.end_moss": "Musgo del End", + "block.betterend.endstone_dust": "Polvo de Piedra del End", + + "block.betterend.end_mycelium_path": "Camino de Micelio del End", + "block.betterend.end_moss_path": "Camino de Musgo del End", + + "block.betterend.ender_ore": "Mena de Ender", + "block.betterend.terminite_block": "Bloque de Terminita", + "block.betterend.aeternium_block": "Bloque de Aeternio", + "block.betterend.ender_block": "Bloque de Ender", + "block.betterend.end_stone_smelter": "Fundidor de Piedra del End", + + "item.betterend.ender_dust": "Polvo de Ender", + "item.betterend.ender_shard": "Fragmento de Ender", + "item.betterend.terminite_ingot": "Lingote de Terminita", + "item.betterend.aeternium_ingot": "Lingote de Aeternio", + "item.betterend.terminite_helmet": "Casco de Terminita", + "item.betterend.terminite_chestplate": "Pechera de Terminita", + "item.betterend.terminite_leggings": "Grebas de Terminita", + "item.betterend.terminite_boots": "Botas de Terminita", + "item.betterend.terminite_shovel": "Pala de Terminita", + "item.betterend.terminite_sword": "Espada de Terminita", + "item.betterend.terminite_pickaxe": "Pico de Terminita", + "item.betterend.terminite_axe": "Hacha de Terminita", + "item.betterend.terminite_hoe": "Azada de Terminita", + "item.betterend.terminite_hammer": "Maryillo Herrero de Terminita", + "item.betterend.aeternium_helmet": "Casco de Aeternio", + "item.betterend.aeternium_chestplate": "Pechera de Aeternio", + "item.betterend.aeternium_leggings": "Grebas de Aeternio", + "item.betterend.aeternium_boots": "Botas de Aeternio", + "item.betterend.aeternium_shovel": "Pala de Aeternio", + "item.betterend.aeternium_sword": "Espada de Aeternio", + "item.betterend.aeternium_pickaxe": "Pico de Aeternio", + "item.betterend.aeternium_axe": "Hacha de Aeternio", + "item.betterend.aeternium_hoe": "Azada de Aeternio", + "item.betterend.aeternium_hammer": "Martillo Herrero de Aeternio", + "item.betterend.iron_hammer": "Martillo Herrero de Hierro", + "item.betterend.golden_hammer": "Martillo Herrero de Oro", + "item.betterend.diamond_hammer": "Martillo Herrero de Diamante", + "item.betterend.netherite_hammer": "Martillo Herrero de Netherite", + "item.betterend.crystalite_boots": "Botas de Cristalita", + "item.betterend.crystalite_chestplate": "Pechera de Cristalita", + "item.betterend.crystalite_helmet": "Casco de Cristalita", + "item.betterend.crystalite_leggings": "Grebas de Cristalita", + "item.betterend.aeternium_axe_head": "Aeternium Axe Head", + "item.betterend.aeternium_hammer_head": "Aeternium Hammer Head", + "item.betterend.aeternium_hoe_head": "Cabeza de Azada de Aeternio", + "item.betterend.aeternium_pickaxe_head": "Cabeza de Pico de Aeternio", + "item.betterend.aeternium_shovel_head": "Cabeza de Pala de Aeternio", + "item.betterend.aeternium_sword_blade": "Hoja de Espada de Aeternio", + "item.betterend.aeternium_sword_handle": "Mango de Espada de Aeternio", + "item.betterend.leather_stripe": "Raya de Cuero", + "item.betterend.leather_wrapped_stick": "Palo Envuelto con Cuero", + "item.betterend.elytra_armored": "Elytra Blindada", + "item.betterend.elytra_crystalite": "Elytra de Cristalite", + "item.betterend.enchanted_membrane": "Membrana Encantada", + + "effect.betterend.end_veil": "Velo del End", + "enchantment.betterend.end_veil": "Velo del End", + "item.minecraft.potion.effect.end_veil": "Poción de Velo del End", + "item.minecraft.potion.effect.long_end_veil": "Poción de Velo del End", + "item.minecraft.splash_potion.effect.end_veil": "Poción Arrojadiza de Velo del End", + "item.minecraft.splash_potion.effect.long_end_veil": "Poción Arrojadiza de Velo del End", + "item.minecraft.lingering_potion.effect.end_veil": "Poción de Efecto Duradero de Velo del End", + "item.minecraft.lingering_potion.effect.long_end_veil": "Poción de Efecto Duradero de Velo del End", + "item.minecraft.tipped_arrow.effect.end_veil": "Flecha de Velo del End", + "item.minecraft.tipped_arrow.effect.long_end_veil": "Flecha de Velo del End", + + "block.betterend.mossy_glowshroom_sapling": "Sapling de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_cap": "Gorra de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_fur": "Pelo de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_hymenophore": "Himenóforo de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_bark": "Corteza de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_barrel": "Barril de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_button": "Botón de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_chest": "Cofre de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_crafting_table": "Mesa de Crafteo de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_door": "Puerta de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_fence": "Valla de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_gate": "Puerta de Valla de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_ladder": "Escalera de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_log": "Tronco de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_planks": "Tablones de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_plate": "Placa de Presión de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_sign": "Cartel de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_slab": "Losa de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_stairs": "Escaleras de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_stripped_bark": "Corteza Despojada de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_stripped_log": "Tronco Despojado de Seta Luminosa Musgosa", + "block.betterend.mossy_glowshroom_trapdoor": "Trampilla de Seta Luminosa Musgosa", + + "block.betterend.umbrella_moss": "Paraguas de Musgo", + "block.betterend.umbrella_moss_tall": "Paraguas de Musgo Alto", + "block.betterend.creeping_moss": "Musgo Reptante", + + "block.betterend.blue_vine_seed": "Semilla de Vid Azul", + "block.betterend.blue_vine": "Vid Azul", + "block.betterend.blue_vine_lantern": "Linterna de Vid Azul", + "block.betterend.blue_vine_fur": "Pelo de Vid Azul", + + "block.betterend.dense_vine": "Vid Densa", + "block.betterend.bubble_coral": "Burbuja Coral", + "block.betterend.aurora_crystal": "Cristal Aurora", + "item.betterend.crystal_shards": "Fragmentos de Cristal", + + "block.betterend.pythadendron_sapling": "Sapling de Fitadendrón", + "block.betterend.pythadendron_bark": "Corteza de Fitadendrón", + "block.betterend.pythadendron_barrel": "Barril de Fitadendrón", + "block.betterend.pythadendron_button": "Botón de Fitadendrón", + "block.betterend.pythadendron_chest": "Cofre de Fitadendrón", + "block.betterend.pythadendron_crafting_table": "Mesa de Crafteo de Fitadendrón", + "block.betterend.pythadendron_door": "Puerta de Fitadendrón", + "block.betterend.pythadendron_fence": "Valla de Fitadendrón", + "block.betterend.pythadendron_gate": "Puerta de Valla de Fitadendrón", + "block.betterend.pythadendron_ladder": "Escalera de Fitadendrón", + "block.betterend.pythadendron_log": "Tronco de Fitadendrón", + "block.betterend.pythadendron_planks": "Tablones de Fitadendrón", + "block.betterend.pythadendron_plate": "Placa de Presión de Fitadendrón", + "block.betterend.pythadendron_sign": "Cartel de Fitadendrón", + "block.betterend.pythadendron_slab": "Losa de Fitadendrón", + "block.betterend.pythadendron_stairs": "Escaleras de Fitadendrón", + "block.betterend.pythadendron_stripped_bark": "Corteza Despojada de Fitadendrón", + "block.betterend.pythadendron_stripped_log": "Tronco Despojado de Fitadendrón", + "block.betterend.pythadendron_trapdoor": "Trampilla de Fitadendrón", + + "block.betterend.chorus_nylium": "Nilio Coral", + "block.betterend.chorus_nylium_path": "Camino de Nilio Coras", + "block.betterend.chorus_grass": "Hierba Coral", + + "block.betterend.end_lily": "Nenúfar del End", + "block.betterend.end_lily_seed": "Semilla de Nenúfar del End", + "item.betterend.end_lily_leaf": "Hoja de Nenúfar del End", + "item.betterend.end_lily_leaf_dried": "Hoja Seca de Nenúfar del End", + + "block.betterend.violecite": "Violecita", + "block.betterend.violecite_bricks": "Ladrillos de Violecita", + "block.betterend.violecite_bricks_slab": "Losa de Ladrillos de Violecita", + "block.betterend.violecite_bricks_stairs": "Escaleras de Ladrillos de Violecita", + "block.betterend.violecite_bricks_wall": "Muro de Ladrillos de Violecita", + "block.betterend.violecite_button": "Botón de Violecita", + "block.betterend.violecite_pillar": "Pilar de Violecita", + "block.betterend.violecite_plate": "Placa de Presión de Violecita", + "block.betterend.violecite_slab": "Losa de Violecita", + "block.betterend.violecite_tiles": "Casilla de Violecita", + "block.betterend.violecite_stairs": "Escaleras de Violecita", + "block.betterend.violecite_polished": "Violecita Pulida", + "block.betterend.violecite_wall": "Muro de Violecita", + "block.betterend.violecite_pedestal": "Pedestal de Violecita", + + "block.betterend.flavolite": "Flavolita", + "block.betterend.flavolite_bricks": "Ladrillos de Flavolita", + "block.betterend.flavolite_bricks_slab": "Losa de Ladrillos de Flavolita", + "block.betterend.flavolite_bricks_stairs": "Escaleras de Ladrillos de Flavolita", + "block.betterend.flavolite_bricks_wall": "Muro de Ladrillos de Flavolita", + "block.betterend.flavolite_button": "Botón de Flavolita", + "block.betterend.flavolite_pillar": "Pilar de Flavolita", + "block.betterend.flavolite_plate": "Placa de Presión de Flavolita", + "block.betterend.flavolite_slab": "Losa de Flavolita", + "block.betterend.flavolite_tiles": "Casilla de Flavolita", + "block.betterend.flavolite_stairs": "Escaleras de Flavolita", + "block.betterend.flavolite_polished": "Flavolita Pulida", + "block.betterend.flavolite_wall": "Muro de Flavolita", + "block.betterend.flavolite_pedestal": "Pedestal de Flavolita", + + "block.betterend.andesite_pedestal": "Pedestal de Andesita", + "block.betterend.diorite_pedestal": "Pdestal de Diorita", + "block.betterend.granite_pedestal": "Pedestal de Granito", + "block.betterend.purpur_pedestal": "Pedestal de Purpur", + "block.betterend.quartz_pedestal": "Pedestal de Cuarzo", + "block.betterend.infusion_pedestal": "Pedestal de Infusión", + + "block.betterend.end_lotus_seed": "Semilla de Loto del End", + "block.betterend.end_lotus_stem": "Tallo de Loto del End", + "block.betterend.end_lotus_leaf": "Hoja de Loto del End", + "block.betterend.end_lotus_flower": "Flor de Loto el End", + + "block.betterend.end_lotus_bark": "Corteza de Loto del End", + "block.betterend.end_lotus_barrel": "Barril de Loto del End", + "block.betterend.end_lotus_button": "Botón de Loto del End", + "block.betterend.end_lotus_chest": "Cofre de Loto del End", + "block.betterend.end_lotus_crafting_table": "Mesa de Crafteo de Loto del End", + "block.betterend.end_lotus_door": "Puerta de Loto del End", + "block.betterend.end_lotus_fence": "Valla de Loto del End", + "block.betterend.end_lotus_gate": "Puerta de Valla de Loto del End", + "block.betterend.end_lotus_ladder": "Escalera de Loto del End", + "block.betterend.end_lotus_log": "Tronco de Loto del End", + "block.betterend.end_lotus_planks": "Tablones de Loto del End", + "block.betterend.end_lotus_plate": "Placa de Presión de Loto del End", + "block.betterend.end_lotus_sign": "Cartel de Loto del End", + "block.betterend.end_lotus_slab": "Losa de Loto del End", + "block.betterend.end_lotus_stairs": "Escaleras de Loto del End", + "block.betterend.end_lotus_stripped_bark": "Corteza Despojada de Loto del End", + "block.betterend.end_lotus_stripped_log": "Tronco Despojado de Loto del End", + "block.betterend.end_lotus_trapdoor": "Trampilla de Loto del End", + + "block.betterend.cave_moss": "Musgo de Cueva", + "block.betterend.cave_grass": "Hierba de Cueva", + "block.betterend.cave_bush": "Arbusto de Cueva", + + "block.betterend.cave_moss_path": "Camino de Musgo de Cueva", + "block.betterend.crystal_moss": "Musgo de Cristal", + "block.betterend.crystal_moss_path": "Camino de Musgo de Cristal", + "block.betterend.pythadendron_leaves": "Hojas de Fitadendrón", + "item.betterend.spawn_egg_end_fish": "Huevo de Generación de Pez del End", + "block.betterend.crystal_grass": "Hierba de Cristal", + + "block.betterend.flavolite_runed": "Flavolita de Runa", + "block.betterend.end_portal_block": "Portal del End", + "block.betterend.eternal_pedestal": "Pedestal Eterno", + "block.betterend.flavolite_runed_eternal": "Flavolita de Runa Eterna", + "item.betterend.eternal_crystal": "Cristal Eterno", + + "block.betterend.lacugrove_bark": "Corteza de Lacugrove", + "block.betterend.lacugrove_barrel": "Barril de Lacugrove", + "block.betterend.lacugrove_button": "Botón de Lacugrove", + "block.betterend.lacugrove_chest": "Cofre de Lacugrove", + "block.betterend.lacugrove_crafting_table": "Mesa de Crafteo de Lacugrove", + "block.betterend.lacugrove_door": "Puerta de Lacugrove", + "block.betterend.lacugrove_fence": "Valla de Lacugrove", + "block.betterend.lacugrove_gate": "Puerta de Valla de Lacugrove", + "block.betterend.lacugrove_ladder": "Escalera de Lacugrove", + "block.betterend.lacugrove_log": "Tronco de Lacugrove", + "block.betterend.lacugrove_planks": "Tablones de Lacugrove", + "block.betterend.lacugrove_plate": "Placa de Presión de Lacugrove", + "block.betterend.lacugrove_sign": "Cartel de Lacugrove", + "block.betterend.lacugrove_slab": "Losa de Lacugrove", + "block.betterend.lacugrove_stairs": "Escaleras de Lacugrove", + "block.betterend.lacugrove_stripped_bark": "Corteza Despojada de Lacugrove", + "block.betterend.lacugrove_stripped_log": "Tronco Despojado de Lacugrove", + "block.betterend.lacugrove_trapdoor": "Trampilla de Lacugrove", + + "block.betterend.lacugrove_leaves": "Hojas de Lacugrove", + "block.betterend.lacugrove_sapling": "Sapling de Lacugrove", + + "biome.betterend.megalake_grove": "Arboleda del Megalago", + "biome.betterend.painted_mountains": "Montañas Pintadas", + + "block.betterend.dragon_tree_bark": "Corteza de Árbol de Dragón", + "block.betterend.dragon_tree_barrel": "Barril de Árbol de Dragón", + "block.betterend.dragon_tree_button": "Botón de Árbol de Dragón", + "block.betterend.dragon_tree_chest": "Cofre de Árbol de Dragón", + "block.betterend.dragon_tree_crafting_table": "Mesa de Crafteo de Árbol de Dragón", + "block.betterend.dragon_tree_door": "Puerta de Árbol de Dragón", + "block.betterend.dragon_tree_fence": "Valla de Árbol de Dragón", + "block.betterend.dragon_tree_gate": "Puerta de Valla de Árbol de Dragón", + "block.betterend.dragon_tree_ladder": "Escalera de Árbol de Dragón", + "block.betterend.dragon_tree_log": "Tronco de Árbol de Dragón", + "block.betterend.dragon_tree_planks": "Tablones de Árbol de Dragón", + "block.betterend.dragon_tree_plate": "Placa de Presión de Árbol de Dragón", + "block.betterend.dragon_tree_sign": "Cartel de Árbol de Dragón", + "block.betterend.dragon_tree_slab": "Losa de Árbol de Dragón", + "block.betterend.dragon_tree_stairs": "Escaleras de Árbol de Dragón", + "block.betterend.dragon_tree_stripped_bark": "Corteza Despojada de Árbol de Dragón", + "block.betterend.dragon_tree_stripped_log": "Tronco Despojado de Árbol de Dragón", + "block.betterend.dragon_tree_trapdoor": "Trampilla de Árbol de Dragón", + + "biome.betterend.shadow_forest": "Bosque Sombrío", + "block.betterend.dragon_tree_leaves": "Hojas de Árbol de Dragón", + "block.betterend.dragon_tree_sapling": "Sapling de Árbol de Dragón", + "block.betterend.shadow_grass": "Hierba Sombría", + "block.betterend.shadow_grass_path": "Camino de Hierba Sombría", + "block.betterend.shadow_plant": "Planta Sombría", + + "block.betterend.dragon_tree_bookshelf": "Librería de Árbol de Dragón", + "block.betterend.end_lotus_bookshelf": "Librería de Loto del End", + "block.betterend.lacugrove_bookshelf": "Librería de Lacugrove", + "block.betterend.mossy_glowshroom_bookshelf": "Librería de Seta Luminosa Musgosa", + "block.betterend.pythadendron_bookshelf": "Librería de Fitadendrón", + + "block.betterend.murkweed": "Hierba Oscura", + "block.betterend.needlegrass": "Hierba Punzante", + "block.betterend.twisted_vine": "Vid Retorcida", + + "block.betterend.shadow_berry": "Semillas de Balla Sombría", + "item.betterend.shadow_berry_cooked": "Balla Sombría Cocinada", + "item.betterend.shadow_berry_raw": "Balla Sombría", + "block.betterend.purple_polypore": "Políporo Morado", + + "block.betterend.cyan_moss": "Musgo Cyan", + "block.betterend.tail_moss": "Musgo Cola", + + "block.betterend.flavolite_lantern": "Linterna de Flavolita", + "block.betterend.end_stone_lantern": "Linterna de Piedra del End", + "block.betterend.violecite_lantern": "Linterna de Violecita", + + "entity.betterend.end_fish": "Pez del End", + "entity.betterend.shadow_walker": "Caminador Sombrío", + "item.betterend.spawn_egg_shadow_walker": "Huevo de Generación de Caminador Sombrío", + + "block.betterend.andesite_lantern": "Linterna de Andesita", + "block.betterend.blackstone_lantern": "Linterna de Piedra Negra", + "block.betterend.diorite_lantern": "Linterna de Diorita", + "block.betterend.granite_lantern": "Linterna de Granito", + "block.betterend.purpur_lantern": "Linterna de Purpur", + "block.betterend.quartz_lantern": "Linterna de Cuarzo", + + "item.betterend.bucket_end_fish": "Cubo de Pez del End", + "item.betterend.bucket_cubozoa": "Cubo de Cubozoa", + "item.betterend.end_fish_cooked": "Pez del End Cocinado", + "item.betterend.end_fish_raw": "Pez del End", + + "biome.betterend.amber_land": "Tierra de Ámbar", + "biome.betterend.blossoming_spires": "Agujas Florecientes", + "block.betterend.amber_grass": "Hierba de Ámber", + "block.betterend.amber_grass_path": "Camino de Hierba de Ámber", + "block.betterend.tenanea_bark": "Corteza de Tenanea", + "block.betterend.tenanea_barrel": "Barril de Tenanea", + "block.betterend.tenanea_bookshelf": "Librería de Tenanea", + "block.betterend.tenanea_button": "Botón de Tenanea", + "block.betterend.tenanea_chest": "Cofre de Tenanea", + "block.betterend.tenanea_crafting_table": "Mesa de Crafteo de Tenanea", + "block.betterend.tenanea_door": "Puerta de Tenanea", + "block.betterend.tenanea_fence": "Valla de Tenanea", + "block.betterend.tenanea_gate": "Puerta de Valla de Tenanea", + "block.betterend.tenanea_ladder": "Escalera de Tenanea", + "block.betterend.tenanea_leaves": "Hojas de Tenanea", + "block.betterend.tenanea_log": "Tronco de Tenanea", + "block.betterend.tenanea_planks": "Tablones de Tenanea", + "block.betterend.tenanea_plate": "Placa de Presión de Tenanea", + "block.betterend.tenanea_sapling": "Sapling de Tenanea", + "block.betterend.tenanea_sign": "Cartel de Tenanea", + "block.betterend.tenanea_slab": "Losa de Tenanea", + "block.betterend.tenanea_stairs": "Escaleras de Tenanea", + "block.betterend.tenanea_stripped_bark": "Corteza Despojada de Tenanea", + "block.betterend.tenanea_stripped_log": "Tronco Despojado de Tenanea", + "block.betterend.tenanea_trapdoor": "Trampilla de Tenanea", + + "block.betterend.amber_block": "Bloque de Ámbar", + "block.betterend.amber_ore": "Mena de Ámbar", + "item.betterend.amber_gem": "Gema de Ámbar", + "item.betterend.raw_amber": "Ámbar Crudo", + "block.betterend.tenanea_flowers": "Flores de Tenanea", + "block.betterend.tenanea_outer_leaves": "Hojas Exteriores de Tenanea", + + "block.betterend.pink_moss": "Musgo Rosa", + "block.betterend.pink_moss_path": "Camino de Musgo Rosa", + + "block.betterend.twisted_moss": "Musgo Retorcido", + + "block.betterend.bulb_vine": "Vid de Bulbo", + "block.betterend.bulb_vine_seed": "Semilla de Vid de Bulbo", + "item.betterend.glowing_bulb": "Bulbo Brillante", + + "block.betterend.iron_bulb_lantern": "Linterna de Bulbo de Hierro", + "block.betterend.iron_bulb_lantern_black": "Linterna de Bulbo de Hierro Negra", + "block.betterend.iron_bulb_lantern_blue": "Linterna de Bulbo de Hierro Azul", + "block.betterend.iron_bulb_lantern_brown": "Linterna de Bulbo de Hierro Marrón", + "block.betterend.iron_bulb_lantern_cyan": "Linterna de Bulbo de Hierro Cyan", + "block.betterend.iron_bulb_lantern_gray": "Linterna de Bulbo de Hierro Gris", + "block.betterend.iron_bulb_lantern_green": "Linterna de Bulbo de Hierro Verde", + "block.betterend.iron_bulb_lantern_light_blue": "Linterna de Bulbo de Hierro Azul Claro", + "block.betterend.iron_bulb_lantern_light_gray": "Linterna de Bulbo de Hierro Gris Claro", + "block.betterend.iron_bulb_lantern_lime": "Linterna de Bulbo de Hierro Lima", + "block.betterend.iron_bulb_lantern_magenta": "Linterna de Bulbo de Hierro Magenta", + "block.betterend.iron_bulb_lantern_orange": "Linterna de Bulbo de Hierro Naranja", + "block.betterend.iron_bulb_lantern_pink": "Linterna de Bulbo de Hierro Rosa", + "block.betterend.iron_bulb_lantern_purple": "Linterna de Bulbo de Hierro Morada", + "block.betterend.iron_bulb_lantern_red": "Linterna de Bulbo de Hierro Roja", + "block.betterend.iron_bulb_lantern_white": "Linterna de Bulbo de Hierro Blanca", + "block.betterend.iron_bulb_lantern_yellow": "Linterna de Bulbo de Hierro Amarilla", + + "block.betterend.thallasium_bulb_lantern": "Linterna de Bulbo de Talismanio", + "block.betterend.thallasium_bulb_lantern_black": "Linterna de Bulbo de Talismanio Negra", + "block.betterend.thallasium_bulb_lantern_blue": "Linterna de Bulbo de Talismanio Azul", + "block.betterend.thallasium_bulb_lantern_brown": "Linterna de Bulbo de Talismanio Marrón", + "block.betterend.thallasium_bulb_lantern_cyan": "Linterna de Bulbo de Talismanio Cyan", + "block.betterend.thallasium_bulb_lantern_gray": "Linterna de Bulbo de Talismanio Gris", + "block.betterend.thallasium_bulb_lantern_green": "Linterna de Bulbo de Talismanio Verde", + "block.betterend.thallasium_bulb_lantern_light_blue": "Linterna de Bulbo de Talismanio Azul Claro", + "block.betterend.thallasium_bulb_lantern_light_gray": "Linterna de Bulbo de Talismanio Gris Claro", + "block.betterend.thallasium_bulb_lantern_lime": "Linterna de Bulbo de Talismanio Lima", + "block.betterend.thallasium_bulb_lantern_magenta": "Linterna de Bulbo de Talismanio Magenta", + "block.betterend.thallasium_bulb_lantern_orange": "Linterna de Bulbo de Talismanio Naranja", + "block.betterend.thallasium_bulb_lantern_pink": "Linterna de Bulbo de Talismanio Rosa", + "block.betterend.thallasium_bulb_lantern_purple": "Linterna de Bulbo de Talismanio Morada", + "block.betterend.thallasium_bulb_lantern_red": "Linterna de Bulbo de Talismanio Roja", + "block.betterend.thallasium_bulb_lantern_white": "Linterna de Bulbo de Talismanio Blanca", + "block.betterend.thallasium_bulb_lantern_yellow": "Linterna de Bulbo de Talismanio Amarilla", + + "block.betterend.bushy_grass": "Hierba Tupida", + + "block.betterend.brimstone": "Azufre", + "block.betterend.sulphuric_rock": "Roca Sulfúrica", + "block.betterend.sulphuric_rock_bricks": "Ladrillos de Roca Sulfúrica", + "block.betterend.sulphuric_rock_bricks_slab": "Losa de Ladrillos de Roca Sulfúrica", + "block.betterend.sulphuric_rock_bricks_stairs": "Escaleras de Ladrillos de Roca Sulfúrica", + "block.betterend.sulphuric_rock_bricks_wall": "Muro de Ladrillos de Roca Sulfúrica", + "block.betterend.sulphuric_rock_button": "Botón de Roca Sulfúrica", + "block.betterend.sulphuric_rock_lantern": "Linterna de Roca Sulfúrica", + "block.betterend.sulphuric_rock_pedestal": "Pedestal de Roca Sulfúrica", + "block.betterend.sulphuric_rock_pillar": "Pilar de Roca Sulfúrica", + "block.betterend.sulphuric_rock_plate": "Placa de Presión de Roca Sulfúrica", + "block.betterend.sulphuric_rock_polished": "Roca Sulfúrica Pulida", + "block.betterend.sulphuric_rock_slab": "Losa de Roca Sulfúrica", + "block.betterend.sulphuric_rock_stairs": "Escaleras de Roca Sulfúrica", + "block.betterend.sulphuric_rock_tiles": "Casillas de Roca Sulfúrica", + "block.betterend.sulphuric_rock_wall": "Muro de Roca Sulfúrica", + "block.betterend.sulphur_crystal": "Cristal de Sulfuro", + "item.betterend.crystalline_sulphur": "Sulfuro", + + "biome.betterend.sulphur_springs": "Manantiales de Sulfuro", + "block.betterend.hydralux_petal_block": "Bloque de Pétalos de Hidrálux", + "block.betterend.hydralux_petal_block_black": "Bloque de Pétalos Negro", + "block.betterend.hydralux_petal_block_blue": "Bloque de Pétalos Azul", + "block.betterend.hydralux_petal_block_brown": "Bloque de Pétalos Marrón", + "block.betterend.hydralux_petal_block_cyan": "Bloque de Pétalos Cyan", + "block.betterend.hydralux_petal_block_gray": "Bloque de Pétalos Gris", + "block.betterend.hydralux_petal_block_green": "Bloque de Pétalos Verde", + "block.betterend.hydralux_petal_block_light_blue": "Bloque de Pétalos Azul Claro", + "block.betterend.hydralux_petal_block_light_gray": "Bloque de Pétalos Gris Claro", + "block.betterend.hydralux_petal_block_lime": "Bloque de Pétalos Lima", + "block.betterend.hydralux_petal_block_magenta": "Bloque de Pétalos Magenta", + "block.betterend.hydralux_petal_block_orange": "Bloque de Pétalos Naranja", + "block.betterend.hydralux_petal_block_pink": "Bloque de Pétalos Rosa", + "block.betterend.hydralux_petal_block_purple": "Bloque de Pétalos Morado", + "block.betterend.hydralux_petal_block_red": "Bloque de Pétalos Rojo", + "block.betterend.hydralux_petal_block_white": "Bloque de Pétalos Blanco", + "block.betterend.hydralux_petal_block_yellow": "Bloque de Pétalos Amarillo", + "block.betterend.hydralux_sapling": "Sapling de Hidrálux", + "block.betterend.hydrothermal_vent": "Ventilación Hidrotermal", + "item.betterend.hydralux_petal": "Pétalo de Hidrálux", + "item.betterend.enchanted_petal": "Pétalo Encantado", + + "block.betterend.menger_sponge": "Esponja Menguer", + "block.betterend.menger_sponge_wet": "Esponja Menguer Mojadar", + "block.betterend.tube_worm": "Tubo de Gusano", + + "block.betterend.charnia_cyan": "Charnia Cyan", + "block.betterend.charnia_light_blue": "Charnia Azul Claro", + "block.betterend.charnia_orange": "Charnia Naranja", + "block.betterend.charnia_purple": "Charnia Morado", + "block.betterend.charnia_red": "Charnia Rojo", + + "entity.betterend.cubozoa": "Cubozoa", + "item.betterend.spawn_egg_cubozoa": "Huevo de Generación de Cubozoa", + + "item.betterend.gelatine": "Gelatina", + "item.betterend.sweet_berry_jelly": "Gelatina de Balla Dulce", + "item.betterend.shadow_berry_jelly": "Gelatina de Balla Sombría", + + "block.betterend.amber_moss": "Musgo de Ámbar", + "block.betterend.amber_moss_path": "Camino de Musgo de Ámbar", + "block.betterend.helix_tree_bark": "Corteza de Árbol Helix", + "block.betterend.helix_tree_barrel": "Barril de Árbol Helix", + "block.betterend.helix_tree_bookshelf": "Librería de Árbol Helix", + "block.betterend.helix_tree_button": "Botón de Árbol Helix", + "block.betterend.helix_tree_chest": "Cofre de Helix Tree Chest", + "block.betterend.helix_tree_crafting_table": "Mesa de Crafteo de Árbol Helix", + "block.betterend.helix_tree_door": "Puerta de Árbol Helix", + "block.betterend.helix_tree_fence": "Valla de Árbol Helix", + "block.betterend.helix_tree_gate": "Puerta de Valla de Árbol Helix", + "block.betterend.helix_tree_ladder": "Escalera de Árbol Helix", + "block.betterend.helix_tree_leaves": "Hojas de Árbol Helix", + "block.betterend.helix_tree_log": "Tronco de Árbol Helix", + "block.betterend.helix_tree_planks": "Tablones de Árbol Helix", + "block.betterend.helix_tree_plate": "Placa de Presión de Árbol Helix", + "block.betterend.helix_tree_sapling": "Sapling de Árbol Helix", + "block.betterend.helix_tree_sign": "Cartel de Árbol Helix", + "block.betterend.helix_tree_slab": "Losa de Árbol Helix", + "block.betterend.helix_tree_stairs": "Escaleras de Árbol Helix", + "block.betterend.helix_tree_stripped_bark": "Corteza Despojada de Árbol Helix", + "block.betterend.helix_tree_stripped_log": "Tronco Despojado de Árbol Helix", + "block.betterend.helix_tree_trapdoor": "Trampilla de Árbol Helix", + "block.betterend.lanceleaf": "Hoja Lanza", + "block.betterend.lanceleaf_seed": "Semilla de Hoja Lanza", + "block.betterend.hydralux": "Hidrálux", + "block.betterend.helix_tree_luminophor": "Luminóforo de Lanceleaf", + + "block.betterend.glowing_pillar_leaves": "Hojas de Pilar Brillante", + "block.betterend.glowing_pillar_luminophor": "Luminóforo de Pilar Brillante", + "block.betterend.glowing_pillar_roots": "Raíces de Pilar Brillante", + "block.betterend.glowing_pillar_seed": "Semilla de Pilar Brillante", + + "biome.betterend.ice_starfield": "Campo Estelar de Hielo", + + "block.betterend.ancient_emerald_ice": "Hielo de Esmeralda Antiguo", + "block.betterend.dense_emerald_ice": "Hielo de Esmeralda Denso", + "block.betterend.dense_snow": "Nieve Densa", + "block.betterend.emerald_ice": "Hielo de Esmeralda", + + "block.betterend.bulb_moss": "Musgo de Bulbo", + + "block.betterend.charnia_green": "Charnia Verde", + "block.betterend.vent_bubble_column": "Ventilación de Columna Burbuja", + "block.betterend.respawn_obelisk": "Obelisco de Reaparición", + "message.betterend.set_spawn": "\u00A7b\u00A7lTu punto de reaparición se ha configurado aquí", + "message.betterend.fail_spawn": "\u00A7c\u00A7lNecesitas sostener 6 Gemas de Ámbar para configurar tu punto de reaparición", + + "block.betterend.dragon_tree_composter": "Compostador de Árbol de Dragón", + "block.betterend.end_lotus_composter": "Compostador de Loto del End", + "block.betterend.helix_tree_composter": "Compostador de Árbol Helix", + "block.betterend.lacugrove_composter": "Compostador de Lacugrove", + "block.betterend.mossy_glowshroom_composter": "Compostador de Seta Luminosa Musgosa", + "block.betterend.pythadendron_composter": "Compostador de Fitadendrón", + "block.betterend.tenanea_composter": "Compostador de Tenanea", + + "biome.betterend.old_bulbis_gardens": "Jardín de Bulbis Viejos", + "block.betterend.ivis_moss": "Musgo Ivis", + "block.betterend.ivis_vine": "Vid Ivis", + "block.betterend.silk_moth_nest": "Nido de Polilla de Seda", + + "block.betterend.umbrella_tree_bark": "Corteza de Árbol Paraguas", + "block.betterend.umbrella_tree_barrel": "Barril de Árbol Paraguas", + "block.betterend.umbrella_tree_bookshelf": "Librería de Árbol Paraguas", + "block.betterend.umbrella_tree_button": "Botón de Árbol Paraguas", + "block.betterend.umbrella_tree_chest": "Cofre de Árbol Paraguas", + "block.betterend.umbrella_tree_composter": "Compostador de Árbol Paraguas", + "block.betterend.umbrella_tree_crafting_table": "Mesa de Crafteo de Árbol Paraguas", + "block.betterend.umbrella_tree_door": "Puerta de Árbol Paraguas", + "block.betterend.umbrella_tree_fence": "Valla de Árbol Paraguas", + "block.betterend.umbrella_tree_gate": "Puerta de Valla de Árbol Paraguas", + "block.betterend.umbrella_tree_ladder": "Escalera de Árbol Paraguas", + "block.betterend.umbrella_tree_log": "Tronco de Árbol Paraguas", + "block.betterend.umbrella_tree_planks": "Tablones de Árbol Paraguas", + "block.betterend.umbrella_tree_plate": "Placa de Presión de Árbol Paraguas", + "block.betterend.umbrella_tree_sign": "Cartel de Árbol Paraguas", + "block.betterend.umbrella_tree_slab": "Losa de Árbol Paraguas", + "block.betterend.umbrella_tree_stairs": "Escaleras de Árbol Paraguas", + "block.betterend.umbrella_tree_stripped_bark": "Corteza Despojada de Árbol Paraguas", + "block.betterend.umbrella_tree_stripped_log": "Tronco Despojado de Árbol Paraguas", + "block.betterend.umbrella_tree_trapdoor": "Trampilla de Árbol Paraguas", + "block.betterend.umbrella_tree_membrane": "Membrana de Árbol Paraguas", + + "biome.betterend.umbrella_jungle": "Jungla Paraguas", + "block.betterend.jungle_grass": "Hierba de Jungla", + "block.betterend.jungle_moss": "Musgo de Jungla", + "block.betterend.jungle_moss_path": "Camino de Musgo de Jungla", + "block.betterend.small_jellyshroom": "Seta Gelatinosa Pequeña", + "block.betterend.twisted_umbrella_moss": "Musgo de Paraguas Retorcido", + "block.betterend.twisted_umbrella_moss_tall": "Musgo de Paraguas Retorcido Alto", + "block.betterend.umbrella_tree_cluster": "Racimo de Árbol Paraguas", + "block.betterend.umbrella_tree_cluster_empty": "Racimo de Árbol Paraguas Vacío", + "block.betterend.jungle_vine": "Vid de Jungla", + "block.betterend.jungle_fern": "Helecho de Jungla", + + "block.betterend.jellyshroom_bark": "Corteza de Seta Gelatinosa", + "block.betterend.jellyshroom_barrel": "Barril de Seta Gelatinosa", + "block.betterend.jellyshroom_bookshelf": "Librería de Seta Gelatinosa", + "block.betterend.jellyshroom_button": "Botón de Seta Gelatinosa", + "block.betterend.jellyshroom_cap_purple": "Copa de Seta Gelatinosa", + "block.betterend.jellyshroom_chest": "Cofre de Seta Gelatinosa", + "block.betterend.jellyshroom_composter": "Compostador de Seta Gelatinosa", + "block.betterend.jellyshroom_crafting_table": "Mesa de Crafteo de Seta Gelatinosa", + "block.betterend.jellyshroom_door": "Puerta de Seta Gelatinosa", + "block.betterend.jellyshroom_fence": "Valla de Seta Gelatinosa", + "block.betterend.jellyshroom_gate": "Puerta de Valla de Seta Gelatinosa", + "block.betterend.jellyshroom_ladder": "Escalera de Seta Gelatinosa", + "block.betterend.jellyshroom_log": "Tronco de Seta Gelatinosa", + "block.betterend.jellyshroom_planks": "Tablones de Seta Gelatinosa", + "block.betterend.jellyshroom_plate": "Placa de Presión de Seta Gelatinosa", + "block.betterend.jellyshroom_sign": "Cartel de Seta Gelatinosa", + "block.betterend.jellyshroom_slab": "Losa de Seta Gelatinosa", + "block.betterend.jellyshroom_stairs": "Escaleras de Seta Gelatinosa", + "block.betterend.jellyshroom_stripped_bark": "Corteza Despojada de Seta Gelatinosa", + "block.betterend.jellyshroom_stripped_log": "Tronco Despojado de Seta Gelatinosa", + "block.betterend.jellyshroom_trapdoor": "Trampilla de Seta Gelatinosa", + + "biome.betterend.eterial_grove": "Arboleda Eterial", + "block.betterend.umbrella_tree_sapling": "Sapling de Árbol Sombrilla", + "item.betterend.umbrella_cluster_juice": "Zumo de Racimo de Paraguas", + "block.betterend.blossom_berry_seed": "Semilla de Balla Floreciente", + "item.betterend.blossom_berry": "Balla Floreciente", + + "biome.betterend.nightshade_redwoods": "Secuoyas Nocturnas", + "block.betterend.nightshade_moss": "Musgo Nocturno", + + "biome.betterend.glowing_grasslands": "Tierras de Hierba Brillante", + "block.betterend.blooming_cooksonia": "Cooksonia Floreciente", + "block.betterend.fracturn": "Fracturno", + "block.betterend.lumecorn": "Lumecornia", + "block.betterend.salteago": "Salteago", + "block.betterend.vaiolush_fern": "Helecho Exhuberante", + "entity.betterend.silk_moth": "Polilla de eda", + "item.betterend.silk_fiber": "Fibra de Seda", + "item.betterend.spawn_egg_silk_moth": "Huevo de Generación de Polilla de Seda", + + "block.betterend.thallasium_ore": "Mena de Talismanio", + "item.betterend.thallasium_axe": "Hacha de Talismanio", + "item.betterend.thallasium_hoe": "Azada de Talismanio", + "item.betterend.thallasium_ingot": "Lingote de Talismanio", + "item.betterend.thallasium_pickaxe": "Pico de Talismanio", + "item.betterend.thallasium_shovel": "Pala de Talismanio", + "item.betterend.thallasium_sword": "Espada de Talismanio", + "block.betterend.thallasium_block": "Bloque de Talismanio", + + "block.betterend.thallasium_bars": "Barras de Talismanio", + "block.betterend.thallasium_door": "Puerta de Talismanio", + "block.betterend.thallasium_plate": "Placa de Presión de Talismanio", + "block.betterend.thallasium_tile": "Casilla de Talismanio", + "block.betterend.thallasium_trapdoor": "Trampilla de Talismanio", + + "block.betterend.lumecorn_seed": "Semilla de Lumecornia", + "item.betterend.lumecorn_rod": "Vara de Lumecornia", + "block.betterend.thallasium_chandelier": "Candelabro de Talismanio", + + "block.betterend.thallasium_anvil": "Yunque de Talismanio", + "block.betterend.thallasium_chain": "Cadena de Talismanio", + "block.betterend.thallasium_slab": "Losa de Talismanio", + "block.betterend.thallasium_stairs": "Escaleras de Talismanio", + + "block.betterend.gold_chandelier": "Candelabro de Oro", + "block.betterend.iron_chandelier": "Candelabro de Hierro", + "item.betterend.thallasium_nugget": "Pepita de Talismanio", + + "block.betterend.terminite_anvil": "Yunque de Terminita", + "block.betterend.terminite_bars": "Barras de Terminita", + + "block.betterend.terminite_bulb_lantern": "Linterna de Bulbo de Terminita", + "block.betterend.terminite_bulb_lantern_black": "Linterna de Bulbo de Terminita Negra", + "block.betterend.terminite_bulb_lantern_blue": "Linterna de Bulbo de Terminita Azul", + "block.betterend.terminite_bulb_lantern_brown": "Linterna de Bulbo de Terminita Marrón", + "block.betterend.terminite_bulb_lantern_cyan": "Linterna de Bulbo de Terminita Cyan", + "block.betterend.terminite_bulb_lantern_gray": "Linterna de Bulbo de Terminita Gris", + "block.betterend.terminite_bulb_lantern_green": "Linterna de Bulbo de Terminita Verde", + "block.betterend.terminite_bulb_lantern_light_blue": "Linterna de Bulbo de Terminita Azul Claro", + "block.betterend.terminite_bulb_lantern_light_gray": "Linterna de Bulbo de Terminita Gris Claro", + "block.betterend.terminite_bulb_lantern_lime": "Linterna de Bulbo de Terminita Lima", + "block.betterend.terminite_bulb_lantern_magenta": "Linterna de Bulbo de Terminita Magenta", + "block.betterend.terminite_bulb_lantern_orange": "Linterna de Bulbo de Terminita Naranja", + "block.betterend.terminite_bulb_lantern_pink": "Linterna de Bulbo de Terminita Rosa", + "block.betterend.terminite_bulb_lantern_purple": "Linterna de Bulbo de Terminita Morada", + "block.betterend.terminite_bulb_lantern_red": "Linterna de Bulbo de Terminita Roja", + "block.betterend.terminite_bulb_lantern_white": "Linterna de Bulbo de Terminita Blanca", + "block.betterend.terminite_bulb_lantern_yellow": "Linterna de Bulbo de Terminita Amarilla", + + "block.betterend.terminite_chain": "adena de Terminita", + "block.betterend.terminite_chandelier": "Candelabro de Terminita", + "block.betterend.terminite_door": "Puerta de Terminita", + "block.betterend.terminite_plate": "Placa de Presión de Terminita", + "block.betterend.terminite_slab": "Losa de Terminita", + "block.betterend.terminite_stairs": "Escaleras de Terminita", + "block.betterend.terminite_tile": "Casilla de Terminita", + "block.betterend.terminite_trapdoor": "Trampilla de Terminita", + "item.betterend.terminite_nugget": "Pepita de Terminita", + "item.betterend.thallasium_boots": "Botas de Talismanio", + "item.betterend.thallasium_chestplate": "Pechera de Talismanio", + "item.betterend.thallasium_hammer": "Martillo de Talismanio", + "item.betterend.thallasium_helmet": "Casco de Talismanio", + "item.betterend.thallasium_leggings": "Grebas de Talismanio", + "block.betterend.missing_tile": "Casilla Faltante", + "block.betterend.charcoal_block": "Bloque de Carbón Vegetal", + "block.betterend.end_stone_furnace": "Horno de Piedra del End", + "block.betterend.flavolite_furnace": "Horno de Flavolita", + "block.betterend.sulphuric_rock_furnace": "Horno de Roca Sulfúrica", + "block.betterend.violecite_furnace": "Horno de Violecita", + + "item.betterend.terminite_axe_head": "Cabeza de Hacha de Terminita", + "item.betterend.terminite_hoe_head": "Cabeza de Azada de Terminita", + "item.betterend.terminite_pickaxe_head": "Cabeza de Pico de Terminita", + "item.betterend.terminite_shovel_head": "Cabeza de Pala de Terminita", + "item.betterend.terminite_sword_blade": "Hoja de Espada de Terminita", + "item.betterend.terminite_sword_handle": "Mango de Espada de Terminita", + "item.betterend.thallasium_axe_head": "Cabeza de Hacha de Talismanio", + "item.betterend.thallasium_hoe_head": "Cabeza de Azada de Talismanio", + "item.betterend.thallasium_pickaxe_head": "Cabeza de Pico de Talismanio", + "item.betterend.thallasium_shovel_head": "Cabeza de Pala de Talismanio", + "item.betterend.thallasium_sword_blade": "Hoja de Espada de Talismanio", + "item.betterend.thallasium_sword_handle": "Mango de Espada de Talismanio", + "block.betterend.aeternium_anvil": "Yunque de Aeternio", + + "biome.betterend.dragon_graveyards": "Cementerios de Dragones", + "biome.betterend.dry_shrubland": "Matorral Seco", + "block.betterend.aeridium": "Aeridio", + "block.betterend.amaranita_cap": "Copa de Amaranita", + "block.betterend.amaranita_fur": "Pelo de Amaranita", + "block.betterend.amaranita_hymenophore": "Himenóforo de Amarinita", + "block.betterend.amaranita_hyphae": "Hifas de Amaranita", + "block.betterend.amaranita_lantern": "Linterna de Amaranita", + "block.betterend.amaranita_stem": "Tallo de Amaranita", + "block.betterend.clawfern": "Helecho de Garra", + "block.betterend.globulagus": "Globulagus", + "block.betterend.lamellarium": "Lamelario", + "block.betterend.large_amaranita_mushroom": "Seta de Amaranita Grande", + "block.betterend.lutebus": "Lutebús", + "block.betterend.mossy_bone": "Hueso Musgoso", + "block.betterend.mossy_obsidian": "Obsidiana Musgosa", + "block.betterend.orango": "Orango", + "block.betterend.rutiscus": "Rútiscus", + "block.betterend.rutiscus_path": "Camino de Rústicus", + "block.betterend.sangnum": "Sángnum", + "block.betterend.sangnum_path": "Camino de Sángnum", + "block.betterend.small_amaranita_mushroom": "Seta de Amarita Pequeña", + + "block.betterend.amber_root_seed": "Semilla de Raíz de Ámbar", + "block.betterend.azure_jadestone": "Piedra Jade Azur", + "block.betterend.azure_jadestone_bricks": "Ladrillos de Piedra Jade Azur", + "block.betterend.azure_jadestone_bricks_slab": "Losa de Ladrillos de Piedra Jade Azur", + "block.betterend.azure_jadestone_bricks_stairs": "Escaleras de Ladrillos de Piedra Jade Azur", + "block.betterend.azure_jadestone_bricks_wall": "Muro de Ladrillos de Piedra Jade Azur", + "block.betterend.azure_jadestone_button": "Botón de Piedra Jade Azur", + "block.betterend.azure_jadestone_furnace": "Horno de Piedra Jade Azur", + "block.betterend.azure_jadestone_lantern": "Linterna de Piedra Jade Azur", + "block.betterend.azure_jadestone_pedestal": "Pedestal de Piedra Jade Azur", + "block.betterend.azure_jadestone_pillar": "Pilar de Piedra Jade Azur", + "block.betterend.azure_jadestone_plate": "Placa de Presión de Piedra Jade Azur", + "block.betterend.azure_jadestone_polished": "Piedra Jade Azur Pulida", + "block.betterend.azure_jadestone_slab": "Losa de Piedra Jade Azur", + "block.betterend.azure_jadestone_stairs": "Escaleras de Piedra Jade Azur", + "block.betterend.azure_jadestone_tiles": "Casillas de Piedra Jade Azur", + "block.betterend.azure_jadestone_wall": "Muro de Piedra Jade Azur", + "block.betterend.chorus_mushroom_seed": "Semilla de Seta Coral", + "block.betterend.end_stone_stalactite": "Estalactita de Piedra del End", + "block.betterend.end_stone_stalactite_cavemoss": "Estalactita de Piedrad el End con Musgo de Cueva", + "block.betterend.pearlberry_seed": "Semilla de Balla Perla", + "block.betterend.rubinea": "Rubinea", + "block.betterend.sandy_jadestone": "Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_bricks": "Ladrillos de Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_bricks_slab": "Losa de Ladrillos de Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_bricks_stairs": "Escaleras de Ladrillos de Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_bricks_wall": "Muro de Ladrillos de Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_button": "Botón de Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_furnace": "Horno de Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_lantern": "Linterna de Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_pedestal": "Pedestal de Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_pillar": "Pilar de Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_plate": "Placa de Presión de Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_polished": "Piedra Jade Arenosa Pulida", + "block.betterend.sandy_jadestone_slab": "Losa de Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_stairs": "Escaleras de Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_tiles": "Casillas de Piedra Jade Arenosa", + "block.betterend.sandy_jadestone_wall": "Muro de Piedra Jade Arenosa", + "block.betterend.smaragdant_crystal": "Cristal de Smaragdant", + "block.betterend.smaragdant_crystal_shard": "Fragemnto de Cristal de Smaragdant", + "block.betterend.virid_jadestone": "Piedra Jade Virida", + "block.betterend.virid_jadestone_bricks": "Ladrillos de Piedra Jade Virida", + "block.betterend.virid_jadestone_bricks_slab": "Losa de Ladrillos de Piedra Jade Virida", + "block.betterend.virid_jadestone_bricks_stairs": "Escaleras de Ladrillos de Piedra Jade Virida", + "block.betterend.virid_jadestone_bricks_wall": "Muro de Ladrillos de Piedra Jade Virida", + "block.betterend.virid_jadestone_button": "Botón de Piedra Jade Virida", + "block.betterend.virid_jadestone_furnace": "Horno de Piedra Jade Virida", + "block.betterend.virid_jadestone_lantern": "Linterna de Piedra Jade Virida", + "block.betterend.virid_jadestone_pedestal": "Pedestal de Piedra Jade Virida", + "block.betterend.virid_jadestone_pillar": "Pilar de Piedra Jade Virida", + "block.betterend.virid_jadestone_plate": "Placa de Presión de Piedra Jade Virida", + "block.betterend.virid_jadestone_polished": "Piedra Jade Virida Pulida", + "block.betterend.virid_jadestone_slab": "Losa de Piedra Jade Virida", + "block.betterend.virid_jadestone_stairs": "Escaleras de Piedra Jade Virida", + "block.betterend.virid_jadestone_tiles": "Casillas de Piedra Jade Virida", + "block.betterend.virid_jadestone_wall": "Muro de Piedra Jade Virida", + "item.betterend.amber_root_raw": "Raíz de Ámbar Cruda", + "item.betterend.chorus_mushroom_cooked": "Seta Coral Cocinada", + "item.betterend.chorus_mushroom_raw": "Seta Coral Cruda", + + "biome.betterend.empty_aurora_cave": "Cuava Aurora Vacía", + "biome.betterend.empty_end_cave": "Cueva del End Vacía", + "biome.betterend.empty_smaragdant_cave": "Cueva de Smagrdant Vacía", + "biome.betterend.lush_aurora_cave": "Cueva Aurora Exhuberante", + "biome.betterend.lush_smaragdant_cave": "Cueva Smagrdant Exhuberante", + + "block.betterend.dragon_bone_block": "Bloque de Hueso de Dragó", + "block.betterend.dragon_bone_slab": "Losa de Hueso de Dragón", + "block.betterend.dragon_bone_stairs": "Escaleras de Hueso de Dragón", + "block.betterend.mossy_dragon_bone": "Hueso de Dragón Musgoso", + + "biome.betterend.lantern_woods": "Bosque Linterna", + "block.betterend.filalux": "Filálux", + "block.betterend.filalux_lantern": "Linterna de Filálux", + "block.betterend.filalux_wings": "Alas de Filálux", + "block.betterend.lucernia_bark": "Corteza de Lucernia", + "block.betterend.lucernia_barrel": "Barril de Lucernia", + "block.betterend.lucernia_bookshelf": "Librería de Lucernia", + "block.betterend.lucernia_button": "Botón de Lucernia", + "block.betterend.lucernia_chest": "Cofre de Lucernia", + "block.betterend.lucernia_composter": "Compostador de Lucernia", + "block.betterend.lucernia_crafting_table": "Mesa de Crafteo e Lucernia", + "block.betterend.lucernia_door": "Puerta de Lucernia", + "block.betterend.lucernia_fence": "Valla de Lucernia", + "block.betterend.lucernia_gate": "Puerta de Valla de Lucernia", + "block.betterend.lucernia_ladder": "Escalera de Lucernia", + "block.betterend.lucernia_leaves": "Hojas de Lucernia", + "block.betterend.lucernia_log": "Tronco de Lucernia", + "block.betterend.lucernia_outer_leaves": "Hojas Exteriores de Lucernia", + "block.betterend.lucernia_planks": "Tablones de Lucernia", + "block.betterend.lucernia_plate": "Placa de Presión de Lucernia", + "block.betterend.lucernia_sapling": "Sapling de Lucernia", + "block.betterend.lucernia_sign": "Cartel de Lucernia", + "block.betterend.lucernia_slab": "Losa de Lucernia", + "block.betterend.lucernia_stairs": "Escaleras de Lucernia", + "block.betterend.lucernia_stripped_bark": "Corteza Despojada de Lucernia", + "block.betterend.lucernia_stripped_log": "Tronco Despojado de Lucernia", + "block.betterend.lucernia_trapdoor": "Trampilla de Lucernia", + + "block.betterend.aurant_polypore": "Políporo Aurante", + "block.betterend.bolux_mushroom": "Seta Bólux", + "block.betterend.flamaea": "Flamaea", + "block.betterend.pond_anemone": "Anémona de Pantano", + "block.betterend.ruscus": "Ruscus", + "item.betterend.bolux_mushroom_cooked": "Seta Bólux Cocinada", + + "block.betterend.silk_moth_hive": "Colmena de Polilla de Seda", + "item.betterend.silk_moth_matrix": "Matrix de Polilla de Seda", + + "biome.betterend.neon_oasis": "Oasis Neón", + "block.betterend.cave_pumpkin": "Calabaza de Cueva", + "block.betterend.cave_pumpkin_seed": "Semilla de Calabaza de Cueva", + "block.betterend.magnula": "Magnula", + "block.betterend.neon_cactus": "Cactus Neón", + "item.betterend.cave_pumpkin_pie": "Tarta de Calabaza de Cueva", + + "item.betterend.music_disc_strange_and_alien": "§bDisco Musical§r", + "item.betterend.music_disc_strange_and_alien.desc": "§5Firel§r - §fStrange And Alien§r", + "item.betterend.music_disc_grasping_at_stars": "§bDisco Musical§r", + "item.betterend.music_disc_grasping_at_stars.desc": "§5Firel§r - §fGrasping At Stars§r", + "item.betterend.music_disc_endseeker": "§bDisco Musical§r", + "item.betterend.music_disc_endseeker.desc": "§5Firel§r - §fEndseeker§r", + "item.betterend.music_disc_eo_dracona": "§bDisco Musical§r", + "item.betterend.music_disc_eo_dracona.desc": "§5Firel§r - §fEo Dracona§r", + + "block.betterend.hydralux_petal_block_amber": "Bloque de Pétalo Ámbar", + "block.betterend.hydralux_petal_block_beige": "Bloque de Pétalo Beige", + "block.betterend.hydralux_petal_block_cream": "Bloque de Pétalo Crema", + "block.betterend.hydralux_petal_block_dark_green": "Bloque de Pétalo Verde Oscuro", + "block.betterend.hydralux_petal_block_forest_green": "Bloque de Pétalo Verde Bosque", + "block.betterend.hydralux_petal_block_hot_pink": "Bloque de Pétalo Rosa Fuerte", + "block.betterend.hydralux_petal_block_indigo": "Bloque de Pétalo Índigo", + "block.betterend.hydralux_petal_block_maroon": "Bloque de Pétalo Granate", + "block.betterend.hydralux_petal_block_navy": "Bloque de Pétalo Azul Marino", + "block.betterend.hydralux_petal_block_olive": "Bloque de Pétalo Oliva", + "block.betterend.hydralux_petal_block_pale_green": "Bloque de Pétalo Verde Pálido", + "block.betterend.hydralux_petal_block_pale_pink": "Bloque de Pétalo Rosa Pálido", + "block.betterend.hydralux_petal_block_pale_yellow": "Bloque de Pétalo Amarillo Pálido", + "block.betterend.hydralux_petal_block_sky_blue": "Bloque de Pétalo Azul Cielo", + "block.betterend.hydralux_petal_block_slate_gray": "Bloque de Pétalo Gris Pizarra", + "block.betterend.hydralux_petal_block_violet": "Bloque de Pétalo Violeta", + + "block.betterend.smaragdant_crystal_bricks": "Ladrillos de Smaragdant", + "block.betterend.smaragdant_crystal_bricks_slab": "Losa de Ladrillos de Smaragdant", + "block.betterend.smaragdant_crystal_bricks_stairs": "Escaleras de Ladrillos de Smaragdant", + "block.betterend.smaragdant_crystal_bricks_wall": "Muro de Ladrillos de Smaragdant", + "block.betterend.smaragdant_crystal_pedestal": "Pedestal de Smaragdant", + "block.betterend.smaragdant_crystal_pillar": "Pilar de Smaragdant", + "block.betterend.smaragdant_crystal_polished": "Smaragdant Pulido", + "block.betterend.smaragdant_crystal_slab": "Losa de Smaragdant", + "block.betterend.smaragdant_crystal_stairs": "Escaleras de Smaragdant", + "block.betterend.smaragdant_crystal_tiles": "Casillas de Smaragdant", + "block.betterend.smaragdant_crystal_wall": "Muro de Smaragdant", + "message.betterend.anvil_damage": "§cDaño", + + "block.betterend.neon_cactus_block": "Bloque de Cactus Neón", + "block.betterend.neon_cactus_slab": "Losa de Cactus Neón", + "block.betterend.neon_cactus_stairs": "Escaleras de Cactus Neón", + "biome.betterend.jade_cave": "Cueva de Jade", + "item.betterend.blossom_berry_jelly": "Gelatina de Balla Floreciente", + "item.betterend.aeternium_forged_plate": "Placa de Aeternio Forjada", + "item.betterend.terminite_forged_plate": "Placa de Terminita Forjada", + "item.betterend.thallasium_forged_plate": "Placa de Talismanio Forjada", + + "attribute.name.generic.blindness_resistance": "Resistencia a la Ceguera", + + "tooltip.armor.crystalite_set": "Dar bonus: Regeneración I", + "tooltip.armor.crystalite_chest": "Efecto: Velocidad de Rapidez I", + "tooltip.armor.crystalite_boots": "Efecto: Velocidad I" +} diff --git a/src/main/resources/assets/betterend/lang/ko_kr.json b/src/main/resources/assets/betterend/lang/ko_kr.json index dcdecc42..c7c5e956 100644 --- a/src/main/resources/assets/betterend/lang/ko_kr.json +++ b/src/main/resources/assets/betterend/lang/ko_kr.json @@ -1,9 +1,9 @@ { - "itemGroup.betterend.end_items": "Better End: 아이템", - "itemGroup.betterend.end_blocks": "Better End: 블록", + "itemGroup.betterend.end_items": "더 좋은 엔드: 아이템", + "itemGroup.betterend.end_blocks": "더 좋은 엔드: 블록", "item.betterend.guidebook": "엔드 무작정 따라하기", - "book.betterend.landing": "엔드의 극한환경에서 살아남기 위한 짤막한 가이드", + "book.betterend.landing": "엔드의 극한 환경에서 살아남기 위한 짤막한 가이드", "book.betterend.subtitle": "엔드에서 살아남기", "category.rei.damage.amount&dmg": "도구 손상: %s", @@ -28,7 +28,7 @@ "block.betterend.end_mycelium_path": "엔드 균사체 길", "block.betterend.end_moss_path": "엔드 이끼 길", - "block.betterend.ender_ore": "엔더 원석", + "block.betterend.ender_ore": "엔더 광석", "block.betterend.terminite_block": "터미나이트 블록", "block.betterend.aeternium_block": "에테르늄 블록", "block.betterend.ender_block": "엔더 블록", @@ -40,7 +40,7 @@ "item.betterend.aeternium_ingot": "에테르늄 주괴", "item.betterend.terminite_helmet": "터미나이트 투구", "item.betterend.terminite_chestplate": "터미나이트 흉갑", - "item.betterend.terminite_leggings": "터미나이트 각반", + "item.betterend.terminite_leggings": "터미나이트 레깅스", "item.betterend.terminite_boots": "터미나이트 부츠", "item.betterend.terminite_shovel": "터미나이트 삽", "item.betterend.terminite_sword": "터미나이트 검", @@ -50,7 +50,7 @@ "item.betterend.terminite_hammer": "터미나이트 단조 망치", "item.betterend.aeternium_helmet": "에테르늄 투구", "item.betterend.aeternium_chestplate": "에테르늄 흉갑", - "item.betterend.aeternium_leggings": "에테르늄 각반", + "item.betterend.aeternium_leggings": "에테르늄 레깅스", "item.betterend.aeternium_boots": "에테르늄 부츠", "item.betterend.aeternium_shovel": "에테르늄 삽", "item.betterend.aeternium_sword": "에테르늄 검", @@ -65,7 +65,7 @@ "item.betterend.crystalite_boots": "크리스탈라이트 부츠", "item.betterend.crystalite_chestplate": "크리스탈라이트 흉갑", "item.betterend.crystalite_helmet": "크리스탈라이트 투구", - "item.betterend.crystalite_leggings": "크리스탈라이트 각반", + "item.betterend.crystalite_leggings": "크리스탈라이트 레깅스", "item.betterend.aeternium_axe_head": "에테르늄 도끼 머리", "item.betterend.aeternium_hammer_head": "에테르늄 망치 머리", "item.betterend.aeternium_hoe_head": "에테르늄 괭이 머리", @@ -76,6 +76,8 @@ "item.betterend.leather_stripe": "가죽끈", "item.betterend.leather_wrapped_stick": "가죽을 감은 막대기", "item.betterend.elytra_armored": "장갑 겉날개", + "item.betterend.elytra_crystalite": "크리스탈라이트 겉날개", + "item.betterend.enchanted_membrane": "마법이 부여된 막", "effect.betterend.end_veil": "엔드 베일", "enchantment.betterend.end_veil": "엔드 베일", @@ -123,27 +125,27 @@ "block.betterend.dense_vine": "조밀한 덩굴", "block.betterend.bubble_coral": "거품 산호", "block.betterend.aurora_crystal": "오로라 수정", - "item.betterend.crystal_shards": "수정 조각", + "item.betterend.crystal_shards": "오로라 수정 조각", - "block.betterend.pythadendron_sapling": "피타덴드론 묘목", - "block.betterend.pythadendron_bark": "피타덴드론", - "block.betterend.pythadendron_barrel": "피타덴드론 통", - "block.betterend.pythadendron_button": "피타덴드론 버튼", - "block.betterend.pythadendron_chest": "피타덴드론 상자", - "block.betterend.pythadendron_crafting_table": "피타덴드론 제작대", - "block.betterend.pythadendron_door": "피타덴드론 문", - "block.betterend.pythadendron_fence": "피타덴드론 울타리", - "block.betterend.pythadendron_gate": "피타덴드론 울타리 문", - "block.betterend.pythadendron_ladder": "피타덴드론 사다리", - "block.betterend.pythadendron_log": "피타덴드론 원목", - "block.betterend.pythadendron_planks": "피타덴드론 판자", - "block.betterend.pythadendron_plate": "피타덴드론 압력판", - "block.betterend.pythadendron_sign": "피타덴드론 표지판", - "block.betterend.pythadendron_slab": "피타덴드론 반 블록", - "block.betterend.pythadendron_stairs": "피타덴드론 계단", - "block.betterend.pythadendron_stripped_bark": "껍질 벗긴 피타덴드론", - "block.betterend.pythadendron_stripped_log": "껍질 벗긴 피타덴드론 원목", - "block.betterend.pythadendron_trapdoor": "피타덴드론 다락문", + "block.betterend.pythadendron_sapling": "피타덴드론나무 묘목", + "block.betterend.pythadendron_bark": "피타덴드론나무", + "block.betterend.pythadendron_barrel": "피타덴드론나무 통", + "block.betterend.pythadendron_button": "피타덴드론나무 버튼", + "block.betterend.pythadendron_chest": "피타덴드론나무 상자", + "block.betterend.pythadendron_crafting_table": "피타덴드론나무 제작대", + "block.betterend.pythadendron_door": "피타덴드론나무 문", + "block.betterend.pythadendron_fence": "피타덴드론나무 울타리", + "block.betterend.pythadendron_gate": "피타덴드론나무 울타리 문", + "block.betterend.pythadendron_ladder": "피타덴드론나무 사다리", + "block.betterend.pythadendron_log": "피타덴드론나무 원목", + "block.betterend.pythadendron_planks": "피타덴드론나무 판자", + "block.betterend.pythadendron_plate": "피타덴드론나무 압력판", + "block.betterend.pythadendron_sign": "피타덴드론나무 표지판", + "block.betterend.pythadendron_slab": "피타덴드론나무 반 블록", + "block.betterend.pythadendron_stairs": "피타덴드론나무 계단", + "block.betterend.pythadendron_stripped_bark": "껍질 벗긴 피타덴드론나무", + "block.betterend.pythadendron_stripped_log": "껍질 벗긴 피타덴드론나무 원목", + "block.betterend.pythadendron_trapdoor": "피타덴드론나무 다락문", "block.betterend.chorus_nylium": "후렴 네사체", "block.betterend.chorus_nylium_path": "후렴 네사체 길", @@ -222,7 +224,7 @@ "block.betterend.cave_moss_path": "동굴 이끼 길", "block.betterend.crystal_moss": "수정 이끼", "block.betterend.crystal_moss_path": "수정 이끼 길", - "block.betterend.pythadendron_leaves": "피타덴드론 잎", + "block.betterend.pythadendron_leaves": "피타덴드론나무 잎", "item.betterend.spawn_egg_end_fish": "엔드 물고기 생성 알", "block.betterend.crystal_grass": "수정 잔디", @@ -232,65 +234,65 @@ "block.betterend.flavolite_runed_eternal": "영원한 룬을 새긴 플라보라이트", "item.betterend.eternal_crystal": "영원한 수정", - "block.betterend.lacugrove_bark": "라쿠그로브", - "block.betterend.lacugrove_barrel": "라쿠그로브 통", - "block.betterend.lacugrove_button": "라쿠그로브 버튼", - "block.betterend.lacugrove_chest": "라쿠그로브 상자", - "block.betterend.lacugrove_crafting_table": "라쿠그로브 제작대", - "block.betterend.lacugrove_door": "라쿠그로브 문", - "block.betterend.lacugrove_fence": "라쿠그로브 울타리", - "block.betterend.lacugrove_gate": "라쿠그로브 울타리 문", - "block.betterend.lacugrove_ladder": "라쿠그로브 사다리", - "block.betterend.lacugrove_log": "라쿠그로브 원목", - "block.betterend.lacugrove_planks": "라쿠그로브 판자", - "block.betterend.lacugrove_plate": "라쿠그로브 압력판", - "block.betterend.lacugrove_sign": "라쿠그로브 표지판", - "block.betterend.lacugrove_slab": "라쿠그로브 반 블록", - "block.betterend.lacugrove_stairs": "라쿠그로브 계단", - "block.betterend.lacugrove_stripped_bark": "껍질 벗긴 라쿠그로브", - "block.betterend.lacugrove_stripped_log": "껍질 벗긴 라쿠그로브 원목", - "block.betterend.lacugrove_trapdoor": "라쿠그로브 다락문", + "block.betterend.lacugrove_bark": "라쿠그로브나무", + "block.betterend.lacugrove_barrel": "라쿠그로브나무 통", + "block.betterend.lacugrove_button": "라쿠그로브나무 버튼", + "block.betterend.lacugrove_chest": "라쿠그로브나무 상자", + "block.betterend.lacugrove_crafting_table": "라쿠그로브나무 제작대", + "block.betterend.lacugrove_door": "라쿠그로브나무 문", + "block.betterend.lacugrove_fence": "라쿠그로브나무 울타리", + "block.betterend.lacugrove_gate": "라쿠그로브나무 울타리 문", + "block.betterend.lacugrove_ladder": "라쿠그로브나무 사다리", + "block.betterend.lacugrove_log": "라쿠그로브나무 원목", + "block.betterend.lacugrove_planks": "라쿠그로브나무 판자", + "block.betterend.lacugrove_plate": "라쿠그로브나무 압력판", + "block.betterend.lacugrove_sign": "라쿠그로브나무 표지판", + "block.betterend.lacugrove_slab": "라쿠그로브나무 반 블록", + "block.betterend.lacugrove_stairs": "라쿠그로브나무 계단", + "block.betterend.lacugrove_stripped_bark": "껍질 벗긴 라쿠그로브나무", + "block.betterend.lacugrove_stripped_log": "껍질 벗긴 라쿠그로브나무 원목", + "block.betterend.lacugrove_trapdoor": "라쿠그로브나무 다락문", - "block.betterend.lacugrove_leaves": "라쿠그로브 잎", - "block.betterend.lacugrove_sapling": "라쿠그로브 묘목", + "block.betterend.lacugrove_leaves": "라쿠그로브나무 잎", + "block.betterend.lacugrove_sapling": "라쿠그로브나무 묘목", "biome.betterend.megalake_grove": "거대한 호수 숲", "biome.betterend.painted_mountains": "채색 산맥", - "block.betterend.dragon_tree_bark": "용혈수", - "block.betterend.dragon_tree_barrel": "용혈수 통", - "block.betterend.dragon_tree_button": "용혈수 버튼", - "block.betterend.dragon_tree_chest": "용혈수 상자", - "block.betterend.dragon_tree_crafting_table": "용혈수 제작대", - "block.betterend.dragon_tree_door": "용혈수 문", - "block.betterend.dragon_tree_fence": "용혈수 울타리", - "block.betterend.dragon_tree_gate": "용혈수 울타리 문", - "block.betterend.dragon_tree_ladder": "용혈수 사다리", - "block.betterend.dragon_tree_log": "용혈수 원목", - "block.betterend.dragon_tree_planks": "용혈수 판자", - "block.betterend.dragon_tree_plate": "용혈수 압력판", - "block.betterend.dragon_tree_sign": "용혈수 표지판", - "block.betterend.dragon_tree_slab": "용혈수 반 블록", - "block.betterend.dragon_tree_stairs": "용혈수 계단", - "block.betterend.dragon_tree_stripped_bark": "껍질 벗긴 용혈수", - "block.betterend.dragon_tree_stripped_log": "껍질 벗긴 용혈수 원목", - "block.betterend.dragon_tree_trapdoor": "용혈수 다락문", + "block.betterend.dragon_tree_bark": "용혈수나무", + "block.betterend.dragon_tree_barrel": "용혈수나무 통", + "block.betterend.dragon_tree_button": "용혈수나무 버튼", + "block.betterend.dragon_tree_chest": "용혈수나무 상자", + "block.betterend.dragon_tree_crafting_table": "용혈수나무 제작대", + "block.betterend.dragon_tree_door": "용혈수나무 문", + "block.betterend.dragon_tree_fence": "용혈수나무 울타리", + "block.betterend.dragon_tree_gate": "용혈수나무 울타리 문", + "block.betterend.dragon_tree_ladder": "용혈수나무 사다리", + "block.betterend.dragon_tree_log": "용혈수나무 원목", + "block.betterend.dragon_tree_planks": "용혈수나무 판자", + "block.betterend.dragon_tree_plate": "용혈수나무 압력판", + "block.betterend.dragon_tree_sign": "용혈수나무 표지판", + "block.betterend.dragon_tree_slab": "용혈수나무 반 블록", + "block.betterend.dragon_tree_stairs": "용혈수나무 계단", + "block.betterend.dragon_tree_stripped_bark": "껍질 벗긴 용혈수나무", + "block.betterend.dragon_tree_stripped_log": "껍질 벗긴 용혈수나무 원목", + "block.betterend.dragon_tree_trapdoor": "용혈수나무 다락문", "biome.betterend.shadow_forest": "그림자 숲", - "block.betterend.dragon_tree_leaves": "용혈수 잎", - "block.betterend.dragon_tree_sapling": "용혈수 묘목", + "block.betterend.dragon_tree_leaves": "용혈수나무 잎", + "block.betterend.dragon_tree_sapling": "용혈수나무 묘목", "block.betterend.shadow_grass": "그림자 잔디", "block.betterend.shadow_grass_path": "그림자 잔디 길", "block.betterend.shadow_plant": "그림자 식물", - "block.betterend.dragon_tree_bookshelf": "용혈수 책장", + "block.betterend.dragon_tree_bookshelf": "용혈수나무 책장", "block.betterend.end_lotus_bookshelf": "엔드 연꽃 책장", - "block.betterend.lacugrove_bookshelf": "라쿠그로브 책장", + "block.betterend.lacugrove_bookshelf": "라쿠그로브나무 책장", "block.betterend.mossy_glowshroom_bookshelf": "이끼 낀 발광버섯 책장", - "block.betterend.pythadendron_bookshelf": "피타덴드론 책장", + "block.betterend.pythadendron_bookshelf": "피타덴드론나무 책장", - "block.betterend.murkweed": "컴컴한풀", - "block.betterend.needlegrass": "털수염풀", + "block.betterend.murkweed": "컴컴한 풀", + "block.betterend.needlegrass": "털수염 풀", "block.betterend.twisted_vine": "뒤틀린 덩굴", "block.betterend.shadow_berry": "그림자 열매 씨앗", @@ -325,34 +327,34 @@ "biome.betterend.blossoming_spires": "만발한 첨탑", "block.betterend.amber_grass": "호박 잔디", "block.betterend.amber_grass_path": "호박 잔디 길", - "block.betterend.tenanea_bark": "테나네아", - "block.betterend.tenanea_barrel": "테나네아 통", - "block.betterend.tenanea_bookshelf": "테나네아 책장", - "block.betterend.tenanea_button": "테나네아 버튼", - "block.betterend.tenanea_chest": "테나네아 상자", - "block.betterend.tenanea_crafting_table": "테나네아 제작대", - "block.betterend.tenanea_door": "테나네아 문", - "block.betterend.tenanea_fence": "테나네아 울타리", - "block.betterend.tenanea_gate": "테나네아 울타리 문", - "block.betterend.tenanea_ladder": "테나네아 사다리", - "block.betterend.tenanea_leaves": "테나네아 잎", - "block.betterend.tenanea_log": "테나네아 원목", - "block.betterend.tenanea_planks": "테나네아 판자", - "block.betterend.tenanea_plate": "테나네아 압력판", - "block.betterend.tenanea_sapling": "테나네아 묘목", - "block.betterend.tenanea_sign": "테나네아 표지판", - "block.betterend.tenanea_slab": "테나네아 반 블록", - "block.betterend.tenanea_stairs": "테나네아 계단", - "block.betterend.tenanea_stripped_bark": "껍질 벗긴 테나네아", - "block.betterend.tenanea_stripped_log": "껍질 벗긴 테나네아 원목", - "block.betterend.tenanea_trapdoor": "테나네아 다락문", + "block.betterend.tenanea_bark": "테나니아나무", + "block.betterend.tenanea_barrel": "테나니아나무 통", + "block.betterend.tenanea_bookshelf": "테나니아나무 책장", + "block.betterend.tenanea_button": "테나니아나무 버튼", + "block.betterend.tenanea_chest": "테나니아나무 상자", + "block.betterend.tenanea_crafting_table": "테나니아나무 제작대", + "block.betterend.tenanea_door": "테나니아나무 문", + "block.betterend.tenanea_fence": "테나니아나무 울타리", + "block.betterend.tenanea_gate": "테나니아나무 울타리 문", + "block.betterend.tenanea_ladder": "테나니아나무 사다리", + "block.betterend.tenanea_leaves": "테나니아나무 잎", + "block.betterend.tenanea_log": "테나니아나무 원목", + "block.betterend.tenanea_planks": "테나니아나무 판자", + "block.betterend.tenanea_plate": "테나니아나무 압력판", + "block.betterend.tenanea_sapling": "테나니아나무 묘목", + "block.betterend.tenanea_sign": "테나니아나무 표지판", + "block.betterend.tenanea_slab": "테나니아나무 반 블록", + "block.betterend.tenanea_stairs": "테나니아나무 계단", + "block.betterend.tenanea_stripped_bark": "껍질 벗긴 테나니아나무", + "block.betterend.tenanea_stripped_log": "껍질 벗긴 테나니아나무 원목", + "block.betterend.tenanea_trapdoor": "테나니아나무 다락문", "block.betterend.amber_block": "호박 블록", - "block.betterend.amber_ore": "호박 원석", + "block.betterend.amber_ore": "호박 광석", "item.betterend.amber_gem": "호박", "item.betterend.raw_amber": "가공하지 않은 호박", - "block.betterend.tenanea_flowers": "테나네아 꽃", - "block.betterend.tenanea_outer_leaves": "테나네아 겉잎", + "block.betterend.tenanea_flowers": "테나니아나무 꽃", + "block.betterend.tenanea_outer_leaves": "테나니아나무 겉잎", "block.betterend.pink_moss": "분홍색 이끼", "block.betterend.pink_moss_path": "분홍색 이끼 길", @@ -378,7 +380,7 @@ "block.betterend.iron_bulb_lantern_pink": "분홍색 철 구근 랜턴", "block.betterend.iron_bulb_lantern_purple": "보라색 철 구근 랜턴", "block.betterend.iron_bulb_lantern_red": "빨간색 철 구근 랜턴", - "block.betterend.iron_bulb_lantern_white": "흰색 철 구근 랜턴", + "block.betterend.iron_bulb_lantern_white": "하얀색 철 구근 랜턴", "block.betterend.iron_bulb_lantern_yellow": "노란색 철 구근 랜턴", "block.betterend.thallasium_bulb_lantern": "탈라슘 구근 랜턴", @@ -396,7 +398,7 @@ "block.betterend.thallasium_bulb_lantern_pink": "분홍색 탈라슘 구근 랜턴", "block.betterend.thallasium_bulb_lantern_purple": "보라색 탈라슘 구근 랜턴", "block.betterend.thallasium_bulb_lantern_red": "빨간색 탈라슘 구근 랜턴", - "block.betterend.thallasium_bulb_lantern_white": "흰색 탈라슘 구근 랜턴", + "block.betterend.thallasium_bulb_lantern_white": "하얀색 탈라슘 구근 랜턴", "block.betterend.thallasium_bulb_lantern_yellow": "노란색 탈라슘 구근 랜턴", "block.betterend.bushy_grass": "무성한 잔디", @@ -436,7 +438,7 @@ "block.betterend.hydralux_petal_block_pink": "분홍색 꽃잎 블록", "block.betterend.hydralux_petal_block_purple": "보라색 꽃잎 블록", "block.betterend.hydralux_petal_block_red": "빨간색 꽃잎 블록", - "block.betterend.hydralux_petal_block_white": "흰색 꽃잎 블록", + "block.betterend.hydralux_petal_block_white": "하얀색 꽃잎 블록", "block.betterend.hydralux_petal_block_yellow": "노란색 꽃잎 블록", "block.betterend.hydralux_sapling": "하이드라럭스 묘목", "block.betterend.hydrothermal_vent": "열수구", @@ -508,13 +510,13 @@ "message.betterend.set_spawn": "§b§l리스폰 지점을 설정했습니다", "message.betterend.fail_spawn": "§c§l리스폰 지점을 설정하려면 호박 6개를 들고 있어야 합니다", - "block.betterend.dragon_tree_composter": "용혈수 퇴비통", + "block.betterend.dragon_tree_composter": "용혈수나무 퇴비통", "block.betterend.end_lotus_composter": "엔드 연꽃 퇴비통", "block.betterend.helix_tree_composter": "나선형 나무 퇴비통", - "block.betterend.lacugrove_composter": "라쿠그로브 퇴비통", + "block.betterend.lacugrove_composter": "라쿠그로브나무 퇴비통", "block.betterend.mossy_glowshroom_composter": "이끼 낀 발광버섯 퇴비통", - "block.betterend.pythadendron_composter": "피타덴드론 퇴비통", - "block.betterend.tenanea_composter": "테나네아 퇴비통", + "block.betterend.pythadendron_composter": "피타덴드론나무 퇴비통", + "block.betterend.tenanea_composter": "테나니아나무 퇴비통", "biome.betterend.old_bulbis_gardens": "오래된 구근 정원", "block.betterend.ivis_moss": "이비스 이끼", @@ -596,6 +598,7 @@ "item.betterend.silk_fiber": "비단 실", "item.betterend.spawn_egg_silk_moth": "누에나방 생성 알", + "item.betterend.thallasium_raw": "탈라슘 원석", "block.betterend.thallasium_ore": "탈라슘 광석", "item.betterend.thallasium_axe": "탈라슘 도끼", "item.betterend.thallasium_hoe": "탈라슘 괭이", @@ -642,7 +645,7 @@ "block.betterend.terminite_bulb_lantern_pink": "분홍색 터미나이트 구근 랜턴", "block.betterend.terminite_bulb_lantern_purple": "보라색 터미나이트 구근 랜턴", "block.betterend.terminite_bulb_lantern_red": "빨간색 터미나이트 구근 랜턴", - "block.betterend.terminite_bulb_lantern_white": "흰색 터미나이트 구근 랜턴", + "block.betterend.terminite_bulb_lantern_white": "하얀색 터미나이트 구근 랜턴", "block.betterend.terminite_bulb_lantern_yellow": "노란색 터미나이트 구근 랜턴", "block.betterend.terminite_chain": "터미나이트 사슬", @@ -658,7 +661,7 @@ "item.betterend.thallasium_chestplate": "탈라슘 흉갑", "item.betterend.thallasium_hammer": "탈라슘 망치", "item.betterend.thallasium_helmet": "탈라슘 투구", - "item.betterend.thallasium_leggings": "탈라슘 각반", + "item.betterend.thallasium_leggings": "탈라슘 레깅스", "block.betterend.missing_tile": "누락된 타일", "block.betterend.charcoal_block": "숯 블록", "block.betterend.end_stone_furnace": "엔드 돌 화로", @@ -715,14 +718,14 @@ "block.betterend.azure_jadestone_pedestal": "하늘색 옥석 받침대", "block.betterend.azure_jadestone_pillar": "하늘색 옥석 기둥", "block.betterend.azure_jadestone_plate": "하늘색 옥석 압력판", - "block.betterend.azure_jadestone_polished": "윤나는 하늘색 옥석 ", + "block.betterend.azure_jadestone_polished": "윤나는 하늘색 옥석", "block.betterend.azure_jadestone_slab": "하늘색 옥석 반 블록", "block.betterend.azure_jadestone_stairs": "하늘색 옥석 계단", "block.betterend.azure_jadestone_tiles": "하늘색 옥석 타일 ", "block.betterend.azure_jadestone_wall": "하늘색 옥석 담장", "block.betterend.chorus_mushroom_seed": "후렴 버섯 씨앗", "block.betterend.end_stone_stalactite": "엔드 돌 종유석", - "block.betterend.end_stone_stalactite_cavemoss": "동굴 이끼가 덮힌 엔드 돌 종유석", + "block.betterend.end_stone_stalactite_cavemoss": "동굴 이끼가 덮인 엔드 돌 종유석", "block.betterend.pearlberry_seed": "펄베리 씨앗", "block.betterend.rubinea": "루비네아", "block.betterend.sandy_jadestone": "모래색 옥석", @@ -741,8 +744,8 @@ "block.betterend.sandy_jadestone_stairs": "모래색 옥석 계단", "block.betterend.sandy_jadestone_tiles": "모래색 옥석 타일", "block.betterend.sandy_jadestone_wall": "모래색 옥석 담장", - "block.betterend.smaragdant_crystal": "스마그댄트 수정", - "block.betterend.smaragdant_crystal_shard": "스마그댄트 수정 조각", + "block.betterend.smaragdant_crystal": "스마라그댄트 수정", + "block.betterend.smaragdant_crystal_shard": "스마라그댄트 수정 조각", "block.betterend.virid_jadestone": "담녹색 옥석", "block.betterend.virid_jadestone_bricks": "담녹색 옥석 벽돌", "block.betterend.virid_jadestone_bricks_slab": "담녹색 옥석 벽돌 반 블록", @@ -765,9 +768,9 @@ "biome.betterend.empty_aurora_cave": "빈 오로라 동굴", "biome.betterend.empty_end_cave": "빈 엔드 동굴", - "biome.betterend.empty_smaragdant_cave": "빈 스마그댄트 동굴", + "biome.betterend.empty_smaragdant_cave": "빈 스마라그댄트 동굴", "biome.betterend.lush_aurora_cave": "무성한 오로라 동굴", - "biome.betterend.lush_smaragdant_cave": "무성한 스마그댄트 동굴", + "biome.betterend.lush_smaragdant_cave": "무성한 스마라그댄트 동굴", "block.betterend.dragon_bone_block": "드래곤 뼈 블록", "block.betterend.dragon_bone_slab": "드래곤 뼈 반 블록", @@ -778,29 +781,29 @@ "block.betterend.filalux": "필라룩스", "block.betterend.filalux_lantern": "필라룩스 랜턴", "block.betterend.filalux_wings": "필라룩스 날개", - "block.betterend.lucernia_bark": "루체르니아", - "block.betterend.lucernia_barrel": "루체르니아 통", - "block.betterend.lucernia_bookshelf": "루체르니아 책장", - "block.betterend.lucernia_button": "루체르니아 버튼", - "block.betterend.lucernia_chest": "루체르니아 상자", - "block.betterend.lucernia_composter": "루체르니아 퇴비통", - "block.betterend.lucernia_crafting_table": "루체르니아 제작대", - "block.betterend.lucernia_door": "루체르니아 문", - "block.betterend.lucernia_fence": "루체르니아 울타리", - "block.betterend.lucernia_gate": "루체르니아 울타리 문", - "block.betterend.lucernia_ladder": "루체르니아 사다리", - "block.betterend.lucernia_leaves": "루체르니아 잎", - "block.betterend.lucernia_log": "루체르니아 원목", - "block.betterend.lucernia_outer_leaves": "루체르니아 겉잎", - "block.betterend.lucernia_planks": "루체르니아 판자", - "block.betterend.lucernia_plate": "루체르니아 압력판", - "block.betterend.lucernia_sapling": "루체르니아 묘목", - "block.betterend.lucernia_sign": "루체르니아 표지판", - "block.betterend.lucernia_slab": "루체르니아 반 블록", - "block.betterend.lucernia_stairs": "루체르니아 계단", - "block.betterend.lucernia_stripped_bark": "껍질 벗긴 루체르니아", - "block.betterend.lucernia_stripped_log": "껍질 벗긴 루체르니아 원목", - "block.betterend.lucernia_trapdoor": "루체르니아 다락문", + "block.betterend.lucernia_bark": "루체르니아나무", + "block.betterend.lucernia_barrel": "루체르니아나무 통", + "block.betterend.lucernia_bookshelf": "루체르니아나무 책장", + "block.betterend.lucernia_button": "루체르니아나무 버튼", + "block.betterend.lucernia_chest": "루체르니아나무 상자", + "block.betterend.lucernia_composter": "루체르니아나무 퇴비통", + "block.betterend.lucernia_crafting_table": "루체르니아나무 제작대", + "block.betterend.lucernia_door": "루체르니아나무 문", + "block.betterend.lucernia_fence": "루체르니아나무 울타리", + "block.betterend.lucernia_gate": "루체르니아나무 울타리 문", + "block.betterend.lucernia_ladder": "루체르니아나무 사다리", + "block.betterend.lucernia_leaves": "루체르니아나무 잎", + "block.betterend.lucernia_log": "루체르니아나무 원목", + "block.betterend.lucernia_outer_leaves": "루체르니아나무 겉잎", + "block.betterend.lucernia_planks": "루체르니아나무 판자", + "block.betterend.lucernia_plate": "루체르니아나무 압력판", + "block.betterend.lucernia_sapling": "루체르니아나무 묘목", + "block.betterend.lucernia_sign": "루체르니아나무 표지판", + "block.betterend.lucernia_slab": "루체르니아나무 반 블록", + "block.betterend.lucernia_stairs": "루체르니아나무 계단", + "block.betterend.lucernia_stripped_bark": "껍질 벗긴 루체르니아나무", + "block.betterend.lucernia_stripped_log": "껍질 벗긴 루체르니아나무 원목", + "block.betterend.lucernia_trapdoor": "루체르니아나무 다락문", "block.betterend.aurant_polypore": "오랑 버섯", "block.betterend.bolux_mushroom": "볼럭스 버섯", @@ -809,7 +812,7 @@ "block.betterend.ruscus": "러스커스", "item.betterend.bolux_mushroom_cooked": "익힌 볼럭스 버섯", - "block.betterend.silk_moth_hive": "누에 나방통 ", + "block.betterend.silk_moth_hive": "누에 나방통", "item.betterend.silk_moth_matrix": "누에 나방 망", "biome.betterend.neon_oasis": "네온 오아시스", @@ -845,17 +848,17 @@ "block.betterend.hydralux_petal_block_slate_gray": "쥐색 꽃잎 블록", "block.betterend.hydralux_petal_block_violet": "보라색 꽃잎 블록", - "block.betterend.smaragdant_crystal_bricks": "스마그댄트 벽돌", - "block.betterend.smaragdant_crystal_bricks_slab": "스마그댄트 벽돌 반 블록", - "block.betterend.smaragdant_crystal_bricks_stairs": "스마그댄트 벽돌 계단", - "block.betterend.smaragdant_crystal_bricks_wall": "스마그댄트 벽돌 담장", - "block.betterend.smaragdant_crystal_pedestal": "스마그댄트 받침대", - "block.betterend.smaragdant_crystal_pillar": "스마그댄트 기둥", - "block.betterend.smaragdant_crystal_polished": "윤나는 스마그댄트", - "block.betterend.smaragdant_crystal_slab": "스마그댄트 반 블록", - "block.betterend.smaragdant_crystal_stairs": "스마그댄트 계단", - "block.betterend.smaragdant_crystal_tiles": "스마그댄트 타일", - "block.betterend.smaragdant_crystal_wall": "스마그댄트 담장", + "block.betterend.smaragdant_crystal_bricks": "스마라그댄트 벽돌", + "block.betterend.smaragdant_crystal_bricks_slab": "스마라그댄트 벽돌 반 블록", + "block.betterend.smaragdant_crystal_bricks_stairs": "스마라그댄트 벽돌 계단", + "block.betterend.smaragdant_crystal_bricks_wall": "스마라그댄트 벽돌 담장", + "block.betterend.smaragdant_crystal_pedestal": "스마라그댄트 받침대", + "block.betterend.smaragdant_crystal_pillar": "스마라그댄트 기둥", + "block.betterend.smaragdant_crystal_polished": "윤나는 스마라그댄트", + "block.betterend.smaragdant_crystal_slab": "스마라그댄트 반 블록", + "block.betterend.smaragdant_crystal_stairs": "스마라그댄트 계단", + "block.betterend.smaragdant_crystal_tiles": "스마라그댄트 타일", + "block.betterend.smaragdant_crystal_wall": "스마라그댄트 담장", "message.betterend.anvil_damage": "§c피해", "block.betterend.neon_cactus_block": "네온 선인장 블록", @@ -869,7 +872,42 @@ "attribute.name.generic.blindness_resistance": "실명 저항", - "tooltip.armor.crystalite_set": "세트 보너스 : 재생 I", - "tooltip.armor.crystalite_chest": "효과 : 굴착 속도 I", - "tooltip.armor.crystalite_boots": "효과 : 신속 I" + "tooltip.armor.crystalite_set": "세트 보너스: 재생 I", + "tooltip.armor.crystalite_chest": "효과: 채굴 속도 I", + "tooltip.armor.crystalite_boots": "효과: 신속 I", + + "block.betterend.azure_jadestone_flower_pot": "하늘색 옥석 화분", + "block.betterend.endstone_flower_pot": "엔드 돌 화분", + "block.betterend.flavolite_flower_pot": "플라보라이트 화분", + "block.betterend.sandy_jadestone_flower_pot": "모래색 옥석 화분", + "block.betterend.sulphuric_rock_flower_pot": "유황암 화분", + "block.betterend.violecite_flower_pot": "바이올사이트 화분", + "block.betterend.virid_jadestone_flower_pot": "담녹색 옥석 화분", + "block.betterend.virid_jadestone_flower_pot": "담녹색 옥석 화분", + + "block.betterend.umbralith": "엄브럴리스", + "block.betterend.umbralith_bricks": "엄브럴리스 벽돌", + "block.betterend.umbralith_bricks_slab": "엄브럴리스 벽돌 반 블록", + "block.betterend.umbralith_bricks_stairs": "엄브럴리스 벽돌 계단", + "block.betterend.umbralith_bricks_wall": "엄브럴리스 벽돌 담장", + "block.betterend.umbralith_button": "엄브럴리스 버튼", + "block.betterend.umbralith_flower_pot": "엄브럴리스 화분", + "block.betterend.umbralith_furnace": "엄브럴리스 화로", + "block.betterend.umbralith_lantern": "엄브럴리스 랜턴", + "block.betterend.umbralith_pedestal": "엄브럴리스 받침대", + "block.betterend.umbralith_pillar": "엄브럴리스 기둥", + "block.betterend.umbralith_plate": "엄브럴리스 압력판", + "block.betterend.umbralith_polished": "윤나는 엄브럴리스", + "block.betterend.umbralith_slab": "엄브럴리스 반 블록", + "block.betterend.umbralith_stairs": "엄브럴리스 계단", + "block.betterend.umbralith_tiles": "엄브럴리스 타일", + "block.betterend.umbralith_wall": "엄브럴리스 담장", + + "biome.betterend.umbra_valley": "그림자 계곡", + "block.betterend.inflexia": "인플렉시아", + "block.betterend.pallidium_full": "팔리디움 (전체형 커버)", + "block.betterend.pallidium_heavy": "팔리디움 (중형 커버)", + "block.betterend.pallidium_thin": "팔리디움 (경형 커버)", + "block.betterend.pallidium_tiny": "팔리디움 (초경형 커버)", + "block.betterend.flammalix": "플래멀릭스" } diff --git a/src/main/resources/assets/betterend/lang/pt_br.json b/src/main/resources/assets/betterend/lang/pt_br.json new file mode 100644 index 00000000..bde732b6 --- /dev/null +++ b/src/main/resources/assets/betterend/lang/pt_br.json @@ -0,0 +1,917 @@ +{ + "itemGroup.betterend.end_items": "Better End: Itens", + "itemGroup.betterend.end_blocks": "Better End: Blocos", + + "item.betterend.guidebook": "The End para Leigos", + "book.betterend.landing": "Um pequeno guia sobre como sobreviver nas condições extremas do End.", + "book.betterend.subtitle": "Sobreviva no End", + + "category.rei.damage.amount&dmg": "Danos na ferramenta: %s", + "category.rei.infusion.time&val": "Tempo: %s", + + "biome.betterend.foggy_mushroomland": "Terras de Cogumelos Neovoada", + "biome.betterend.dust_wastelands": "Terras Devastadas", + "biome.betterend.chorus_forest": "Floresta de Choros", + "biome.betterend.megalake": "Megalake", + "biome.betterend.crystal_mountains": "Montanhas de Cristal", + + "entity.betterend.dragonfly": "Libélula", + "item.betterend.spawn_egg_dragonfly": "Ovo gerador de Libélula", + + "entity.betterend.end_slime": "Slime do End", + "item.betterend.spawn_egg_end_slime": "ovo gerador de Slime do End", + + "block.betterend.end_mycelium": "Micélio do End", + "block.betterend.end_moss": "Musgo do End", + "block.betterend.endstone_dust": "Areia do End", + + "block.betterend.end_mycelium_path": "Caminho de Micélio do End", + "block.betterend.end_moss_path": "Caminho de Musgo do End", + + "block.betterend.ender_ore": "Minério do End", + "block.betterend.terminite_block": "Bloco de Terminita", + "block.betterend.aeternium_block": "Bloco de Aeternio", + "block.betterend.ender_block": "Bloco do Ender", + "block.betterend.end_stone_smelter": "Fundidora de Pedra do End", + + "item.betterend.ender_dust": "Pó do Ender", + "item.betterend.ender_shard": "Fragmento do Ender", + "item.betterend.terminite_ingot": "Barra de Terminita", + "item.betterend.aeternium_ingot": "Barra de Aeternio", + "item.betterend.terminite_helmet": "Capacete de Terminita", + "item.betterend.terminite_chestplate": "Peitoral de Terminita", + "item.betterend.terminite_leggings": "Calças de Terminita", + "item.betterend.terminite_boots": "Botas de Terminita", + "item.betterend.terminite_shovel": "Pá de Terminita", + "item.betterend.terminite_sword": "Espada de Terminita", + "item.betterend.terminite_pickaxe": "Picareta de Terminita", + "item.betterend.terminite_axe": "Machado de Terminita", + "item.betterend.terminite_hoe": "Enxada de Terminita", + "item.betterend.terminite_hammer": "Martelo de Terminita", + "item.betterend.aeternium_helmet": "Capacete de Aeternio", + "item.betterend.aeternium_chestplate": "Peitoral de Aeternio", + "item.betterend.aeternium_leggings": "Calças de Aeternio", + "item.betterend.aeternium_boots": "Botas de Aeternio", + "item.betterend.aeternium_shovel": "Pá de Aeternio", + "item.betterend.aeternium_sword": "Espada de Aeternio", + "item.betterend.aeternium_pickaxe": "Picareta de Aeternio", + "item.betterend.aeternium_axe": "Machado de Aeternio", + "item.betterend.aeternium_hoe": "Enxada de Aeternio", + "item.betterend.aeternium_hammer": "Martelo de Aeternio", + "item.betterend.iron_hammer": "Martelo de Ferro", + "item.betterend.golden_hammer": "Martelo de Ouro", + "item.betterend.diamond_hammer": "Martelo de Diamante", + "item.betterend.netherite_hammer": "Martelo de Netherita", + "item.betterend.crystalite_boots": "Botas de Cristalita", + "item.betterend.crystalite_chestplate": "Peitoral de Cristalita", + "item.betterend.crystalite_helmet": "Capacete de Cristalita", + "item.betterend.crystalite_leggings": "Calças de Cristalita", + "item.betterend.aeternium_axe_head": "Cabeça de machado de Aeternio", + "item.betterend.aeternium_hammer_head": "Cabeça de Martelo de Aeternio", + "item.betterend.aeternium_hoe_head": "Cabeça de enxada de Aeternio", + "item.betterend.aeternium_pickaxe_head": "Cabeça de picareta de Aeternio", + "item.betterend.aeternium_shovel_head": "Cabeça de pá de Aeternio", + "item.betterend.aeternium_sword_blade": "Lâmina de espada de Aeternio", + "item.betterend.aeternium_sword_handle": "Punho de espada de Aeternio", + "item.betterend.leather_stripe": "Fatia de Couro", + "item.betterend.leather_wrapped_stick": "Couro Enrolado no Graveto", + "item.betterend.elytra_armored": "Élitros Blindada", + "item.betterend.elytra_crystalite": "Élitros de Cristalita", + "item.betterend.enchanted_membrane": "Membrana Encantada", + + "effect.betterend.end_veil": "Véu do End", + "enchantment.betterend.end_veil": "Véu do End", + "item.minecraft.potion.effect.end_veil": "Poção de Véu do End", + "item.minecraft.potion.effect.long_end_veil": "Poção de Véu do End", + "item.minecraft.splash_potion.effect.end_veil": "Poção Arremessável de Véu do End", + "item.minecraft.splash_potion.effect.long_end_veil": "Poção Arremessável de Véu do End", + "item.minecraft.lingering_potion.effect.end_veil": "Poção Prolongada de Véu do End", + "item.minecraft.lingering_potion.effect.long_end_veil": "Poção Prolongada de Véu do End", + "item.minecraft.tipped_arrow.effect.end_veil": "Flecha de Véu do End", + "item.minecraft.tipped_arrow.effect.long_end_veil": "Flecha de Véu do End", + + "block.betterend.mossy_glowshroom_sapling": "Muda de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_cap": "Copa de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_fur": "Pelagem de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_hymenophore": "Himenóforo de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_bark": "Casca de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_barrel": "Barril de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_button": "Botão de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_chest": "Baú de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_crafting_table": "Bancada de Trabalho de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_door": "Porta de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_fence": "Cerca de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_gate": "Portão de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_ladder": "Escada de mão de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_log": "Tronco de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_planks": "Tábuas de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_plate": "Placa de pressão de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_sign": "Placa de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_slab": "Laje de Coguluminoso Musgosoe", + "block.betterend.mossy_glowshroom_stairs": "Escadas de Coguluminoso Musgoso", + "block.betterend.mossy_glowshroom_stripped_bark": "Madeira de Coguluminoso Musgoso descadada", + "block.betterend.mossy_glowshroom_stripped_log": "Tronco de Coguluminoso Musgoso descascado", + "block.betterend.mossy_glowshroom_trapdoor": "Alçapão de Cogulumiso Musgoso", + + "block.betterend.umbrella_moss": "Musgo Guarda-chuva", + "block.betterend.umbrella_moss_tall": "Musgo Guarda-chuva alto", + "block.betterend.creeping_moss": "Musgo rastejante", + + "block.betterend.blue_vine_seed": "Semente de Trepadeiras Azul", + "block.betterend.blue_vine": "Trepadeiras Azul", + "block.betterend.blue_vine_lantern": "Lanterna de Trepadeiras Azul", + "block.betterend.blue_vine_fur": "Pelagem de Trepadeiras Azul", + + "block.betterend.dense_vine": "Trepadeiras densa", + "block.betterend.bubble_coral": "Coral de Bolhas", + "block.betterend.aurora_crystal": "Cristral de Aurora", + "item.betterend.crystal_shards": "Fragmentos de Cristal de Aurora", + + "block.betterend.pythadendron_sapling": "Muda de Pythadendron", + "block.betterend.pythadendron_bark": "Madeira de Pythadendron", + "block.betterend.pythadendron_barrel": "Barril de Pythadendron", + "block.betterend.pythadendron_button": "Botão de Pythadendron", + "block.betterend.pythadendron_chest": "Baú de Pythadendron", + "block.betterend.pythadendron_crafting_table": "Bancada de Trabalho de Pythadendron", + "block.betterend.pythadendron_door": "Porta de Pythadendron", + "block.betterend.pythadendron_fence": "Cerca de Pythadendron", + "block.betterend.pythadendron_gate": "Portão de Pythadendron", + "block.betterend.pythadendron_ladder": "Escada de mão de Pythadendron", + "block.betterend.pythadendron_log": "Tronco de Pythadendron", + "block.betterend.pythadendron_planks": "Tábuas de Pythadendron", + "block.betterend.pythadendron_plate": "Placa de pressão de Pythadendron", + "block.betterend.pythadendron_sign": "Placa de Pythadendron", + "block.betterend.pythadendron_slab": "Laje de Pythadendron", + "block.betterend.pythadendron_stairs": "Escadas de Pythadendron", + "block.betterend.pythadendron_stripped_bark": "Madeira de Pythadendron descascada", + "block.betterend.pythadendron_stripped_log": "Tronco de Pythadendron descascado", + "block.betterend.pythadendron_trapdoor": "Alçapão de Pythadendron", + + "block.betterend.chorus_nylium": "Nicélio do Coro", + "block.betterend.chorus_nylium_path": "Caminho de Nicélio do Coro", + "block.betterend.chorus_grass": "Grama do Coro", + + "block.betterend.end_lily": "Lírio do End", + "block.betterend.end_lily_seed": "Semente de Lírio do End", + "item.betterend.end_lily_leaf": "Folhas de Lírio do End", + "item.betterend.end_lily_leaf_dried": "Folhas seca de Lírio do End", + + "block.betterend.violecite": "Violecita", + "block.betterend.violecite_bricks": "Tijolos de Violecita", + "block.betterend.violecite_bricks_slab": "Laje de tijolos de Violecita", + "block.betterend.violecite_bricks_stairs": "Escadas de tijolos de Violecita", + "block.betterend.violecite_bricks_wall": "Muro de tijolos de Violecita", + "block.betterend.violecite_button": "Botão de Violecita", + "block.betterend.violecite_pillar": "Pilar de Violecita", + "block.betterend.violecite_plate": "Placa de pressão de Violecita", + "block.betterend.violecite_slab": "Laje de Violecita", + "block.betterend.violecite_tiles": "Azulejos de Violecita", + "block.betterend.violecite_stairs": "Escadas de Violecita", + "block.betterend.violecite_polished": "Violecita Polido", + "block.betterend.violecite_wall": "Muro de Violecita", + "block.betterend.violecite_pedestal": "Pedestal de Violecita", + + "block.betterend.flavolite": "Flavolito", + "block.betterend.flavolite_bricks": "Tijolos de Flavolito", + "block.betterend.flavolite_bricks_slab": "Laje de tijolos de Flavolito", + "block.betterend.flavolite_bricks_stairs": "Escadas de tijolos de Flavolito", + "block.betterend.flavolite_bricks_wall": "Muro de tijolos de Flavolito", + "block.betterend.flavolite_button": "Botão de Flavolito", + "block.betterend.flavolite_pillar": "Pilar de Flavolito", + "block.betterend.flavolite_plate": "Placa de pressão de Flavolito", + "block.betterend.flavolite_slab": "Laje de Flavolito", + "block.betterend.flavolite_tiles": "Azulejos de Flavolito", + "block.betterend.flavolite_stairs": "Escadas de Flavolito", + "block.betterend.flavolite_polished": "Flavolito Polido", + "block.betterend.flavolite_wall": "Muro de Flavolito", + "block.betterend.flavolite_pedestal": "Pedestal de Flavolito", + + "block.betterend.andesite_pedestal": "Pedestal de Andesito", + "block.betterend.diorite_pedestal": "Pedestal de Diorito", + "block.betterend.granite_pedestal": "Pedestal de Granito", + "block.betterend.purpur_pedestal": "Pedestal de Púrpura", + "block.betterend.quartz_pedestal": "Pedestal de Quartzo", + "block.betterend.infusion_pedestal": "Pedestal de Infusão", + + "block.betterend.end_lotus_seed": "Semente de Lotus do End", + "block.betterend.end_lotus_stem": "Caule de Lotus do End", + "block.betterend.end_lotus_leaf": "Folhas de Lotus do End", + "block.betterend.end_lotus_flower": "Flor de Lotus do End", + + "block.betterend.end_lotus_bark": "Madeira de Lotus do End", + "block.betterend.end_lotus_barrel": "Barril de Lotus do End", + "block.betterend.end_lotus_button": "Botão de Lotus do End", + "block.betterend.end_lotus_chest": "baú de Lotus do End", + "block.betterend.end_lotus_crafting_table": "Bancada de Trabalho de Lotus do End", + "block.betterend.end_lotus_door": "Porta de Lotus do End", + "block.betterend.end_lotus_fence": "Cerca de Lotus do End", + "block.betterend.end_lotus_gate": "Portão de Lotus do End", + "block.betterend.end_lotus_ladder": "Escada de mão de Lotus do End", + "block.betterend.end_lotus_log": "Tronco de Lotus do End", + "block.betterend.end_lotus_planks": "Tábuas de Lotus do End", + "block.betterend.end_lotus_plate": "Placa de pressão de Lotus do End", + "block.betterend.end_lotus_sign": "Placa de Lotus do End", + "block.betterend.end_lotus_slab": "Laje de Lotus do End", + "block.betterend.end_lotus_stairs": "Escadas de Lotus do End", + "block.betterend.end_lotus_stripped_bark": "Madeira de Lotus do End descascada", + "block.betterend.end_lotus_stripped_log": "Tronco de Lotus do End descascado", + "block.betterend.end_lotus_trapdoor": "Alçapão", + + "block.betterend.cave_moss": "Musgo Cavernoso", + "block.betterend.cave_grass": "Grama Cavernoso", + "block.betterend.cave_bush": "Arbusto Cavernoso", + + "block.betterend.cave_moss_path": "Caminho de Musgo Cavernoso", + "block.betterend.crystal_moss": "Musgo de Cristal", + "block.betterend.crystal_moss_path": "Caminho de Musgo Cavernoso", + "block.betterend.pythadendron_leaves": "Folhas de Pythadendron", + "item.betterend.spawn_egg_end_fish": "Ovo gerador de Peixe do End", + "block.betterend.crystal_grass": "Grama de Cristal", + + "block.betterend.flavolite_runed": "Runas de Flavolito", + "block.betterend.end_portal_block": "Portal do End", + "block.betterend.eternal_pedestal": "Pedestal de Eternal", + "block.betterend.flavolite_runed_eternal": "Runas de Eternal de Flavolito", + "item.betterend.eternal_crystal": "Cristal Eternal", + + "block.betterend.lacugrove_bark": "Madeira de Lacugrove", + "block.betterend.lacugrove_barrel": "Barril de Lacugrove", + "block.betterend.lacugrove_button": "Botão de Lacugrove", + "block.betterend.lacugrove_chest": "Baú de Lacugrove", + "block.betterend.lacugrove_crafting_table": "Bancada de Trabalho de Lacugrove", + "block.betterend.lacugrove_door": "Porta de Lacugrove", + "block.betterend.lacugrove_fence": "Cerca de Lacugrove", + "block.betterend.lacugrove_gate": "Portão de Lacugrove", + "block.betterend.lacugrove_ladder": "Escada de mão de Lacugrove", + "block.betterend.lacugrove_log": "Tronco de Lacugrove", + "block.betterend.lacugrove_planks": "Tábuas de Lacugrove", + "block.betterend.lacugrove_plate": "Placa de pressão de Lacugrove", + "block.betterend.lacugrove_sign": "Placa de Lacugrove", + "block.betterend.lacugrove_slab": "Lajes de Lacugrove", + "block.betterend.lacugrove_stairs": "Escadas de Lacugrove", + "block.betterend.lacugrove_stripped_bark": "Madeira de Lacugrove descascada", + "block.betterend.lacugrove_stripped_log": "Tronco de Lacugrove descascado", + "block.betterend.lacugrove_trapdoor": "Alçapão de Lacugrove", + + "block.betterend.lacugrove_leaves": "Folhas de Lacugrove", + "block.betterend.lacugrove_sapling": "Muda de Lacugrove", + + "biome.betterend.megalake_grove": "Arvoredos de Megalake", + "biome.betterend.painted_mountains": "Montanhas Pintadas", + + "block.betterend.dragon_tree_bark": "Madeira de Árvore do Dragão", + "block.betterend.dragon_tree_barrel": "Barril de Árvore do Dragão", + "block.betterend.dragon_tree_button": "Butão de Árvore do Dragão", + "block.betterend.dragon_tree_chest": "Baú de Árvore do Dragão", + "block.betterend.dragon_tree_crafting_table": "Bancada de Trabalho de Árvore do Dragão", + "block.betterend.dragon_tree_door": "Porta de Árvore do Dragão", + "block.betterend.dragon_tree_fence": "Cerca de Árvore do Dragão", + "block.betterend.dragon_tree_gate": "Portão de Árvore do Dragão", + "block.betterend.dragon_tree_ladder": "Escada de mão de Árvore do Dragão", + "block.betterend.dragon_tree_log": "Tronco de Árvore do Dragão", + "block.betterend.dragon_tree_planks": "tábuas de Árvore do Dragão", + "block.betterend.dragon_tree_plate": "Placa de pressão de Árvore do Dragão", + "block.betterend.dragon_tree_sign": "Placa de Árvore do Dragão", + "block.betterend.dragon_tree_slab": "Laje de Árvore do Dragão", + "block.betterend.dragon_tree_stairs": "Escadas de Árvore do Dragão", + "block.betterend.dragon_tree_stripped_bark": "Madeira de Árvore do Dragão descascada", + "block.betterend.dragon_tree_stripped_log": "Tronco de Árvore do Dragão descascado", + "block.betterend.dragon_tree_trapdoor": "Alçapão de Árvore do Dragão", + + "biome.betterend.shadow_forest": "Floresta da Sombra", + "block.betterend.dragon_tree_leaves": "Folhas de Árvore do Dragão", + "block.betterend.dragon_tree_sapling": "Muda de Árvore do Dragão", + "block.betterend.shadow_grass": "Grama da Sombra", + "block.betterend.shadow_grass_path": "Caminho de Grama da Sombra", + "block.betterend.shadow_plant": "Planta da Sombra", + + "block.betterend.dragon_tree_bookshelf": "Estante de livros de Árvore do Dragão", + "block.betterend.end_lotus_bookshelf": "Estante de livros de Lotus do End", + "block.betterend.lacugrove_bookshelf": "Estante de livros de Lacugrove", + "block.betterend.mossy_glowshroom_bookshelf": "Estante de livros de Coguluminoso Musgoso", + "block.betterend.pythadendron_bookshelf": "Estante de livros de Pythadendron", + + "block.betterend.murkweed": "Erva daninha", + "block.betterend.needlegrass": "Gramagulha", + "block.betterend.twisted_vine": "Trepadeiras torcida", + + "block.betterend.shadow_berry": "Semente de baga da Sombra", + "item.betterend.shadow_berry_cooked": "Baga da Sombra cozida", + "item.betterend.shadow_berry_raw": "Baga da Sombra", + "block.betterend.purple_polypore": "Polypore Púrpura", + + "block.betterend.cyan_moss": "Musgo ciano", + "block.betterend.tail_moss": "Cauda musgosa", + + "block.betterend.flavolite_lantern": "Lanterna de Flavolito", + "block.betterend.end_stone_lantern": "Lanterna de Preda do End", + "block.betterend.violecite_lantern": "Lantern de Violecita", + + "entity.betterend.end_fish": "Peixe do End", + "entity.betterend.shadow_walker": "Andarilho da Sombra", + "item.betterend.spawn_egg_shadow_walker": "Ovo gerador de Andarilho da Sombra", + + "block.betterend.andesite_lantern": "Lampião de Andesito", + "block.betterend.blackstone_lantern": "Lampião de Pedra negra", + "block.betterend.diorite_lantern": "Lampião de Diorito", + "block.betterend.granite_lantern": "Lampião de Granito", + "block.betterend.purpur_lantern": "Lampião de Púrpura", + "block.betterend.quartz_lantern": "Lampião de Quartzo", + + "item.betterend.bucket_end_fish": "Balde com Peixe do End", + "item.betterend.bucket_cubozoa": "Balde com Cubozoa", + "item.betterend.end_fish_cooked": "Peixe do End cozido", + "item.betterend.end_fish_raw": "Peixe do End", + + "biome.betterend.amber_land": "Terras de Âmbar", + "biome.betterend.blossoming_spires": "Pináculos em Flor", + "block.betterend.amber_grass": "Grama de Âmbar", + "block.betterend.amber_grass_path": "Caminho de grama de Âmbar", + "block.betterend.tenanea_bark": "Madeira de Tenanea", + "block.betterend.tenanea_barrel": "Barril de Tenanea", + "block.betterend.tenanea_bookshelf": "Estante de livros de Tenanea", + "block.betterend.tenanea_button": "Baú de Tenanea", + "block.betterend.tenanea_chest": "Báu Tenanea", + "block.betterend.tenanea_crafting_table": "Bancada de Trabalho de Tenanea", + "block.betterend.tenanea_door": "Porta de Tenanea", + "block.betterend.tenanea_fence": "Cerca de Tenanea", + "block.betterend.tenanea_gate": "Portão de Tenanea", + "block.betterend.tenanea_ladder": "Escada de mão de Tenanea", + "block.betterend.tenanea_leaves": "Folhas de Tenanea", + "block.betterend.tenanea_log": "Tronco de Tenanea", + "block.betterend.tenanea_planks": "Tábuas de Tenanea", + "block.betterend.tenanea_plate": "Placa de pressão de Tenanea", + "block.betterend.tenanea_sapling": "Muda de Tenanea", + "block.betterend.tenanea_sign": "Placa de Tenanea", + "block.betterend.tenanea_slab": "Laje de Tenanea", + "block.betterend.tenanea_stairs": "Escadas de Tenanea", + "block.betterend.tenanea_stripped_bark": "Madeira de Tenanea descascada", + "block.betterend.tenanea_stripped_log": "Tronco de Tenanea descascado", + "block.betterend.tenanea_trapdoor": "Alçapão de Tenanea", + + "block.betterend.amber_block": "Bloco de Âmbar", + "block.betterend.amber_ore": "Minério de Âmbar", + "item.betterend.amber_gem": "Joia de Âmbar", + "item.betterend.raw_amber": "Âmbar bruto", + "block.betterend.tenanea_flowers": "Flores de Tenanea", + "block.betterend.tenanea_outer_leaves": "Folhas Exteriores de Tenanea", + + "block.betterend.pink_moss": "Musgo Pink", + "block.betterend.pink_moss_path": "Pink Moss Path", + + "block.betterend.twisted_moss": "Musgo torcido", + + "block.betterend.bulb_vine": "Trepadeiras Bulbo", + "block.betterend.bulb_vine_seed": "Semente de Trepadeiras Bulbo", + "item.betterend.glowing_bulb": "Bulbo Brilhante", + + "block.betterend.iron_bulb_lantern": "Lanterna bulbo de Ferro", + "block.betterend.iron_bulb_lantern_black": "Lantera bulbo preta de Ferro", + "block.betterend.iron_bulb_lantern_blue": "Lanterna bulbo azul de Ferro", + "block.betterend.iron_bulb_lantern_brown": "Lanterna bulbo marrom de Ferro", + "block.betterend.iron_bulb_lantern_cyan": "Lanterna bulbo ciana de Ferro", + "block.betterend.iron_bulb_lantern_gray": "Lanterna bulbo cinza de Ferro", + "block.betterend.iron_bulb_lantern_green": "Lanterna bulbo verde de Ferro", + "block.betterend.iron_bulb_lantern_light_blue": "Lanterna bulbo azul-clara de Ferro", + "block.betterend.iron_bulb_lantern_light_gray": "Lanterna bulbo cinza-clara de Ferro", + "block.betterend.iron_bulb_lantern_lime": "Lanterna bulbo verde-limão de Ferro", + "block.betterend.iron_bulb_lantern_magenta": "Lanterna bulbo magenta de Ferro", + "block.betterend.iron_bulb_lantern_orange": "Lanterna bulbo laranja de Ferro", + "block.betterend.iron_bulb_lantern_pink": "Lanterna rosa de ferro de Bulbo", + "block.betterend.iron_bulb_lantern_purple": "Lanterna bulbo púrpura de Ferro", + "block.betterend.iron_bulb_lantern_red": "Lanterna bulbo vermelha de Ferro", + "block.betterend.iron_bulb_lantern_white": "Lanterna bulbo branca de Ferro", + "block.betterend.iron_bulb_lantern_yellow": "Lanterna bulbo amarelo de Ferro", + + "block.betterend.thallasium_bulb_lantern": "Lanterna bulbo de Thallasio", + "block.betterend.thallasium_bulb_lantern_black": "Lanterna bulbo preta de Thallasio", + "block.betterend.thallasium_bulb_lantern_blue": "Lanterna bulbo azul de Thallasio", + "block.betterend.thallasium_bulb_lantern_brown": "Lanterna bulbo marrom de Thallasio", + "block.betterend.thallasium_bulb_lantern_cyan": "Lanterna bulbo ciana de Thallasio", + "block.betterend.thallasium_bulb_lantern_gray": "Lanterna bulbo cinza de Thallasio", + "block.betterend.thallasium_bulb_lantern_green": "Lanterna bulbo verde de Thallasio", + "block.betterend.thallasium_bulb_lantern_light_blue": "Lanterna bulbo azul-clara de Thallasio", + "block.betterend.thallasium_bulb_lantern_light_gray": "Lanterna bulbo cinza-clara de Thallasio", + "block.betterend.thallasium_bulb_lantern_lime": "Lanterna bulbo verde-limão de Thallasio", + "block.betterend.thallasium_bulb_lantern_magenta": "Lanterna bulbo magenta de Thallasio", + "block.betterend.thallasium_bulb_lantern_orange": "Lanterna bulbo laranja de Thallasio", + "block.betterend.thallasium_bulb_lantern_pink": "Lanterna bulbo rosa de Thallasio", + "block.betterend.thallasium_bulb_lantern_purple": "Lanterna bulbo púrpura de Thallasio", + "block.betterend.thallasium_bulb_lantern_red": "Lanterna bulbo vermelha de Thallasio", + "block.betterend.thallasium_bulb_lantern_white": "Lanterna bulbo branca de Thallasio", + "block.betterend.thallasium_bulb_lantern_yellow": "Lanterna bulbo amarela de Thallasio", + + "block.betterend.bushy_grass": "Grama espessa", + + "block.betterend.brimstone": "Enxofre", + "block.betterend.sulphuric_rock": "Rocha Sulfúrica", + "block.betterend.sulphuric_rock_bricks": "Tijolos de Rocha Sulfúrica", + "block.betterend.sulphuric_rock_bricks_slab": "Laje de tijolos de Rocha Sulfúrica", + "block.betterend.sulphuric_rock_bricks_stairs": "Escadas de tijolos de Rocha Sulfúrica", + "block.betterend.sulphuric_rock_bricks_wall": "Muro de tijolos de Rocha Sulfúrica", + "block.betterend.sulphuric_rock_button": "Botão dde Rocha Sulfúrica", + "block.betterend.sulphuric_rock_lantern": "Lanterna de Rocha Sulfúrica", + "block.betterend.sulphuric_rock_pedestal": "Pedestal de Rocha Sulfúrica", + "block.betterend.sulphuric_rock_pillar": "Pilar de Rocha Sulfúrica", + "block.betterend.sulphuric_rock_plate": "Placa de pressão de Rocha Sulfúrica", + "block.betterend.sulphuric_rock_polished": "Rocha Sulfúrica polida", + "block.betterend.sulphuric_rock_slab": "Laje de Rocha Sulfúrica", + "block.betterend.sulphuric_rock_stairs": "Escadas de Rocha Sulfúrica", + "block.betterend.sulphuric_rock_tiles": "Rocha Sulfúrica lapidada", + "block.betterend.sulphuric_rock_wall": "Muro de Rocha Sulfúrica", + "block.betterend.sulphur_crystal": "Cristal de enxofre", + "item.betterend.crystalline_sulphur": "Enxofre", + + "biome.betterend.sulphur_springs": "Fontes Sulfúricas", + "block.betterend.hydralux_petal_block": "Bloco de Pétalas Hidraluxe", + "block.betterend.hydralux_petal_block_black": "Bloco de Pétalas preto", + "block.betterend.hydralux_petal_block_blue": "Bloco de Pétalas azul", + "block.betterend.hydralux_petal_block_brown": "Bloco de Pétalas marrom", + "block.betterend.hydralux_petal_block_cyan": "Bloco de Pétalas ciano", + "block.betterend.hydralux_petal_block_gray": "Bloco de Pétalas cinza", + "block.betterend.hydralux_petal_block_green": "Bloco de Pétalas verde", + "block.betterend.hydralux_petal_block_light_blue": "Bloco de Pétalas azul-claro", + "block.betterend.hydralux_petal_block_light_gray": "Bloco de Pétalas cinza-claro", + "block.betterend.hydralux_petal_block_lime": "Bloco de Pétalas verde-limão", + "block.betterend.hydralux_petal_block_magenta": "Bloco de Pétalas magenta", + "block.betterend.hydralux_petal_block_orange": "Bloco de Pétalas laranja", + "block.betterend.hydralux_petal_block_pink": "Bloco de Pétalas rosa", + "block.betterend.hydralux_petal_block_purple": "Bloco de Pétalas púrpura", + "block.betterend.hydralux_petal_block_red": "Bloco de Pétalas veremelho", + "block.betterend.hydralux_petal_block_white": "White Petal Block", + "block.betterend.hydralux_petal_block_yellow": "Bloco de Pétalas amarelo", + "block.betterend.hydralux_sapling": "Muda de Hidraluxe", + "block.betterend.hydrothermal_vent": "Respiradouro Hidrotérmico", + "item.betterend.hydralux_petal": "Pétala de Hidraluxe", + "item.betterend.enchanted_petal": "Pétala encantada", + + "block.betterend.menger_sponge": "Esponja Menger", + "block.betterend.menger_sponge_wet": "Esponja Menger molhada", + "block.betterend.tube_worm": "Verme Tubular", + + "block.betterend.charnia_cyan": "Charnia Ciana", + "block.betterend.charnia_light_blue": "Charnia Azul-clara", + "block.betterend.charnia_orange": "Charnia Laranja", + "block.betterend.charnia_purple": "Charnia Púrpura", + "block.betterend.charnia_red": "Charnia Vermelha", + + "entity.betterend.cubozoa": "Cubozoa", + "item.betterend.spawn_egg_cubozoa": "Ovo gerador de Cubozoa", + + "item.betterend.gelatine": "Gelatina", + "item.betterend.sweet_berry_jelly": "Geléia de frutas doces", + "item.betterend.shadow_berry_jelly": "Geléia de frutas da Sombra", + + "block.betterend.amber_moss": "Musgo de Âmbar", + "block.betterend.amber_moss_path": "Caminho de musgo de Âmbar", + "block.betterend.helix_tree_bark": "Madeira de Árvore de Helix", + "block.betterend.helix_tree_barrel": "Barril de Árvore de Helix", + "block.betterend.helix_tree_bookshelf": "Estante de livros de Árvore de Helix", + "block.betterend.helix_tree_button": "botão de Árvore de Helix", + "block.betterend.helix_tree_chest": "Baú de Árvore de Helix", + "block.betterend.helix_tree_crafting_table": "Bancada de Trabalho de Árvore de Helix", + "block.betterend.helix_tree_door": "Porta de Árvore de Helix", + "block.betterend.helix_tree_fence": "Cerca de Árvore de Helix", + "block.betterend.helix_tree_gate": "Portão de Árvore de Helix", + "block.betterend.helix_tree_ladder": "Escada de mão de Árvore de Helix", + "block.betterend.helix_tree_leaves": "Folhas de Árvore de Helix", + "block.betterend.helix_tree_log": "Tronco de Árvore de Helix", + "block.betterend.helix_tree_planks": "Tábuas de Árvore de Helix", + "block.betterend.helix_tree_plate": "Placa de pressão de Árvore de Helix", + "block.betterend.helix_tree_sapling": "Muda de Árvore de Helix", + "block.betterend.helix_tree_sign": "Placa de Árvore de Helix", + "block.betterend.helix_tree_slab": "Laje de Árvore de Helix", + "block.betterend.helix_tree_stairs": "Escadas de Árvore de Helix", + "block.betterend.helix_tree_stripped_bark": "Madeira de Árvore de Helix descascada", + "block.betterend.helix_tree_stripped_log": "Tronco de Árvore de Helix descascado", + "block.betterend.helix_tree_trapdoor": "Alçapão de Árvore de Helix", + "block.betterend.lanceleaf": "Lanceleaf", + "block.betterend.lanceleaf_seed": "Semente de Lanceleaf", + "block.betterend.hydralux": "Hydralux", + "block.betterend.helix_tree_luminophor": "Árvore de Helix Luminophor", + + "block.betterend.glowing_pillar_leaves": "Folhas de pilar luminoso", + "block.betterend.glowing_pillar_luminophor": "Pilar luminoso de Luminophor", + "block.betterend.glowing_pillar_roots": "Raizes de pilar luminoso", + "block.betterend.glowing_pillar_seed": "Semente de pilar luminoso", + + "biome.betterend.ice_starfield": "Campo de Estrelas de Gelo", + + "block.betterend.ancient_emerald_ice": "Gelo Esmeralda Milenar", + "block.betterend.dense_emerald_ice": "Gelo Esmeralda Denso", + "block.betterend.dense_snow": "Neve Densa", + "block.betterend.emerald_ice": "Gelo Esmeralda", + + "block.betterend.bulb_moss": "Musgo Bulbo", + + "block.betterend.charnia_green": "Charnia Verde", + "block.betterend.vent_bubble_column": "Coluna de bolha de ventilação", + "block.betterend.respawn_obelisk": "Obelisco de Ressurgimento", + "message.betterend.set_spawn": "\u00A7b\u00A7lSeu ponto de renascimento está definido aqui", + "message.betterend.fail_spawn": "\u00A7c\u00A7lVocê precisa segurar 6 Joias de Âmbar para definir o seu ponto de renascimento", + + "block.betterend.dragon_tree_composter": "Composteira de Árvore do Dragão", + "block.betterend.end_lotus_composter": "Composteira de Lotus do End", + "block.betterend.helix_tree_composter": "Composteira de Árvore de Helix", + "block.betterend.lacugrove_composter": "Composteira de Lacugrove", + "block.betterend.mossy_glowshroom_composter": "Composteira de Coguluminoso Musgoso", + "block.betterend.pythadendron_composter": "Composteira de Pythadendron", + "block.betterend.tenanea_composter": "Composteira de Tenanea", + + "biome.betterend.old_bulbis_gardens": "Jardins Antigos Bulbis", + "block.betterend.ivis_moss": "Musgo Ivis", + "block.betterend.ivis_vine": "Trepadeiras Ivis", + "block.betterend.silk_moth_nest": "Ninho de Mariposa de Seda", + + "block.betterend.umbrella_tree_bark": "Madeira de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_barrel": "Barril de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_bookshelf": "Estante de livros de de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_button": "Botão de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_chest": "Baú de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_composter": "Composteira de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_crafting_table": "Bancada de Trabalho de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_door": "Porta de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_fence": "Cerca de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_gate": "Portão de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_ladder": "Escada de mão de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_log": "Tronco de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_planks": "Tábuas de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_plate": "Placa de pressão de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_sign": "Placa de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_slab": "Laje de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_stairs": "Escadas de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_stripped_bark": "Madeira de Árvore Guarda-chuva descascada", + "block.betterend.umbrella_tree_stripped_log": "Tronco de Árvore Guarda-chuva descascado", + "block.betterend.umbrella_tree_trapdoor": "Alçapão de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_membrane": "Membrana de Árvore Guarda-chuva", + + "biome.betterend.umbrella_jungle": "Selva de Guarda-chuvas", + "block.betterend.jungle_grass": "Jungle Grass", + "block.betterend.jungle_moss": "Jungle Moss", + "block.betterend.jungle_moss_path": "Caminho de Musgo da Selva", + "block.betterend.small_jellyshroom": "Cogumelo Gelatinoso pequeno", + "block.betterend.twisted_umbrella_moss": "Musgo torcido de Guarda-chuva", + "block.betterend.twisted_umbrella_moss_tall": "Musgo alto torcido de Guarda-chuva ", + "block.betterend.umbrella_tree_cluster": "Cacho de Árvore Guarda-chuva", + "block.betterend.umbrella_tree_cluster_empty": "Cacho vazio de Árvore Guada-chuva", + "block.betterend.jungle_vine": "Trepadeiras da Selva", + "block.betterend.jungle_fern": "Samambaia da Jungle", + + "block.betterend.jellyshroom_bark": "Madeira de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_barrel": "Barril de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_bookshelf": "Estante de livros de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_button": "botão de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_cap_purple": "Copa púrpura de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_chest": "Baú de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_composter": "Compesteira de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_crafting_table": "Bancada de Trabalho de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_door": "Porta de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_fence": "Cerca de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_gate": "Portão de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_ladder": "Escada de mão de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_log": "Tronco de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_planks": "Tábuas de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_plate": "Placa de pressão de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_sign": "Placa de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_slab": "Laje de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_stairs": "Escadas de Cogumelo Gelatinoso", + "block.betterend.jellyshroom_stripped_bark": "Madeira de Cogumelo Gelatinoso descascada", + "block.betterend.jellyshroom_stripped_log": "Tronco de Cogumelo Gelatinoso descascado", + "block.betterend.jellyshroom_trapdoor": "Alçapão de Cogumelo Gelatinoso", + + + "biome.betterend.eterial_grove": "Arvoredos Eterial", + "block.betterend.umbrella_tree_sapling": "Muda de Árvore Guarda-chuva", + "item.betterend.umbrella_cluster_juice": "Suco do Cacho de árvore guarda-chuva", + "block.betterend.blossom_berry_seed": "Semente de Flor de Baga", + "item.betterend.blossom_berry": "Flor de Baga", + + "biome.betterend.nightshade_redwoods": "Madeiras Vermelhas da Sombra Noturna", + "block.betterend.nightshade_moss": "Musgo da Sombra Noturna", + + "biome.betterend.glowing_grasslands": "Prados Brilhantes", + "block.betterend.blooming_cooksonia": "Flor Cooksonia", + "block.betterend.fracturn": "Fracturn", + "block.betterend.lumecorn": "Bloco de Espigaluminosa", + "block.betterend.salteago": "Salteago", + "block.betterend.vaiolush_fern": "Samambaia de Vaio Exuberante", + "entity.betterend.silk_moth": "Mariposa de Seda", + "item.betterend.silk_fiber": "Fibra de seda", + "item.betterend.spawn_egg_silk_moth": "Ovo gerador de Mariposa de Seda", + + "item.betterend.thallasium_raw": "Thallasio bruto", + "block.betterend.thallasium_ore": "Minério de Thallasio", + "item.betterend.thallasium_axe": "Machado de Thallasio", + "item.betterend.thallasium_hoe": "Enxada de Thallasio", + "item.betterend.thallasium_ingot": "Barra de Thallasio", + "item.betterend.thallasium_pickaxe": "Picareta de Thallasio", + "item.betterend.thallasium_shovel": "Pá de Thallasio", + "item.betterend.thallasium_sword": "Espada de Thallasio", + "block.betterend.thallasium_block": "Bloco de Thallasio", + + "block.betterend.thallasium_bars": "Grades de Thallasio", + "block.betterend.thallasium_door": "Porta de Thallasio", + "block.betterend.thallasium_plate": "Placa de pressão de Thallasio", + "block.betterend.thallasium_tile": "Thallasio lapidado", + "block.betterend.thallasium_trapdoor": "Alçapão de Thallasio", + + "block.betterend.lumecorn_seed": "Semenete de Espigaluminosa", + "item.betterend.lumecorn_rod": "Espigaluminosa", + "block.betterend.thallasium_chandelier": "Lustre de Thallasio", + + "block.betterend.thallasium_anvil": "Bigorna de Thallasio", + "block.betterend.thallasium_chain": "Corrente de Thallasio", + "block.betterend.thallasium_slab": "Laje de Thallasio", + "block.betterend.thallasium_stairs": "Escadas de Thallasio", + + "block.betterend.gold_chandelier": "Lustre de Ouro", + "block.betterend.iron_chandelier": "Lustre de Ferro", + "item.betterend.thallasium_nugget": "Pepita de Thallasio", + + "block.betterend.terminite_anvil": "Bigorna de Terminita", + "block.betterend.terminite_bars": "Grades de Terminita", + + "block.betterend.terminite_bulb_lantern": "Lanterna bulbo de Terminita", + "block.betterend.terminite_bulb_lantern_black": "Lanterna bulbo preta de Terminita", + "block.betterend.terminite_bulb_lantern_blue": "Lanterna bulbo azul de Terminita", + "block.betterend.terminite_bulb_lantern_brown": "Lanterna bulbo marrom de Terminita", + "block.betterend.terminite_bulb_lantern_cyan": "Lanterna bulbo ciana de Terminita", + "block.betterend.terminite_bulb_lantern_gray": "Lanterna bulbo cinza de Terminita", + "block.betterend.terminite_bulb_lantern_green": "Lanterna bulbo verde de Terminita", + "block.betterend.terminite_bulb_lantern_light_blue": "Lanterna bulbo azul-clara de Terminita", + "block.betterend.terminite_bulb_lantern_light_gray": "Lanterna bulbo cinza-clara de Terminita", + "block.betterend.terminite_bulb_lantern_lime": "Lanterna bulbo verde-limão de Terminita", + "block.betterend.terminite_bulb_lantern_magenta": "Lanterna bulbo magenta de Terminita", + "block.betterend.terminite_bulb_lantern_orange": "Lanterna bulbo laranja de Terminita", + "block.betterend.terminite_bulb_lantern_pink": "Lanterna bulbo rosa de Terminita", + "block.betterend.terminite_bulb_lantern_purple": "Lanterna bulbo púrpura de Terminita", + "block.betterend.terminite_bulb_lantern_red": "Lanterna bulbo vermelha de Terminita", + "block.betterend.terminite_bulb_lantern_white": "Lanterna bulbo branca de Terminita", + "block.betterend.terminite_bulb_lantern_yellow": "Lanterna bulbo amarela de Terminita", + + "block.betterend.terminite_chain": "Corrente de Terminita", + "block.betterend.terminite_chandelier": "Lustre de Terminita", + "block.betterend.terminite_door": "Porta de Terminita", + "block.betterend.terminite_plate": "Placa de pressão de Terminita", + "block.betterend.terminite_slab": "Laje de Terminita", + "block.betterend.terminite_stairs": "Escadas de Terminita", + "block.betterend.terminite_tile": "Terminita Lapidado", + "block.betterend.terminite_trapdoor": "Alçapão de Terminita", + "item.betterend.terminite_nugget": "Pepita de Terminita", + "item.betterend.thallasium_boots": "Botas de Thallasio", + "item.betterend.thallasium_chestplate": "Peitoral de Thallasio", + "item.betterend.thallasium_hammer": "Martelo de Thallasio", + "item.betterend.thallasium_helmet": "Capacete de Thallasio", + "item.betterend.thallasium_leggings": "Calças de Thallasio", + "block.betterend.missing_tile": "Ladrilho Ausente", + "block.betterend.charcoal_block": "Bloco de carvão", + "block.betterend.end_stone_furnace": "Fonalha de Pedra do End", + "block.betterend.flavolite_furnace": "Fornalha de Flavolito", + "block.betterend.sulphuric_rock_furnace": "Fornalha de Rocha Sulfúrica", + "block.betterend.violecite_furnace": "Fornalha de Violecita", + + "item.betterend.terminite_axe_head": "Cabeça de machado de Terminita", + "item.betterend.terminite_hoe_head": "Cabeça de enxada de Terminita", + "item.betterend.terminite_pickaxe_head": "Cabeça de picareta Terminita", + "item.betterend.terminite_shovel_head": "Cabeça de pá de Terminita", + "item.betterend.terminite_sword_blade": "Lâmina de espada de Terminita", + "item.betterend.terminite_sword_handle": "Punho de espada de Terminita", + "item.betterend.thallasium_axe_head": "Cabeça de machado de Thallasio", + "item.betterend.thallasium_hoe_head": "Cabeça de enxada de Thallasio", + "item.betterend.thallasium_pickaxe_head": "cabeça de picareta de Thallasio", + "item.betterend.thallasium_shovel_head": "Cabeça de pá de Thallasio", + "item.betterend.thallasium_sword_blade": "Punho de espada de Thallasio", + "item.betterend.thallasium_sword_handle": "Punho de espada de Thallasio", + "block.betterend.aeternium_anvil": "Bigorna de Aeternio", + + "biome.betterend.dragon_graveyards": "Cemitérios de Dragão", + "biome.betterend.dry_shrubland": "Arbusto Seco", + "block.betterend.aeridium": "Aeridio", + "block.betterend.amaranita_cap": "Copa de Amaranita", + "block.betterend.amaranita_fur": "Pelagem de Amaranita", + "block.betterend.amaranita_hymenophore": "Himenóforo de Amaranita", + "block.betterend.amaranita_hyphae": "Hifas de Amaranita", + "block.betterend.amaranita_lantern": "Lanterna de Amaranita", + "block.betterend.amaranita_stem": "Caule de Amaranita", + "block.betterend.clawfern": "Samambaia Gatázios", + "block.betterend.globulagus": "Globulagus", + "block.betterend.lamellarium": "Lamellario", + "block.betterend.large_amaranita_mushroom": "Cogumelo grande de Amaranita", + "block.betterend.lutebus": "Lutebus", + "block.betterend.mossy_bone": "Osso Musgoso", + "block.betterend.mossy_obsidian": "Obsidiana Musgosa", + "block.betterend.orango": "Laranjo", + "block.betterend.rutiscus": "Rutiscus", + "block.betterend.rutiscus_path": "Caminho de Rutiscus", + "block.betterend.sangnum": "Sangno", + "block.betterend.sangnum_path": "Caminho de Sangno", + "block.betterend.small_amaranita_mushroom": "Cogumelo pequeno de Amaranita", + + "block.betterend.amber_root_seed": "Semente de Raiz Âmbar", + "block.betterend.azure_jadestone": "Azure Jadestone", + "block.betterend.azure_jadestone_bricks": "Tijolos de Pedra jade azure", + "block.betterend.azure_jadestone_bricks_slab": "Laje de tijolos de Pedra Jade Azure", + "block.betterend.azure_jadestone_bricks_stairs": "Escadas de tijolos de Pedra Jade Azure", + "block.betterend.azure_jadestone_bricks_wall": "Muro de tijolos de Pedra Jade Azure", + "block.betterend.azure_jadestone_button": "Botão de Pedra Jade Azure", + "block.betterend.azure_jadestone_furnace": "Fornalha de Pedra Jade Azure", + "block.betterend.azure_jadestone_lantern": "Lanterna de Pedra Jade Azure", + "block.betterend.azure_jadestone_pedestal": "Pedestal de Pedra Jade Azure", + "block.betterend.azure_jadestone_pillar": "Pilar de Pedra Jade Azure", + "block.betterend.azure_jadestone_plate": "Placa de pressão de Pedra Jade Azure", + "block.betterend.azure_jadestone_polished": "Pedra Jade Azure polida", + "block.betterend.azure_jadestone_slab": "Laje de Pedra Jade Azure", + "block.betterend.azure_jadestone_stairs": "Escadas de Pedra Jade Azure", + "block.betterend.azure_jadestone_tiles": "Pedra Jade Azure lapidada", + "block.betterend.azure_jadestone_wall": "Muro de Pedra Jade Azure", + "block.betterend.chorus_mushroom_seed": "Semente de Cogumelo do coro", + "block.betterend.end_stone_stalactite": "Estalactite de Pedra do End", + "block.betterend.end_stone_stalactite_cavemoss": "Estalactite de Pedra do End de Musgo Cavernoso", + "block.betterend.pearlberry_seed": "Semente de Pérola", + "block.betterend.rubinea": "Rubinea", + "block.betterend.sandy_jadestone": "Pedra de Jade Arenosa", + "block.betterend.sandy_jadestone_bricks": "Tijolos de Pedra de Jade Arenosa", + "block.betterend.sandy_jadestone_bricks_slab": "Laje de tijolos de Pedra de Jade Arenosa", + "block.betterend.sandy_jadestone_bricks_stairs": "Escadas de tijolos de Pedra de Jade Arenosa", + "block.betterend.sandy_jadestone_bricks_wall": "Muro de tijolos de Pedra de Jade Arenosa", + "block.betterend.sandy_jadestone_button": "Botão de Pedra de Jade Arenosa", + "block.betterend.sandy_jadestone_furnace": "Fornalha de Pedra de Jade Arenosa", + "block.betterend.sandy_jadestone_lantern": "Lanterna de Pedra de Jade Arenosa", + "block.betterend.sandy_jadestone_pedestal": "Pedestal de Pedra de Jade Arenosa", + "block.betterend.sandy_jadestone_pillar": "Pilar de Pedra de Jade Arenosa", + "block.betterend.sandy_jadestone_plate": "Placa de pressão de Pedra de Jade Arenosa", + "block.betterend.sandy_jadestone_polished": "Pedra de Jade Arenosa polida", + "block.betterend.sandy_jadestone_slab": "Laje de Pedra de Jade Arenosa", + "block.betterend.sandy_jadestone_stairs": "Escadas de Pedra de Jade Arenosa", + "block.betterend.sandy_jadestone_tiles": "Pedra de Jade Arenosa lapidada", + "block.betterend.sandy_jadestone_wall": "Muro de Pedra de Jade Arenosa", + + "block.betterend.smaragdant_crystal": "Cristal Esmaragdante", + "block.betterend.smaragdant_crystal_shard": "Fragmento de cristal de Esmaragdante", + + "block.betterend.virid_jadestone": "Pedra de Jade Viride", + "block.betterend.virid_jadestone_bricks": "Tijolos de Pedra de Jade Viride", + "block.betterend.virid_jadestone_bricks_slab": "Laje de tijolos de Pedra de Jade Viride", + "block.betterend.virid_jadestone_bricks_stairs": "Escadas de tijolos de Pedra de Jade Viride", + "block.betterend.virid_jadestone_bricks_wall": "Muro de tijolos de Pedra de Jade Viride", + "block.betterend.virid_jadestone_button": "Botão de Pedra de Jade Viride", + "block.betterend.virid_jadestone_furnace": "Fornalha de Pedra de Jade Viride", + "block.betterend.virid_jadestone_lantern": "Lanterna de Pedra de Jade Viride", + "block.betterend.virid_jadestone_pedestal": "Pedestal de Pedra de Jade Viride", + "block.betterend.virid_jadestone_pillar": "Pilar de Pedra de Jade Viride", + "block.betterend.virid_jadestone_plate": "Placa de pressão de Pedra de Jade Viride", + "block.betterend.virid_jadestone_polished": "Pedra de Jade Viride polida", + "block.betterend.virid_jadestone_slab": "Laje de Pedra de Jade Viride", + "block.betterend.virid_jadestone_stairs": "Escadas de Pedra de Jade Viride", + "block.betterend.virid_jadestone_tiles": "Pedra de Jade Viride lapidada", + "block.betterend.virid_jadestone_wall": "Muro de Pedra de Jade Viride", + + "item.betterend.amber_root_raw": "Raiz de Âmbar crua", + "item.betterend.chorus_mushroom_cooked": "Cogumelo do Coro cozido", + "item.betterend.chorus_mushroom_raw": "Cogumelo do Coro cru", + + "biome.betterend.empty_aurora_cave": "Caverna Aurora Vazia", + "biome.betterend.empty_end_cave": "Caverna do End Vazia", + "biome.betterend.empty_smaragdant_cave": "Caverna Exuberante de Esmaragdante Vazia", + "biome.betterend.lush_aurora_cave": "Caverna Exuberante de Aurora", + "biome.betterend.lush_smaragdant_cave": "Caverna Exuberante de Esmaragdante", + + "block.betterend.dragon_bone_block": "Bloco de Osso de Dragão", + "block.betterend.dragon_bone_slab": "Laje de Osso de Dragão", + "block.betterend.dragon_bone_stairs": "Escadas de Osso de Dragão", + "block.betterend.mossy_dragon_bone": "Osso de Dragão musgoso", + + "biome.betterend.lantern_woods": "Madeiras Lanterna", + "block.betterend.filalux": "Filaluxe", + "block.betterend.filalux_lantern": "Laterna de Filaluxe", + "block.betterend.filalux_wings": "Asas-de-Filaluxe", + "block.betterend.lucernia_bark": "Madeira de Lucernia", + "block.betterend.lucernia_barrel": "Barril de Lucernia", + "block.betterend.lucernia_bookshelf": "Estante de livros de Lucernia", + "block.betterend.lucernia_button": "botão de Lucernia", + "block.betterend.lucernia_chest": "Baú de Lucernia", + "block.betterend.lucernia_composter": "Compesteira de Lucernia", + "block.betterend.lucernia_crafting_table": "Bancada de Trabalho de Lucernia", + "block.betterend.lucernia_door": "Porta de Lucernia", + "block.betterend.lucernia_fence": "Cerca de Lucernia", + "block.betterend.lucernia_gate": "Portão de Lucernia", + "block.betterend.lucernia_ladder": "Escada de mão de Lucernia", + "block.betterend.lucernia_leaves": "Folhas de Lucernia", + "block.betterend.lucernia_log": "Tronco de Lucernia", + "block.betterend.lucernia_outer_leaves": "Folhas Exteriores de Lucernia", + "block.betterend.lucernia_planks": "Tábuas de Lucernia", + "block.betterend.lucernia_plate": "Placa de pressão de Lucernia", + "block.betterend.lucernia_sapling": "Muda de Lucernia", + "block.betterend.lucernia_sign": "Placa de Lucernia", + "block.betterend.lucernia_slab": "Laje de Lucernia", + "block.betterend.lucernia_stairs": "Escadas de Lucernia", + "block.betterend.lucernia_stripped_bark": "Madeira de Lucernia descascada", + "block.betterend.lucernia_stripped_log": "Tronco de Lucernia descascado", + "block.betterend.lucernia_trapdoor": "Alçapão de Lucernia", + + "block.betterend.aurant_polypore": "Poliporo Aurante", + "block.betterend.bolux_mushroom": "Cogumelo Boluxe", + "block.betterend.flamaea": "Flamaea", + "block.betterend.pond_anemone": "Anêmona de lago", + "block.betterend.ruscus": "Ruscus", + "item.betterend.bolux_mushroom_cooked": "Cogumelo Boluxe cozido", + + "block.betterend.silk_moth_hive": "Colmeia de Mariposa de Seda", + "item.betterend.silk_moth_matrix": "Matriz de Mariposa de Seda", + + "biome.betterend.neon_oasis": "Oasis Neon", + "block.betterend.cave_pumpkin": "Abóbora de Caverna", + "block.betterend.cave_pumpkin_seed": "Sementes de Abóbora de Caverna", + "block.betterend.magnula": "Magnula", + "block.betterend.neon_cactus": "Cacto Neon", + "item.betterend.cave_pumpkin_pie": "Torta de Abóbora de Caverna", + + "item.betterend.music_disc_strange_and_alien": "§bDisco de Música§r", + "item.betterend.music_disc_strange_and_alien.desc": "§5Firel§r - §fEstranho e Alienígena§r", + "item.betterend.music_disc_grasping_at_stars": "§bDisco de Música§r", + "item.betterend.music_disc_grasping_at_stars.desc": "§5Firel§r - §fAgarrando-se às Estrelas§r", + "item.betterend.music_disc_endseeker": "§bDisco de Música§r", + "item.betterend.music_disc_endseeker.desc": "§5Firel§r - §fCaçador do End§r", + "item.betterend.music_disc_eo_dracona": "§bDisco de Música§r", + "item.betterend.music_disc_eo_dracona.desc": "§5Firel§r - §fEo Dracona§r", + + "block.betterend.hydralux_petal_block_amber": "Bloco de Pétalas Âmbar", + "block.betterend.hydralux_petal_block_beige": "Bloco de pétalas bege", + "block.betterend.hydralux_petal_block_cream": "Bloco de pétalas creme", + "block.betterend.hydralux_petal_block_dark_green": "Bloco de pétalas verde-escuro", + "block.betterend.hydralux_petal_block_forest_green": "Bloco de pétalas verde-floresta", + "block.betterend.hydralux_petal_block_hot_pink": "Bloco de pétalas rosa-quente", + "block.betterend.hydralux_petal_block_indigo": "Bloco de pétalas indigo", + "block.betterend.hydralux_petal_block_maroon": "Bloco de pétalas maroon", + "block.betterend.hydralux_petal_block_navy": "Bloco de pétalas marinho", + "block.betterend.hydralux_petal_block_olive": "Bloco de pétalas oliva", + "block.betterend.hydralux_petal_block_pale_green": "Bloco de pétalas verde-pálido", + "block.betterend.hydralux_petal_block_pale_pink": "Bloco de pétalas rosa-pálido", + "block.betterend.hydralux_petal_block_pale_yellow": "Bloco de pétalas amerelo-pálido", + "block.betterend.hydralux_petal_block_sky_blue": "Bloco de pétalas céu-azul", + "block.betterend.hydralux_petal_block_slate_gray": "Bloco de pétalas ardósia-cinza", + "block.betterend.hydralux_petal_block_violet": "Bloco de pétalas violeta", + + "block.betterend.smaragdant_crystal_bricks": "Tijolos de Esmaragdante", + "block.betterend.smaragdant_crystal_bricks_slab": "Laje de tijolos de Esmaragdante", + "block.betterend.smaragdant_crystal_bricks_stairs": "Escadas de tijolos de Esmaragdante", + "block.betterend.smaragdant_crystal_bricks_wall": "Muro de tijolos de Esmaragdante", + "block.betterend.smaragdant_crystal_pedestal": "Pedestal de Esmaragdante", + "block.betterend.smaragdant_crystal_pillar": "Pilar de Esmaragdante", + "block.betterend.smaragdant_crystal_polished": "Esmaragdante Polido", + "block.betterend.smaragdant_crystal_slab": "Laje de Esmaragdante", + "block.betterend.smaragdant_crystal_stairs": "Escadas de Esmaragdante", + "block.betterend.smaragdant_crystal_tiles": "Esmaragdante lapidado", + "block.betterend.smaragdant_crystal_wall": "Muro de Esmaragdante", + "message.betterend.anvil_damage": "§cDano", + + "block.betterend.neon_cactus_block": "Bloco de Cacto Neon", + "block.betterend.neon_cactus_slab": "Laje de Cacto Neon", + "block.betterend.neon_cactus_stairs": "Escadas de Cacto Neon", + "biome.betterend.jade_cave": "Caverna de Jade", + "item.betterend.blossom_berry_jelly": "Geléia de baga de flor", + "item.betterend.aeternium_forged_plate": "Placa forjada de Aeternio", + "item.betterend.terminite_forged_plate": "Placa forjada de Terminita", + "item.betterend.thallasium_forged_plate": "Placa forjada de Thallasio", + + "attribute.name.generic.blindness_resistance": "Resistência à cegueira", + + "tooltip.armor.crystalite_set": "Conjunto de bônus: Regeneração I", + "tooltip.armor.crystalite_chest": "Efeito: Velocidade de escavação I", + "tooltip.armor.crystalite_boots": "Efeito: Velocidade I", + + "block.betterend.azure_jadestone_flower_pot": "Vaso de flor de Pedra de Jade Azure", + "block.betterend.endstone_flower_pot": "Vaso de flor de Pedra do End", + "block.betterend.flavolite_flower_pot": "Vaso de flor de Flavolito", + "block.betterend.sandy_jadestone_flower_pot": "Vaso de flor de Pedra de Jade Arenosa", + "block.betterend.sulphuric_rock_flower_pot": "Vaso de flor de Rocha Sulfúrica", + "block.betterend.violecite_flower_pot": "Vaso de flor de Violecita", + "block.betterend.virid_jadestone_flower_pot": "Vaso de flor de Pedra de Jade Viride", + "block.betterend.virid_jadestone_flower_pot": "Vaso de flor de Pedra de Jade Viride", + + "block.betterend.umbralith": "Umbralite", + "block.betterend.umbralith_bricks": "Tijolos de Umbralite", + "block.betterend.umbralith_bricks_slab": "Laje de tijolos de Umbralite", + "block.betterend.umbralith_bricks_stairs": "Escadas de tijolos de Umbralite", + "block.betterend.umbralith_bricks_wall": "Muro de tijolos de Umbralite", + "block.betterend.umbralith_button": "Botão de Umbralite", + "block.betterend.umbralith_flower_pot": "Vaso de flores de Umbralite", + "block.betterend.umbralith_furnace": "Fornalha de Umbralite", + "block.betterend.umbralith_lantern": "Lanterna de Umbralite", + "block.betterend.umbralith_pedestal": "Pesdestal de Umbralite", + "block.betterend.umbralith_pillar": "Pilar de Umbralite", + "block.betterend.umbralith_plate": "Placa de pressão de Umbralite", + "block.betterend.umbralith_polished": "Umbralite Polido", + "block.betterend.umbralith_slab": "Laje de Umbralite", + "block.betterend.umbralith_stairs": "Escadas de Umbralite", + "block.betterend.umbralith_tiles": "Umbralite Lapido", + "block.betterend.umbralith_wall": "Muro de Umbralite", + + "biome.betterend.umbra_valley": "Vale Da Sombra", + "block.betterend.inflexia": "Inflexia", + "block.betterend.pallidium_full": "Pallidio (Cobertura completa)", + "block.betterend.pallidium_heavy": "Pallidio (Cobertura pesada)", + "block.betterend.pallidium_thin": "Pallidio (Cobertuna fina)", + "block.betterend.pallidium_tiny": "Pallidio (Cobertura dispersada)", + "block.betterend.flammalix": "Flammalixe" +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/lang/ru_ru.json b/src/main/resources/assets/betterend/lang/ru_ru.json index 1db5508b..20608acc 100644 --- a/src/main/resources/assets/betterend/lang/ru_ru.json +++ b/src/main/resources/assets/betterend/lang/ru_ru.json @@ -13,7 +13,7 @@ "biome.betterend.dust_wastelands": "Пыльные пустоши", "biome.betterend.chorus_forest": "Хорусовый лес", "biome.betterend.megalake": "Мегаозеро", - "biome.betterend.crystal_mountains": "Клисталлические горы", + "biome.betterend.crystal_mountains": "Кристаллические горы", "entity.betterend.dragonfly": "Стрекоза", "item.betterend.spawn_egg_dragonfly": "Яйцо призыва стрекозы", @@ -125,7 +125,7 @@ "block.betterend.dense_vine": "Плотная лоза", "block.betterend.bubble_coral": "Пузырчатый коралл", "block.betterend.aurora_crystal": "Кристалл авроры", - "item.betterend.crystal_shards": "Осколки кристаллов", + "item.betterend.crystal_shards": "Осколки кристаллов авроры", "block.betterend.pythadendron_sapling": "Саженец пифадендрона", "block.betterend.pythadendron_bark": "Кора пифадендрона", @@ -174,7 +174,7 @@ "block.betterend.flavolite": "Флаволит", "block.betterend.flavolite_bricks": "Флаволитовые кирпичи", "block.betterend.flavolite_bricks_slab": "Плита из флаволитовых кирпичей", - "block.betterend.flavolite_bricks_stairs": "Сутупени из флаволитовых кирпичей", + "block.betterend.flavolite_bricks_stairs": "Ступени из флаволитовых кирпичей", "block.betterend.flavolite_bricks_wall": "Стена из флаволитовых кирпичей", "block.betterend.flavolite_button": "Флаволитовая кнопка", "block.betterend.flavolite_pillar": "Флаволитовая колонна", @@ -573,7 +573,7 @@ "block.betterend.twisted_umbrella_moss": "Закрученный зонтичный мох", "block.betterend.twisted_umbrella_moss_tall": "Высокий закрученный зонтичный мох", "block.betterend.umbrella_tree_cluster": "Кластер зонтичного дерева", - "block.betterend.umbrella_tree_cluster_empty": "Пустой кластер хонтичного дерева", + "block.betterend.umbrella_tree_cluster_empty": "Пустой кластер зонтичного дерева", "block.betterend.jungle_vine": "Лоза джунглей", "block.betterend.jungle_fern": "Папоротник джунглей", @@ -618,6 +618,7 @@ "item.betterend.silk_fiber": "Шёлковое волокно", "item.betterend.spawn_egg_silk_moth": "Яйцо призыва шелковичной моли", + "item.betterend.thallasium_raw": "Необработанный талласий", "block.betterend.thallasium_ore": "Талласиевая руда", "item.betterend.thallasium_axe": "Талласиевый топор", "item.betterend.thallasium_hoe": "Талласиевая мотыга", @@ -859,7 +860,7 @@ "block.betterend.hydralux_petal_block_pale_green": "Бледно-зеленый блок лепестков", "block.betterend.hydralux_petal_block_pale_pink": "Бледно-розовый блок лепестков", "block.betterend.hydralux_petal_block_pale_yellow": "Бледно-жёлтый блок лепестков", - "block.betterend.hydralux_petal_block_sky_blue": "Неьесно-голубой блок лепестков", + "block.betterend.hydralux_petal_block_sky_blue": "Небесно-голубой блок лепестков", "block.betterend.hydralux_petal_block_slate_gray": "Сланцево-серый блок лепестков", "block.betterend.hydralux_petal_block_violet": "Лиловый блок лепестков", @@ -889,5 +890,39 @@ "tooltip.armor.crystalite_set": "Бонус сета: Регенерация I", "tooltip.armor.crystalite_chest": "Эффект: Ускорение I", - "tooltip.armor.crystalite_boots": "Эффект: Стремительность I" -} \ No newline at end of file + "tooltip.armor.crystalite_boots": "Эффект: Стремительность I", + + "block.betterend.azure_jadestone_flower_pot": "Цветочный горшок из лазурного нефрита", + "block.betterend.endstone_flower_pot": "Цветочный горшок из эндерняка", + "block.betterend.flavolite_flower_pot": "Цветочный горшок из флаволита", + "block.betterend.sandy_jadestone_flower_pot": "Цветочный горшок из песчаного нефрита", + "block.betterend.sulphuric_rock_flower_pot": "Цветочный горшок из серного камня", + "block.betterend.violecite_flower_pot": "Цветочный горшок из виолецита", + "block.betterend.virid_jadestone_flower_pot": "Цветочный горшок из зелёного нефрита", + + "block.betterend.umbralith": "Умбралит", + "block.betterend.umbralith_bricks": "Умбралитовые кирпичи", + "block.betterend.umbralith_bricks_slab": "Плита из умбралитовых кирпичей", + "block.betterend.umbralith_bricks_stairs": "Ступени из умбралитовых кирпичей", + "block.betterend.umbralith_bricks_wall": "Стена из умбралитовых кирпичей", + "block.betterend.umbralith_button": "Умбралитовая кнопка", + "block.betterend.umbralith_flower_pot": "Умбралитовый горшок", + "block.betterend.umbralith_furnace": "Умбралитовая печь", + "block.betterend.umbralith_lantern": "Умбралитовый фонарь", + "block.betterend.umbralith_pedestal": "Умбралитовый пьедестал", + "block.betterend.umbralith_pillar": "Умбралитовая колонна", + "block.betterend.umbralith_plate": "Умбралитовая нажимная плита", + "block.betterend.umbralith_polished": "Полированный умбралит", + "block.betterend.umbralith_slab": "Умбралитовая плита", + "block.betterend.umbralith_stairs": "Умбралитовые ступени", + "block.betterend.umbralith_tiles": "Умбралитовая плитка", + "block.betterend.umbralith_wall": "Умбралитовая стена", + + "biome.betterend.umbra_valley": "Долина Умбра", + "block.betterend.inflexia": "Инфлексия", + "block.betterend.pallidium_full": "Паллидиум (полное покрытие)", + "block.betterend.pallidium_heavy": "Паллидиум (густое покрытие)", + "block.betterend.pallidium_thin": "Паллидиум (тонкое покрытие)", + "block.betterend.pallidium_tiny": "Паллидиум (маленькое покрытие)", + "block.betterend.flammalix": "Фламмаликс" +} diff --git a/src/main/resources/assets/betterend/lang/thai_th.json b/src/main/resources/assets/betterend/lang/thai_th.json new file mode 100644 index 00000000..b9bb7c9e --- /dev/null +++ b/src/main/resources/assets/betterend/lang/thai_th.json @@ -0,0 +1,821 @@ +{ + "itemGroup.betterend.end_items": "จุดจบที่ดีกว่า: ไอเท่ม", + "itemGroup.betterend.end_blocks": "จุดจบที่ดีกว่า: บล็อก", + "item.betterend.guidebook": "The End for Dummies", + "book.betterend.landing": "คำแนะนำสั้น ๆ เกี่ยวกับการเอาชีวิตรอดในสภาวะสุดขั้วของ The End.", + "book.betterend.subtitle": "เอาชีวิตรอด ใน The End", + "category.rei.damage.amount&dmg": "ดาเมจ เครื่องมือ: %s", + "category.rei.infusion.time&val": "เวลา: %s", + "biome.betterend.foggy_mushroomland": "ป่าต้นเห็ด ดินแดนกบ", + "biome.betterend.dust_wastelands": "ดินแดนฝุ่น", + "biome.betterend.chorus_forest": "ป่าคอรัส", + "biome.betterend.megalake": "หนองน้ำ เมก้าเลค", + "biome.betterend.crystal_mountains": "หุบเขา คลิสตั่ล", + "entity.betterend.dragonfly": "แมลงปอ", + "item.betterend.spawn_egg_dragonfly": "ไข่แมลงปอ", + "entity.betterend.end_slime": "End Slime", + "item.betterend.spawn_egg_end_slime": "ไข่ สไลม์ ", + "block.betterend.end_mycelium": "เอ็นด์ เชื้อรา", + "block.betterend.end_moss": "End มอสส์", + "block.betterend.endstone_dust": "End ฝุ่นผง", + "block.betterend.end_mycelium_path": "End เชื้อรา แบบทางเดิน", + "block.betterend.end_moss_path": "End มอสส์ ทางเดิน", + "block.betterend.ender_ore": "เอ็นเดอร์ แร่", + "block.betterend.terminite_block": "เทอร์มิไนท์ บล็อค", + "block.betterend.aeternium_block": "เอเทอร์เรี่ยม บล็อค", + "block.betterend.ender_block": "เอ็นเดอร์ บล็อค", + "block.betterend.end_stone_smelter": "End Stone Smelter", + "item.betterend.ender_dust": "ผงเอ็นเดอร์", + "item.betterend.ender_shard": "เอ็นเเอร์ ชาดร์", + "item.betterend.terminite_ingot": "เทอร์มิไนท์ ก้อน", + "item.betterend.aeternium_ingot": "เอเทอร์เรี่ยม", + "item.betterend.terminite_helmet": "Terminite Helmet", + "item.betterend.terminite_chestplate": "Terminite Chestplate", + "item.betterend.terminite_leggings": "Terminite Leggings", + "item.betterend.terminite_boots": "Terminite Boots", + "item.betterend.terminite_shovel": "ที่ขุดดิน เทอร์มิไนท์", + "item.betterend.terminite_sword": "ดาบเทอร์มิไนท์", + "item.betterend.terminite_pickaxe": "ที่ขุดเทอร์มิไนท์", + "item.betterend.terminite_axe": "ขวาน เทอร์มิไนท์", + "item.betterend.terminite_hoe": "จอบเทอร์มิไนท์", + "item.betterend.terminite_hammer": "Terminite Smith Hammer", + "item.betterend.aeternium_helmet": "Aeternium Helmet", + "item.betterend.aeternium_chestplate": "Aeternium Chestplate", + "item.betterend.aeternium_leggings": "Aeternium Leggings", + "item.betterend.aeternium_boots": "Aeternium Boots", + "item.betterend.aeternium_shovel": "Aeternium Shovel", + "item.betterend.aeternium_sword": "Aeternium Sword", + "item.betterend.aeternium_pickaxe": "Aeternium Pickaxe", + "item.betterend.aeternium_axe": "Aeternium Axe", + "item.betterend.aeternium_hoe": "Aeternium Hoe", + "item.betterend.aeternium_hammer": "Aeternium Smith Hammer", + "item.betterend.iron_hammer": "Iron Smith Hammer", + "item.betterend.golden_hammer": "Golden Smith Hammer", + "item.betterend.diamond_hammer": "Diamond Smith Hammer", + "item.betterend.netherite_hammer": "Netherite Smith Hammer", + "item.betterend.crystalite_boots": "Crystalite Boots", + "item.betterend.crystalite_chestplate": "Crystalite Chestplate", + "item.betterend.crystalite_helmet": "Crystalite Helmet", + "item.betterend.crystalite_leggings": "Crystalite Leggings", + "item.betterend.aeternium_axe_head": "Aeternium Axe Head", + "item.betterend.aeternium_hammer_head": "Aeternium Hammer Head", + "item.betterend.aeternium_hoe_head": "Aeternium Hoe Head", + "item.betterend.aeternium_pickaxe_head": "Aeternium Pickaxe Head", + "item.betterend.aeternium_shovel_head": "Aeternium Shovel Head", + "item.betterend.aeternium_sword_blade": "Aeternium Sword Blade", + "item.betterend.aeternium_sword_handle": "Aeternium Sword Handle", + "item.betterend.leather_stripe": "Leather Stripe", + "item.betterend.leather_wrapped_stick": "Leather Wrapped Stick", + "item.betterend.elytra_armored": "เอ็มมอเล็ท ปีก", + "item.betterend.elytra_crystalite": "ปีก คลิสตั่ล", + "item.betterend.enchanted_membrane": "Enchanted Membrane", + "effect.betterend.end_veil": "End Veil", + "enchantment.betterend.end_veil": "End Veil", + "item.minecraft.potion.effect.end_veil": "Potion Of End Veil", + "item.minecraft.potion.effect.long_end_veil": "Potion Of End Veil", + "item.minecraft.splash_potion.effect.end_veil": "Splash Potion Of End Veil", + "item.minecraft.splash_potion.effect.long_end_veil": "Splash Potion Of End Veil", + "item.minecraft.lingering_potion.effect.end_veil": "Lingering Potion Of End Veil", + "item.minecraft.lingering_potion.effect.long_end_veil": "Lingering Potion Of End Veil", + "item.minecraft.tipped_arrow.effect.end_veil": "Arrow Of End Veil", + "item.minecraft.tipped_arrow.effect.long_end_veil": "Arrow Of End Veil", + "block.betterend.mossy_glowshroom_sapling": "ต้นออน่ เห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_cap": "เห็ดเรืองแสง หมวก", + "block.betterend.mossy_glowshroom_fur": "เห็ดเรืองแสง ขน", + "block.betterend.mossy_glowshroom_hymenophore": "เห็ดเรืองแสง Hymenophore", + "block.betterend.mossy_glowshroom_bark": "เห็ดเรืองแสง เห่า", + "block.betterend.mossy_glowshroom_barrel": "ถังเห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_button": "ปุ่ม เห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_chest": "หีบ เห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_crafting_table": "โต๊ะคราฟ เห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_door": "ประตูเห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_fence": "รั้วเห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_gate": "ประตูรั้ว เห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_ladder": "บันไดปีนเห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_log": "ตอไม้เห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_planks": "เเผ่นไม้เห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_plate": "ที่เหยียบเห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_sign": "ป้ายเห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_slab": "แสล็บเห็ดเรืองแสง", + "block.betterend.mossy_glowshroom_stairs": "Mossy Glowshroom Stairs", + "block.betterend.mossy_glowshroom_stripped_bark": "Stripped Mossy Glowshroom Bark", + "block.betterend.mossy_glowshroom_stripped_log": "Stripped Mossy Glowshroom Log", + "block.betterend.mossy_glowshroom_trapdoor": "ประตูเล็ก เห็ดเรืองแสง", + "block.betterend.umbrella_moss": "Umbrella Moss", + "block.betterend.umbrella_moss_tall": "Tall Umbrella Moss", + "block.betterend.creeping_moss": "Creeping Moss", + "block.betterend.blue_vine_seed": "Blue Vine Seed", + "block.betterend.blue_vine": "Blue Vine", + "block.betterend.blue_vine_lantern": "Blue Vine Lantern", + "block.betterend.blue_vine_fur": "Blue Vine Fur", + "block.betterend.dense_vine": "Dense Vine", + "block.betterend.bubble_coral": "Bubble Coral", + "block.betterend.aurora_crystal": "Aurora Crystal", + "item.betterend.crystal_shards": "Aurora Crystal Shards", + "block.betterend.pythadendron_sapling": "Pythadendron Sapling", + "block.betterend.pythadendron_bark": "Pythadendron Bark", + "block.betterend.pythadendron_barrel": "Pythadendron Barrel", + "block.betterend.pythadendron_button": "Pythadendron Button", + "block.betterend.pythadendron_chest": "Pythadendron Chest", + "block.betterend.pythadendron_crafting_table": "Pythadendron Crafting Table", + "block.betterend.pythadendron_door": "Pythadendron Door", + "block.betterend.pythadendron_fence": "Pythadendron Fence", + "block.betterend.pythadendron_gate": "Pythadendron Gate", + "block.betterend.pythadendron_ladder": "Pythadendron Ladder", + "block.betterend.pythadendron_log": "Pythadendron Log", + "block.betterend.pythadendron_planks": "Pythadendron Planks", + "block.betterend.pythadendron_plate": "Pythadendron Pressure Plate", + "block.betterend.pythadendron_sign": "Pythadendron Sign", + "block.betterend.pythadendron_slab": "Pythadendron Slab", + "block.betterend.pythadendron_stairs": "Pythadendron Stairs", + "block.betterend.pythadendron_stripped_bark": "Stripped Pythadendron Bark", + "block.betterend.pythadendron_stripped_log": "Stripped Pythadendron Log", + "block.betterend.pythadendron_trapdoor": "Pythadendron Trapdoor", + "block.betterend.chorus_nylium": "Chorus Nylium", + "block.betterend.chorus_nylium_path": "Chorus Nylium Path", + "block.betterend.chorus_grass": "Chorus Grass", + "block.betterend.end_lily": "End Lily", + "block.betterend.end_lily_seed": "End Lily Seed", + "item.betterend.end_lily_leaf": "End Lily Leaf", + "item.betterend.end_lily_leaf_dried": "End Lily Leaf Dried", + "block.betterend.violecite": "Violecite", + "block.betterend.violecite_bricks": "Violecite Bricks", + "block.betterend.violecite_bricks_slab": "Violecite Brick Slab", + "block.betterend.violecite_bricks_stairs": "Violecite Brick Stairs", + "block.betterend.violecite_bricks_wall": "Violecite Brick Wall", + "block.betterend.violecite_button": "Violecite Button", + "block.betterend.violecite_pillar": "Violecite Pillar", + "block.betterend.violecite_plate": "Violecite Pressure Plate", + "block.betterend.violecite_slab": "Violecite Slab", + "block.betterend.violecite_tiles": "Violecite Tiles", + "block.betterend.violecite_stairs": "Violecite Stairs", + "block.betterend.violecite_polished": "Polished Violecite", + "block.betterend.violecite_wall": "Violecite Wall", + "block.betterend.violecite_pedestal": "Violecite Pedestal", + "block.betterend.flavolite": "Flavolite", + "block.betterend.flavolite_bricks": "Flavolite Bricks", + "block.betterend.flavolite_bricks_slab": "Flavolite Brick Slab", + "block.betterend.flavolite_bricks_stairs": "Flavolite Brick Stairs", + "block.betterend.flavolite_bricks_wall": "Flavolite Brick Wall", + "block.betterend.flavolite_button": "Flavolite Button", + "block.betterend.flavolite_pillar": "Flavolite Pillar", + "block.betterend.flavolite_plate": "Flavolite Pressure Plate", + "block.betterend.flavolite_slab": "Flavolite Slab", + "block.betterend.flavolite_tiles": "Flavolite Tiles", + "block.betterend.flavolite_stairs": "Flavolite Stairs", + "block.betterend.flavolite_polished": "Polished Flavolite", + "block.betterend.flavolite_wall": "Flavolite Wall", + "block.betterend.flavolite_pedestal": "Flavolite Pedestal", + "block.betterend.andesite_pedestal": "Andesite Pedestal", + "block.betterend.diorite_pedestal": "Diorite Pedestal", + "block.betterend.granite_pedestal": "Granite Pedestal", + "block.betterend.purpur_pedestal": "Purpur Pedestal", + "block.betterend.quartz_pedestal": "Quartz Pedestal", + "block.betterend.infusion_pedestal": "Infusion Pedestal", + "block.betterend.end_lotus_seed": "End Lotus Seed", + "block.betterend.end_lotus_stem": "End Lotus Stem", + "block.betterend.end_lotus_leaf": "End Lotus Leaf", + "block.betterend.end_lotus_flower": "End Lotus Flower", + "block.betterend.end_lotus_bark": "End Lotus Bark", + "block.betterend.end_lotus_barrel": "End Lotus Barrel", + "block.betterend.end_lotus_button": "End Lotus Button", + "block.betterend.end_lotus_chest": "End Lotus Chest", + "block.betterend.end_lotus_crafting_table": "End Lotus Crafting Table", + "block.betterend.end_lotus_door": "End Lotus Door", + "block.betterend.end_lotus_fence": "End Lotus Fence", + "block.betterend.end_lotus_gate": "End Lotus Gate", + "block.betterend.end_lotus_ladder": "End Lotus Ladder", + "block.betterend.end_lotus_log": "End Lotus Log", + "block.betterend.end_lotus_planks": "End Lotus Planks", + "block.betterend.end_lotus_plate": "End Lotus Pressure Plate", + "block.betterend.end_lotus_sign": "End Lotus Sign", + "block.betterend.end_lotus_slab": "End Lotus Slab", + "block.betterend.end_lotus_stairs": "End Lotus Stairs", + "block.betterend.end_lotus_stripped_bark": "Stripped End Lotus Bark", + "block.betterend.end_lotus_stripped_log": "Stripped End Lotus Log", + "block.betterend.end_lotus_trapdoor": "End Lotus Trapdoor", + "block.betterend.cave_moss": "Cave Moss", + "block.betterend.cave_grass": "Cave Grass", + "block.betterend.cave_bush": "Cave Bush", + "block.betterend.cave_moss_path": "Cave Moss Path", + "block.betterend.crystal_moss": "Crystal Moss", + "block.betterend.crystal_moss_path": "Crystal Moss Path", + "block.betterend.crystal_moss_cover": "Crystal Moss Cover", + "block.betterend.pythadendron_leaves": "Pythadendron Leaves", + "item.betterend.spawn_egg_end_fish": "End Fish Spawn Egg", + "block.betterend.crystal_grass": "Crystal Grass", + "block.betterend.flavolite_runed": "Runed Flavolite", + "block.betterend.end_portal_block": "End Portal", + "block.betterend.eternal_pedestal": "Eternal Pedestal", + "block.betterend.flavolite_runed_eternal": "Eternal Runed Flavolite", + "item.betterend.eternal_crystal": "Eternal Crystal", + "block.betterend.lacugrove_bark": "Lacugrove Bark", + "block.betterend.lacugrove_barrel": "Lacugrove Barrel", + "block.betterend.lacugrove_button": "Lacugrove Button", + "block.betterend.lacugrove_chest": "Lacugrove Chest", + "block.betterend.lacugrove_crafting_table": "Lacugrove Crafting Table", + "block.betterend.lacugrove_door": "Lacugrove Door", + "block.betterend.lacugrove_fence": "Lacugrove Fence", + "block.betterend.lacugrove_gate": "Lacugrove Gate", + "block.betterend.lacugrove_ladder": "Lacugrove Ladder", + "block.betterend.lacugrove_log": "Lacugrove Log", + "block.betterend.lacugrove_planks": "Lacugrove Planks", + "block.betterend.lacugrove_plate": "Lacugrove Pressure Plate", + "block.betterend.lacugrove_sign": "Lacugrove Sign", + "block.betterend.lacugrove_slab": "Lacugrove Slab", + "block.betterend.lacugrove_stairs": "Lacugrove Stairs", + "block.betterend.lacugrove_stripped_bark": "Stripped Lacugrove Bark", + "block.betterend.lacugrove_stripped_log": "Stripped Lacugrove Log", + "block.betterend.lacugrove_trapdoor": "Lacugrove Trapdoor", + "block.betterend.lacugrove_leaves": "Lacugrove Leaves", + "block.betterend.lacugrove_sapling": "Lacugrove Sapling", + "biome.betterend.megalake_grove": "Megalake Grove", + "biome.betterend.painted_mountains": "Painted Mountains", + "block.betterend.dragon_tree_bark": "Dragon Tree Bark", + "block.betterend.dragon_tree_barrel": "Dragon Tree Barrel", + "block.betterend.dragon_tree_button": "Dragon Tree Button", + "block.betterend.dragon_tree_chest": "Dragon Tree Chest", + "block.betterend.dragon_tree_crafting_table": "Dragon Tree Crafting Table", + "block.betterend.dragon_tree_door": "Dragon Tree Door", + "block.betterend.dragon_tree_fence": "Dragon Tree Fence", + "block.betterend.dragon_tree_gate": "Dragon Tree Gate", + "block.betterend.dragon_tree_ladder": "Dragon Tree Ladder", + "block.betterend.dragon_tree_log": "Dragon Tree Log", + "block.betterend.dragon_tree_planks": "Dragon Tree Planks", + "block.betterend.dragon_tree_plate": "Dragon Tree Pressure Plate", + "block.betterend.dragon_tree_sign": "Dragon Tree Sign", + "block.betterend.dragon_tree_slab": "Dragon Tree Slab", + "block.betterend.dragon_tree_stairs": "Dragon Tree Stairs", + "block.betterend.dragon_tree_stripped_bark": "Stripped Dragon Tree Bark", + "block.betterend.dragon_tree_stripped_log": "Stripped Dragon Tree Log", + "block.betterend.dragon_tree_trapdoor": "Dragon Tree Trapdoor", + "biome.betterend.shadow_forest": "Shadow Forest", + "block.betterend.dragon_tree_leaves": "Dragon Tree Leaves", + "block.betterend.dragon_tree_sapling": "Dragon Tree Sapling", + "block.betterend.shadow_grass": "Shadow Grass", + "block.betterend.shadow_grass_path": "Shadow Grass Path", + "block.betterend.shadow_plant": "Shadow Plant", + "block.betterend.dragon_tree_bookshelf": "Dragon Tree Bookshelf", + "block.betterend.end_lotus_bookshelf": "End Lotus Bookshelf", + "block.betterend.lacugrove_bookshelf": "Lacugrove Bookshelf", + "block.betterend.mossy_glowshroom_bookshelf": "Mossy Glowshroom Bookshelf", + "block.betterend.pythadendron_bookshelf": "Pythadendron Bookshelf", + "block.betterend.murkweed": "Murkweed", + "block.betterend.needlegrass": "Needlegrass", + "block.betterend.twisted_vine": "Twisted Vine", + "block.betterend.shadow_berry": "Shadow Berry Seeds", + "item.betterend.shadow_berry_cooked": "Shadow Berry Cooked", + "item.betterend.shadow_berry_raw": "Shadow Berry", + "block.betterend.purple_polypore": "Purple Polypore", + "block.betterend.cyan_moss": "Cyan Moss", + "block.betterend.tail_moss": "Tail Moss", + "block.betterend.flavolite_lantern": "Flavolite Lantern", + "block.betterend.end_stone_lantern": "End Stone Lantern", + "block.betterend.violecite_lantern": "Violecite Lantern", + "entity.betterend.end_fish": "End Fish", + "entity.betterend.shadow_walker": "Shadow Walker", + "item.betterend.spawn_egg_shadow_walker": "Shadow Walker Spawn Egg", + "block.betterend.andesite_lantern": "Andesite Lantern", + "block.betterend.blackstone_lantern": "Blackstone Lantern", + "block.betterend.diorite_lantern": "Diorite Lantern", + "block.betterend.granite_lantern": "Granite Lantern", + "block.betterend.purpur_lantern": "Purpur Lantern", + "block.betterend.quartz_lantern": "Quartz Lantern", + "item.betterend.bucket_end_fish": "Bucket of End Fish", + "item.betterend.bucket_cubozoa": "Bucket of Cubozoa", + "item.betterend.end_fish_cooked": "Cooked End Fish", + "item.betterend.end_fish_raw": "End Fish", + "biome.betterend.amber_land": "Amber Land", + "biome.betterend.blossoming_spires": "Blossoming Spires", + "block.betterend.amber_grass": "Amber Grass", + "block.betterend.amber_grass_path": "Amber Grass Path", + "block.betterend.tenanea_bark": "Tenanea Bark", + "block.betterend.tenanea_barrel": "Tenanea Barrel", + "block.betterend.tenanea_bookshelf": "Tenanea Bookshelf", + "block.betterend.tenanea_button": "Tenanea Button", + "block.betterend.tenanea_chest": "Tenanea Chest", + "block.betterend.tenanea_crafting_table": "Tenanea Crafting Table", + "block.betterend.tenanea_door": "Tenanea Door", + "block.betterend.tenanea_fence": "Tenanea Fence", + "block.betterend.tenanea_gate": "Tenanea Gate", + "block.betterend.tenanea_ladder": "Tenanea Ladder", + "block.betterend.tenanea_leaves": "Tenanea Leaves", + "block.betterend.tenanea_log": "Tenanea Log", + "block.betterend.tenanea_planks": "Tenanea Planks", + "block.betterend.tenanea_plate": "Tenanea Pressure Plate", + "block.betterend.tenanea_sapling": "Tenanea Sapling", + "block.betterend.tenanea_sign": "Tenanea Sign", + "block.betterend.tenanea_slab": "Tenanea Slab", + "block.betterend.tenanea_stairs": "Tenanea Stairs", + "block.betterend.tenanea_stripped_bark": "Stripped Tenanea Bark", + "block.betterend.tenanea_stripped_log": "Stripped Tenanea Log", + "block.betterend.tenanea_trapdoor": "Tenanea Trapdoor", + "block.betterend.amber_block": "Amber Block", + "block.betterend.amber_ore": "Amber Ore", + "item.betterend.amber_gem": "Amber Gem", + "item.betterend.raw_amber": "Raw Amber", + "block.betterend.tenanea_flowers": "Tenanea Flowers", + "block.betterend.tenanea_outer_leaves": "Tenanea Outer Leaves", + "block.betterend.pink_moss": "Pink Moss", + "block.betterend.pink_moss_path": "Pink Moss Path", + "block.betterend.twisted_moss": "Twisted Moss", + "block.betterend.bulb_vine": "Bulb Vine", + "block.betterend.bulb_vine_seed": "Bulb Vine Seed", + "item.betterend.glowing_bulb": "Glowing Bulb", + "block.betterend.iron_bulb_lantern": "Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_black": "Black Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_blue": "Blue Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_brown": "Brown Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_cyan": "Cyan Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_gray": "Gray Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_green": "Green Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_light_blue": "Light Blue Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_light_gray": "Light Gray Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_lime": "Lime Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_magenta": "Magenta Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_orange": "Orange Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_pink": "Pink Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_purple": "Purple Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_red": "Red Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_white": "White Iron Bulb Lantern", + "block.betterend.iron_bulb_lantern_yellow": "Yellow Iron Bulb Lantern", + "block.betterend.thallasium_bulb_lantern": "Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_black": "Black Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_blue": "Blue Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_brown": "Brown Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_cyan": "Cyan Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_gray": "Gray Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_green": "Green Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_light_blue": "Light Blue Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_light_gray": "Light Gray Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_lime": "Lime Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_magenta": "Magenta Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_orange": "Orange Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_pink": "Pink Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_purple": "Purple Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_red": "Red Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_white": "White Thallasium Bulb Lantern", + "block.betterend.thallasium_bulb_lantern_yellow": "Yellow Thallasium Bulb Lantern", + "block.betterend.bushy_grass": "Bushy Grass", + "block.betterend.brimstone": "Brimstone", + "block.betterend.sulphuric_rock": "Sulfuric Rock", + "block.betterend.sulphuric_rock_bricks": "Sulfuric Rock Bricks", + "block.betterend.sulphuric_rock_bricks_slab": "Sulfuric Rock Brick Slab", + "block.betterend.sulphuric_rock_bricks_stairs": "Sulfuric Rock Brick Stairs", + "block.betterend.sulphuric_rock_bricks_wall": "Sulfuric Rock Brick Wall", + "block.betterend.sulphuric_rock_button": "Sulfuric Rock Button", + "block.betterend.sulphuric_rock_lantern": "Sulfuric Rock Lantern", + "block.betterend.sulphuric_rock_pedestal": "Sulfuric Rock Pedestal", + "block.betterend.sulphuric_rock_pillar": "Sulfuric Rock Pillar", + "block.betterend.sulphuric_rock_plate": "Sulfuric Rock Pressure Plate", + "block.betterend.sulphuric_rock_polished": "Sulfuric Rock Polished", + "block.betterend.sulphuric_rock_slab": "Sulfuric Rock Slab", + "block.betterend.sulphuric_rock_stairs": "Sulfuric Rock Stairs", + "block.betterend.sulphuric_rock_tiles": "Sulfuric Rock Tiles", + "block.betterend.sulphuric_rock_wall": "Sulfuric Rock Wall", + "block.betterend.sulphur_crystal": "Sulfur Crystal", + "item.betterend.crystalline_sulphur": "Sulfur", + "biome.betterend.sulphur_springs": "Sulfur Springs", + "block.betterend.hydralux_petal_block": "Hydralux Petal Block", + "block.betterend.hydralux_petal_block_black": "Black Petal Block", + "block.betterend.hydralux_petal_block_blue": "Blue Petal Block", + "block.betterend.hydralux_petal_block_brown": "Brown Petal Block", + "block.betterend.hydralux_petal_block_cyan": "Cyan Petal Block", + "block.betterend.hydralux_petal_block_gray": "Gray Petal Block", + "block.betterend.hydralux_petal_block_green": "Green Petal Block", + "block.betterend.hydralux_petal_block_light_blue": "Light Blue Petal Block", + "block.betterend.hydralux_petal_block_light_gray": "Light Gray Petal Block", + "block.betterend.hydralux_petal_block_lime": "Lime Petal Block", + "block.betterend.hydralux_petal_block_magenta": "Magenta Petal Block", + "block.betterend.hydralux_petal_block_orange": "Orange Petal Block", + "block.betterend.hydralux_petal_block_pink": "Pink Petal Block", + "block.betterend.hydralux_petal_block_purple": "Purple Petal Block", + "block.betterend.hydralux_petal_block_red": "Red Petal Block", + "block.betterend.hydralux_petal_block_white": "White Petal Block", + "block.betterend.hydralux_petal_block_yellow": "Yellow Petal Block", + "block.betterend.hydralux_sapling": "Hydralux Sapling", + "block.betterend.hydrothermal_vent": "Hydrothermal Vent", + "item.betterend.hydralux_petal": "Hydralux Petal", + "item.betterend.enchanted_petal": "Enchanted Petal", + "block.betterend.menger_sponge": "Menger Sponge", + "block.betterend.menger_sponge_wet": "Wet Menger Sponge", + "block.betterend.tube_worm": "Tube Worm", + "block.betterend.charnia_cyan": "Cyan Charnia", + "block.betterend.charnia_light_blue": "Light Blue Charnia", + "block.betterend.charnia_orange": "Orange Charnia", + "block.betterend.charnia_purple": "Purple Charnia", + "block.betterend.charnia_red": "Red Charnia", + "entity.betterend.cubozoa": "Cubozoa", + "item.betterend.spawn_egg_cubozoa": "Cubozoa Spawn Egg", + "item.betterend.gelatine": "Gelatine", + "item.betterend.sweet_berry_jelly": "Sweet Berry Jelly", + "item.betterend.shadow_berry_jelly": "Shadow Berry Jelly", + "block.betterend.amber_moss": "Amber Moss", + "block.betterend.amber_moss_path": "Amber Moss Path", + "block.betterend.helix_tree_bark": "Helix Tree Bark", + "block.betterend.helix_tree_barrel": "Helix Tree Barrel", + "block.betterend.helix_tree_bookshelf": "Helix Tree Bookshelf", + "block.betterend.helix_tree_button": "Helix Tree Button", + "block.betterend.helix_tree_chest": "Helix Tree Chest", + "block.betterend.helix_tree_crafting_table": "Helix Tree Crafting Table", + "block.betterend.helix_tree_door": "Helix Tree Door", + "block.betterend.helix_tree_fence": "Helix Tree Fence", + "block.betterend.helix_tree_gate": "Helix Tree Gate", + "block.betterend.helix_tree_ladder": "Helix Tree Ladder", + "block.betterend.helix_tree_leaves": "Helix Tree Leaves", + "block.betterend.helix_tree_log": "Helix Tree Log", + "block.betterend.helix_tree_planks": "Helix Tree Planks", + "block.betterend.helix_tree_plate": "Helix Tree Pressure Plate", + "block.betterend.helix_tree_sapling": "Helix Tree Sapling", + "block.betterend.helix_tree_sign": "Helix Tree Sign", + "block.betterend.helix_tree_slab": "Helix Tree Slab", + "block.betterend.helix_tree_stairs": "Helix Tree Stairs", + "block.betterend.helix_tree_stripped_bark": "Stripped Helix Tree Bark", + "block.betterend.helix_tree_stripped_log": "Stripped Helix Tree Log", + "block.betterend.helix_tree_trapdoor": "Helix Tree Trapdoor", + "block.betterend.lanceleaf": "Lanceleaf", + "block.betterend.lanceleaf_seed": "Lanceleaf Seed", + "block.betterend.hydralux": "Hydralux", + "block.betterend.helix_tree_luminophor": "Helix Tree Luminophor", + "block.betterend.glowing_pillar_leaves": "Glowing Pillar Leaves", + "block.betterend.glowing_pillar_luminophor": "Glowing Pillar Luminophor", + "block.betterend.glowing_pillar_roots": "Glowing Pillar Roots", + "block.betterend.glowing_pillar_seed": "Glowing Pillar Seed", + "biome.betterend.ice_starfield": "Ice Starfield", + "block.betterend.ancient_emerald_ice": "Ancient Emerald Ice", + "block.betterend.dense_emerald_ice": "Dense Emerald Ice", + "block.betterend.dense_snow": "Dense Snow", + "block.betterend.emerald_ice": "Emerald Ice", + "block.betterend.bulb_moss": "Bulb Moss", + "block.betterend.charnia_green": "Green Charnia", + "block.betterend.vent_bubble_column": "Vent Bubble Column", + "block.betterend.respawn_obelisk": "Respawn Obelisk", + "message.betterend.set_spawn": "\u00A7b\u00A7lYour spawn point is set here", + "message.betterend.fail_spawn": "\u00A7c\u00A7lYou need to hold 6 Amber Gems to set your spawn point", + "block.betterend.dragon_tree_composter": "Dragon Tree Composter", + "block.betterend.end_lotus_composter": "End Lotus Composter", + "block.betterend.helix_tree_composter": "Helix Tree Composter", + "block.betterend.lacugrove_composter": "Lacugrove Composter", + "block.betterend.mossy_glowshroom_composter": "Mossy Glowshroom Composter", + "block.betterend.pythadendron_composter": "Pythadendron Composter", + "block.betterend.tenanea_composter": "Tenanea Composter", + "biome.betterend.old_bulbis_gardens": "Old Bulbis Gardens", + "block.betterend.ivis_moss": "Ivis Moss", + "block.betterend.ivis_vine": "Ivis Vine", + "block.betterend.silk_moth_nest": "Silk Moth Nest", + "block.betterend.umbrella_tree_bark": "Umbrella Tree Bark", + "block.betterend.umbrella_tree_barrel": "Umbrella Tree Barrel", + "block.betterend.umbrella_tree_bookshelf": "Umbrella Tree Bookshelf", + "block.betterend.umbrella_tree_button": "Umbrella Tree Button", + "block.betterend.umbrella_tree_chest": "Umbrella Tree Chest", + "block.betterend.umbrella_tree_composter": "Umbrella Tree Composter", + "block.betterend.umbrella_tree_crafting_table": "Umbrella Tree Crafting Table", + "block.betterend.umbrella_tree_door": "Umbrella Tree Door", + "block.betterend.umbrella_tree_fence": "Umbrella Tree Fence", + "block.betterend.umbrella_tree_gate": "Umbrella Tree Gate", + "block.betterend.umbrella_tree_ladder": "Umbrella Tree Ladder", + "block.betterend.umbrella_tree_log": "Umbrella Tree Log", + "block.betterend.umbrella_tree_planks": "Umbrella Tree Planks", + "block.betterend.umbrella_tree_plate": "Umbrella Tree Pressure Plate", + "block.betterend.umbrella_tree_sign": "Umbrella Tree Sign", + "block.betterend.umbrella_tree_slab": "Umbrella Tree Slab", + "block.betterend.umbrella_tree_stairs": "Umbrella Tree Stairs", + "block.betterend.umbrella_tree_stripped_bark": "Stripped Umbrella Tree Bark", + "block.betterend.umbrella_tree_stripped_log": "Stripped Umbrella Tree Log", + "block.betterend.umbrella_tree_trapdoor": "Umbrella Tree Trapdoor", + "block.betterend.umbrella_tree_membrane": "Umbrella Tree Membrane", + "biome.betterend.umbrella_jungle": "Umbrella Jungle", + "block.betterend.jungle_grass": "Jungle Grass", + "block.betterend.jungle_moss": "Jungle Moss", + "block.betterend.jungle_moss_path": "Jungle Moss Path", + "block.betterend.small_jellyshroom": "Small Jellyshroom", + "block.betterend.twisted_umbrella_moss": "Twisted Umbrella Moss", + "block.betterend.twisted_umbrella_moss_tall": "Twisted Umbrella Moss Tall", + "block.betterend.umbrella_tree_cluster": "Umbrella Tree Cluster", + "block.betterend.umbrella_tree_cluster_empty": "Empty Umbrella Tree Cluster", + "block.betterend.jungle_vine": "Jungle Vine", + "block.betterend.jungle_fern": "Jungle Fern", + "block.betterend.jellyshroom_bark": "Jellyshroom Bark", + "block.betterend.jellyshroom_barrel": "Jellyshroom Barrel", + "block.betterend.jellyshroom_bookshelf": "Jellyshroom Bookshelf", + "block.betterend.jellyshroom_button": "Jellyshroom Button", + "block.betterend.jellyshroom_cap_purple": "Purple Jellyshroom Cap", + "block.betterend.jellyshroom_chest": "Jellyshroom Chest", + "block.betterend.jellyshroom_composter": "Jellyshroom Composter", + "block.betterend.jellyshroom_crafting_table": "Jellyshroom Crafting Table", + "block.betterend.jellyshroom_door": "Jellyshroom Door", + "block.betterend.jellyshroom_fence": "Jellyshroom Fence", + "block.betterend.jellyshroom_gate": "Jellyshroom Gate", + "block.betterend.jellyshroom_ladder": "Jellyshroom Ladder", + "block.betterend.jellyshroom_log": "Jellyshroom Log", + "block.betterend.jellyshroom_planks": "Jellyshroom Planks", + "block.betterend.jellyshroom_plate": "Jellyshroom Pressure Plate", + "block.betterend.jellyshroom_sign": "Jellyshroom Sign", + "block.betterend.jellyshroom_slab": "Jellyshroom Slab", + "block.betterend.jellyshroom_stairs": "Jellyshroom Stairs", + "block.betterend.jellyshroom_stripped_bark": "Stripped Jellyshroom Bark", + "block.betterend.jellyshroom_stripped_log": "Stripped Jellyshroom Log", + "block.betterend.jellyshroom_trapdoor": "Jellyshroom Trapdoor", + "biome.betterend.eterial_grove": "Eterial Grove", + "block.betterend.umbrella_tree_sapling": "Umbrella Tree Sapling", + "item.betterend.umbrella_cluster_juice": "Umbrella Cluster Juice", + "block.betterend.blossom_berry_seed": "Blossom Berry Seed", + "item.betterend.blossom_berry": "Blossom Berry", + "biome.betterend.nightshade_redwoods": "Nightshade Redwoods", + "block.betterend.nightshade_moss": "Nightshade Moss", + "biome.betterend.glowing_grasslands": "Glowing Grasslands", + "block.betterend.blooming_cooksonia": "Blooming Cooksonia", + "block.betterend.fracturn": "Fracturn", + "block.betterend.lumecorn": "Lumecorn", + "block.betterend.salteago": "Salteago", + "block.betterend.vaiolush_fern": "Vaiolush Fern", + "entity.betterend.silk_moth": "Silk Moth", + "item.betterend.silk_fiber": "Silk Fiber", + "item.betterend.spawn_egg_silk_moth": "Silk Moth Spawn Egg", + "item.betterend.thallasium_raw": "Raw Thallasium", + "block.betterend.thallasium_ore": "Thallasium Ore", + "item.betterend.thallasium_axe": "Thallasium Axe", + "item.betterend.thallasium_hoe": "Thallasium Hoe", + "item.betterend.thallasium_ingot": "Thallasium Ingot", + "item.betterend.thallasium_pickaxe": "Thallasium Pickaxe", + "item.betterend.thallasium_shovel": "Thallasium Shovel", + "item.betterend.thallasium_sword": "Thallasium Sword", + "block.betterend.thallasium_block": "Thallasium Block", + "block.betterend.thallasium_bars": "Thallasium Bars", + "block.betterend.thallasium_door": "Thallasium Door", + "block.betterend.thallasium_plate": "Thallasium Pressure Plate", + "block.betterend.thallasium_tile": "Thallasium Tile", + "block.betterend.thallasium_trapdoor": "Thallasium Trapdoor", + "block.betterend.lumecorn_seed": "Lumecorn Seed", + "item.betterend.lumecorn_rod": "Lumecorn Rod", + "block.betterend.thallasium_chandelier": "Thallasium Chandelier", + "block.betterend.thallasium_anvil": "Thallasium Anvil", + "block.betterend.thallasium_chain": "Thallasium Chain", + "block.betterend.thallasium_slab": "Thallasium Slab", + "block.betterend.thallasium_stairs": "Thallasium Stairs", + "block.betterend.gold_chandelier": "Gold Chandelier", + "block.betterend.iron_chandelier": "Iron Chandelier", + "item.betterend.thallasium_nugget": "Thallasium Nugget", + "block.betterend.terminite_anvil": "Terminite Anvil", + "block.betterend.terminite_bars": "Terminite Bars", + "block.betterend.terminite_bulb_lantern": "Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_black": "Black Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_blue": "Blue Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_brown": "Brown Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_cyan": "Cyan Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_gray": "Gray Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_green": "Green Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_light_blue": "Light Blue Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_light_gray": "Light Gray Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_lime": "Lime Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_magenta": "Magenta Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_orange": "Orange Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_pink": "Pink Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_purple": "Purple Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_red": "Red Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_white": "White Terminite Bulb Lantern", + "block.betterend.terminite_bulb_lantern_yellow": "Yellow Terminite Bulb Lantern", + "block.betterend.terminite_chain": "Terminite Chain", + "block.betterend.terminite_chandelier": "Terminite Chandelier", + "block.betterend.terminite_door": "Terminite Door", + "block.betterend.terminite_plate": "Terminite Pressure Plate", + "block.betterend.terminite_slab": "Terminite Slab", + "block.betterend.terminite_stairs": "Terminite Stairs", + "block.betterend.terminite_tile": "Terminite Tile", + "block.betterend.terminite_trapdoor": "Terminite Trapdoor", + "item.betterend.terminite_nugget": "Terminite Nugget", + "item.betterend.thallasium_boots": "Thallasium Boots", + "item.betterend.thallasium_chestplate": "Thallasium Chestplate", + "item.betterend.thallasium_hammer": "Thallasium Hammer", + "item.betterend.thallasium_helmet": "Thallasium Helmet", + "item.betterend.thallasium_leggings": "Thallasium Leggings", + "block.betterend.missing_tile": "Missing Tile", + "block.betterend.charcoal_block": "Charcoal Block", + "block.betterend.end_stone_furnace": "End Stone Furnace", + "block.betterend.flavolite_furnace": "Flavolite Furnace", + "block.betterend.sulphuric_rock_furnace": "Sulfuric Rock Furnace", + "block.betterend.violecite_furnace": "Violecite Furnace", + "item.betterend.terminite_axe_head": "Terminite Axe Head", + "item.betterend.terminite_hoe_head": "Terminite Hoe Head", + "item.betterend.terminite_pickaxe_head": "Terminite Pickaxe Head", + "item.betterend.terminite_shovel_head": "Terminite Shovel Head", + "item.betterend.terminite_sword_blade": "Terminite Sword Blade", + "item.betterend.terminite_sword_handle": "Terminite Sword Handle", + "item.betterend.thallasium_axe_head": "Thallasium Axe Head", + "item.betterend.thallasium_hoe_head": "Thallasium Hoe Head", + "item.betterend.thallasium_pickaxe_head": "Thallasium Pickaxe Head", + "item.betterend.thallasium_shovel_head": "Thallasium Shovel Head", + "item.betterend.thallasium_sword_blade": "Thallasium Sword Blade", + "item.betterend.thallasium_sword_handle": "Thallasium Sword Handle", + "block.betterend.aeternium_anvil": "Aeternium Anvil", + "biome.betterend.dragon_graveyards": "Dragon Graveyards", + "biome.betterend.dry_shrubland": "Dry Shrubland", + "block.betterend.aeridium": "Aeridium", + "block.betterend.amaranita_cap": "Amaranita Cap", + "block.betterend.amaranita_fur": "Amaranita Fur", + "block.betterend.amaranita_hymenophore": "Amaranita Hymenophore", + "block.betterend.amaranita_hyphae": "Amaranita Hyphae", + "block.betterend.amaranita_lantern": "Amaranita Lantern", + "block.betterend.amaranita_stem": "Amaranita Stem", + "block.betterend.clawfern": "Clawfern", + "block.betterend.globulagus": "Globulagus", + "block.betterend.lamellarium": "Lamellarium", + "block.betterend.large_amaranita_mushroom": "Large Amaranita Mushroom", + "block.betterend.lutebus": "Lutebus", + "block.betterend.mossy_bone": "Mossy Bone", + "block.betterend.mossy_obsidian": "Mossy Obsidian", + "block.betterend.orango": "Orango", + "block.betterend.rutiscus": "Rutiscus", + "block.betterend.rutiscus_path": "Rutiscus Path", + "block.betterend.sangnum": "Sangnum", + "block.betterend.sangnum_path": "Sangnum Path", + "block.betterend.small_amaranita_mushroom": "Small Amaranita Mushroom", + "block.betterend.amber_root_seed": "Amber Root Seed", + "block.betterend.azure_jadestone": "Azure Jadestone", + "block.betterend.azure_jadestone_bricks": "Azure Jadestone Bricks", + "block.betterend.azure_jadestone_bricks_slab": "Azure Jadestone Brick Slab", + "block.betterend.azure_jadestone_bricks_stairs": "Azure Jadestone Brick Stairs", + "block.betterend.azure_jadestone_bricks_wall": "Azure Jadestone Brick Wall", + "block.betterend.azure_jadestone_button": "Azure Jadestone Button", + "block.betterend.azure_jadestone_furnace": "Azure Jadestone Furnace", + "block.betterend.azure_jadestone_lantern": "Azure Jadestone Lantern", + "block.betterend.azure_jadestone_pedestal": "Azure Jadestone Pedestal", + "block.betterend.azure_jadestone_pillar": "Azure Jadestone Pillar", + "block.betterend.azure_jadestone_plate": "Azure Jadestone Pressure Plate", + "block.betterend.azure_jadestone_polished": "Azure Jadestone Polished", + "block.betterend.azure_jadestone_slab": "Azure Jadestone Slab", + "block.betterend.azure_jadestone_stairs": "Azure Jadestone Stairs", + "block.betterend.azure_jadestone_tiles": "Azure Jadestone Tiles", + "block.betterend.azure_jadestone_wall": "Azure Jadestone Wall", + "block.betterend.chorus_mushroom_seed": "Chorus Mushroom Seed", + "block.betterend.end_stone_stalactite": "End Stone Stalactite", + "block.betterend.end_stone_stalactite_cavemoss": "Cave Moss Endstone Stalactite", + "block.betterend.pearlberry_seed": "Pearlberry Seed", + "block.betterend.rubinea": "Rubinea", + "block.betterend.sandy_jadestone": "Sandy Jadestone", + "block.betterend.sandy_jadestone_bricks": "Sandy Jadestone Bricks", + "block.betterend.sandy_jadestone_bricks_slab": "Sandy Jadestone Brick Slab", + "block.betterend.sandy_jadestone_bricks_stairs": "Sandy Jadestone Brick Stairs", + "block.betterend.sandy_jadestone_bricks_wall": "Sandy Jadestone Brick Wall", + "block.betterend.sandy_jadestone_button": "Sandy Jadestone Button", + "block.betterend.sandy_jadestone_furnace": "Sandy Jadestone Furnace", + "block.betterend.sandy_jadestone_lantern": "Sandy Jadestone Lantern", + "block.betterend.sandy_jadestone_pedestal": "Sandy Jadestone Pedestal", + "block.betterend.sandy_jadestone_pillar": "Sandy Jadestone Pillar", + "block.betterend.sandy_jadestone_plate": "Sandy Jadestone Pressure Plate", + "block.betterend.sandy_jadestone_polished": "Sandy Jadestone Polished", + "block.betterend.sandy_jadestone_slab": "Sandy Jadestone Slab", + "block.betterend.sandy_jadestone_stairs": "Sandy Jadestone Stairs", + "block.betterend.sandy_jadestone_tiles": "Sandy Jadestone Tiles", + "block.betterend.sandy_jadestone_wall": "Sandy Jadestone Wall", + "block.betterend.smaragdant_crystal": "Smaragdant Crystal", + "block.betterend.smaragdant_crystal_shard": "Smaragdant Crystal Shard", + "block.betterend.virid_jadestone": "Virid Jadestone", + "block.betterend.virid_jadestone_bricks": "Virid Jadestone Bricks", + "block.betterend.virid_jadestone_bricks_slab": "Virid Jadestone Brick Slab", + "block.betterend.virid_jadestone_bricks_stairs": "Virid Jadestone Brick Stairs", + "block.betterend.virid_jadestone_bricks_wall": "Virid Jadestone Brick Wall", + "block.betterend.virid_jadestone_button": "Virid Jadestone Button", + "block.betterend.virid_jadestone_furnace": "Virid Jadestone Furnace", + "block.betterend.virid_jadestone_lantern": "Virid Jadestone Lantern", + "block.betterend.virid_jadestone_pedestal": "Virid Jadestone Pedestal", + "block.betterend.virid_jadestone_pillar": "Virid Jadestone Pillar", + "block.betterend.virid_jadestone_plate": "Virid Jadestone Pressure Plate", + "block.betterend.virid_jadestone_polished": "Virid Jadestone Polished", + "block.betterend.virid_jadestone_slab": "Virid Jadestone Slab", + "block.betterend.virid_jadestone_stairs": "Virid Jadestone Stairs", + "block.betterend.virid_jadestone_tiles": "Virid Jadestone Tiles", + "block.betterend.virid_jadestone_wall": "Virid Jadestone Wall", + "item.betterend.amber_root_raw": "Raw Amber Root", + "item.betterend.chorus_mushroom_cooked": "Cooked Chorus Mushroom", + "item.betterend.chorus_mushroom_raw": "Raw Chorus Mushroom", + "biome.betterend.empty_aurora_cave": "Empty Aurora Cave", + "biome.betterend.empty_end_cave": "Empty End Cave", + "biome.betterend.empty_smaragdant_cave": "Empty Smaragdant Cave", + "biome.betterend.lush_aurora_cave": "Lush Aurora Cave", + "biome.betterend.lush_smaragdant_cave": "Lush Smaragdant Cave", + "block.betterend.dragon_bone_block": "Dragon Bone Block", + "block.betterend.dragon_bone_slab": "Dragon Bone Slab", + "block.betterend.dragon_bone_stairs": "Dragon Bone Stairs", + "block.betterend.mossy_dragon_bone": "Mossy Dragon Bone", + "biome.betterend.lantern_woods": "Lantern Woods", + "block.betterend.filalux": "Filalux", + "block.betterend.filalux_lantern": "Filalux Lantern", + "block.betterend.filalux_wings": "Filalux Wings", + "block.betterend.lucernia_bark": "Lucernia Bark", + "block.betterend.lucernia_barrel": "Lucernia Barrel", + "block.betterend.lucernia_bookshelf": "Lucernia Bookshelf", + "block.betterend.lucernia_button": "Lucernia Button", + "block.betterend.lucernia_chest": "Lucernia Chest", + "block.betterend.lucernia_composter": "Lucernia Composter", + "block.betterend.lucernia_crafting_table": "Lucernia Crafting Table", + "block.betterend.lucernia_door": "Lucernia Door", + "block.betterend.lucernia_fence": "Lucernia Fence", + "block.betterend.lucernia_gate": "Lucernia Gate", + "block.betterend.lucernia_ladder": "Lucernia Ladder", + "block.betterend.lucernia_leaves": "Lucernia Leaves", + "block.betterend.lucernia_log": "Lucernia Log", + "block.betterend.lucernia_outer_leaves": "Lucernia Outer Leaves", + "block.betterend.lucernia_planks": "Lucernia Planks", + "block.betterend.lucernia_plate": "Lucernia Pressure Plate", + "block.betterend.lucernia_sapling": "Lucernia Sapling", + "block.betterend.lucernia_sign": "Lucernia Sign", + "block.betterend.lucernia_slab": "Lucernia Slab", + "block.betterend.lucernia_stairs": "Lucernia Stairs", + "block.betterend.lucernia_stripped_bark": "Stripped Lucernia Bark", + "block.betterend.lucernia_stripped_log": "Stripped Lucernia Log", + "block.betterend.lucernia_trapdoor": "Lucernia Trapdoor", + "block.betterend.aurant_polypore": "Aurant Polypore", + "block.betterend.bolux_mushroom": "Bolux Mushroom", + "block.betterend.flamaea": "Flamaea", + "block.betterend.pond_anemone": "Pond Anemone", + "block.betterend.ruscus": "Ruscus", + "item.betterend.bolux_mushroom_cooked": "Cooked Bolux Mushroom", + "block.betterend.silk_moth_hive": "Silk Moth Hive", + "item.betterend.silk_moth_matrix": "Silk Moth Matrix", + "biome.betterend.neon_oasis": "Neon Oasis", + "block.betterend.cave_pumpkin": "Cave Pumpkin", + "block.betterend.cave_pumpkin_seed": "Cave Pumpkin Seed", + "block.betterend.magnula": "Magnula", + "block.betterend.neon_cactus": "Neon Cactus", + "item.betterend.cave_pumpkin_pie": "Cave Pumpkin Pie", + "item.betterend.music_disc_strange_and_alien": "§bMusic Disc§r", + "item.betterend.music_disc_strange_and_alien.desc": "§5Firel§r - §fStrange And Alien§r", + "item.betterend.music_disc_grasping_at_stars": "§bMusic Disc§r", + "item.betterend.music_disc_grasping_at_stars.desc": "§5Firel§r - §fGrasping At Stars§r", + "item.betterend.music_disc_endseeker": "§bMusic Disc§r", + "item.betterend.music_disc_endseeker.desc": "§5Firel§r - §fEndseeker§r", + "item.betterend.music_disc_eo_dracona": "§bMusic Disc§r", + "item.betterend.music_disc_eo_dracona.desc": "§5Firel§r - §fEo Dracona§r", + "block.betterend.hydralux_petal_block_amber": "Amber Petal Block", + "block.betterend.hydralux_petal_block_beige": "Beige Petal Block", + "block.betterend.hydralux_petal_block_cream": "Cream Petal Block", + "block.betterend.hydralux_petal_block_dark_green": "Dark Green Petal Block", + "block.betterend.hydralux_petal_block_forest_green": "Forest Green Petal Block", + "block.betterend.hydralux_petal_block_hot_pink": "Hot Pink Petal Block", + "block.betterend.hydralux_petal_block_indigo": "Indigo Petal Block", + "block.betterend.hydralux_petal_block_maroon": "Maroon Petal Block", + "block.betterend.hydralux_petal_block_navy": "Navy Petal Block", + "block.betterend.hydralux_petal_block_olive": "Olive Petal Block", + "block.betterend.hydralux_petal_block_pale_green": "Pale Green Petal Block", + "block.betterend.hydralux_petal_block_pale_pink": "Pale Pink Petal Block", + "block.betterend.hydralux_petal_block_pale_yellow": "Pale Yellow Petal Block", + "block.betterend.hydralux_petal_block_sky_blue": "Sky Blue Petal Block", + "block.betterend.hydralux_petal_block_slate_gray": "Slate Gray Petal Block", + "block.betterend.hydralux_petal_block_violet": "Violet Petal Block", + "block.betterend.smaragdant_crystal_bricks": "Smaragdant Bricks", + "block.betterend.smaragdant_crystal_bricks_slab": "Smaragdant Brick Slab", + "block.betterend.smaragdant_crystal_bricks_stairs": "Smaragdant Brick Stairs", + "block.betterend.smaragdant_crystal_bricks_wall": "Smaragdant Brick Wall", + "block.betterend.smaragdant_crystal_pedestal": "Smaragdant Pedestal", + "block.betterend.smaragdant_crystal_pillar": "Smaragdant Pillar", + "block.betterend.smaragdant_crystal_polished": "Polished Smaragdant", + "block.betterend.smaragdant_crystal_slab": "Smaragdant Slab", + "block.betterend.smaragdant_crystal_stairs": "Smaragdant Stairs", + "block.betterend.smaragdant_crystal_tiles": "Smaragdant Tiles", + "block.betterend.smaragdant_crystal_wall": "Smaragdant Wall", + "message.betterend.anvil_damage": "§cDamage", + "block.betterend.neon_cactus_block": "Neon Cactus Block", + "block.betterend.neon_cactus_slab": "Neon Cactus Slab", + "block.betterend.neon_cactus_stairs": "Neon Cactus Stairs", + "biome.betterend.jade_cave": "Jade Cave", + "item.betterend.blossom_berry_jelly": "Blossom Berry Jelly", + "item.betterend.aeternium_forged_plate": "Aeternium Forged Plate", + "item.betterend.terminite_forged_plate": "Terminite Forged Plate", + "item.betterend.thallasium_forged_plate": "Thallasium Forged Plate", + "attribute.name.generic.blindness_resistance": "Blindness Resistance", + "tooltip.armor.crystalite_set": "Set bonus: Regeneration I", + "tooltip.armor.crystalite_chest": "Effect: Dig Speed I", + "tooltip.armor.crystalite_boots": "Effect: Swiftness I", + "block.betterend.azure_jadestone_flower_pot": "Azure Jadestone Flower Pot", + "block.betterend.endstone_flower_pot": "Endstone Flower Pot", + "block.betterend.flavolite_flower_pot": "Flavolite Flower Pot", + "block.betterend.sandy_jadestone_flower_pot": "Sandy Jadestone Flower Pot", + "block.betterend.sulphuric_rock_flower_pot": "Sulphuric Rock Flower Pot", + "block.betterend.violecite_flower_pot": "Violecite Flower Pot", + "block.betterend.virid_jadestone_flower_pot": "Virid Jadestone Flower Pot", + "block.betterend.umbralith": "Umbralith", + "block.betterend.umbralith_bricks": "Umbralith Bricks", + "block.betterend.umbralith_bricks_slab": "Umbralith Bricks Slab", + "block.betterend.umbralith_bricks_stairs": "Umbralith Bricks Stairs", + "block.betterend.umbralith_bricks_wall": "Umbralith Bricks Wall", + "block.betterend.umbralith_button": "Umbralith Button", + "block.betterend.umbralith_flower_pot": "Umbralith Flower Pot", + "block.betterend.umbralith_furnace": "Umbralith Furnace", + "block.betterend.umbralith_lantern": "Umbralith Lantern", + "block.betterend.umbralith_pedestal": "Umbralith Pedestal", + "block.betterend.umbralith_pillar": "Umbralith Pillar", + "block.betterend.umbralith_plate": "Umbralith Pressure Plate", + "block.betterend.umbralith_polished": "Umbralith Polished", + "block.betterend.umbralith_slab": "Umbralith Slab", + "block.betterend.umbralith_stairs": "Umbralith Stairs", + "block.betterend.umbralith_tiles": "Umbralith Tiles", + "block.betterend.umbralith_wall": "Umbralith Wall", + "biome.betterend.umbra_valley": "Umbra Valley", + "block.betterend.inflexia": "Inflexia", + "block.betterend.pallidium_full": "Pallidium (Full Cover)", + "block.betterend.pallidium_heavy": "Pallidium (Heavy Cover)", + "block.betterend.pallidium_thin": "Pallidium (Thin Cover)", + "block.betterend.pallidium_tiny": "Pallidium (Tiny Cover)", + "block.betterend.flammalix": "Flammalix" +} diff --git a/src/main/resources/assets/betterend/lang/zh_cn.json b/src/main/resources/assets/betterend/lang/zh_cn.json index 524c9ddb..d8204197 100644 --- a/src/main/resources/assets/betterend/lang/zh_cn.json +++ b/src/main/resources/assets/betterend/lang/zh_cn.json @@ -44,18 +44,11 @@ "item.betterend.aeternium_leggings": "太古合金护腿", "item.betterend.aeternium_boots": "太古合金靴子", "item.betterend.aeternium_shovel": "太古合金锹", - "item.betterend.aeternium_shovel_head": "太古合金锹头部", "item.betterend.aeternium_sword": "太古合金剑", - "item.betterend.aeternium_sword_blade": "太古合金剑刃", - "item.betterend.aeternium_sword_handle": "太古合金剑柄", "item.betterend.aeternium_pickaxe": "太古合金镐", - "item.betterend.aeternium_pickaxe_head": "太古合金镐头部", "item.betterend.aeternium_axe": "太古合金斧", - "item.betterend.aeternium_axe_head": "太古合金斧头部", "item.betterend.aeternium_hoe": "太古合金锄", - "item.betterend.aeternium_hoe_head": "太古合金锄头部", "item.betterend.aeternium_hammer": "太古合金锻锤", - "item.betterend.aeternium_hammer_head": "太古合金锻锤头部", "item.betterend.iron_hammer": "铁锻锤", "item.betterend.golden_hammer": "金锻锤", "item.betterend.diamond_hammer": "钻石锻锤", @@ -64,9 +57,18 @@ "item.betterend.crystalite_chestplate": "融晶合金胸甲", "item.betterend.crystalite_helmet": "融晶合金头盔", "item.betterend.crystalite_leggings": "融晶合金护腿", + "item.betterend.aeternium_axe_head": "太古合金斧头部", + "item.betterend.aeternium_hammer_head": "太古合金锻锤头部", + "item.betterend.aeternium_hoe_head": "太古合金锄头部", + "item.betterend.aeternium_pickaxe_head": "太古合金镐头部", + "item.betterend.aeternium_shovel_head": "太古合金锹头部", + "item.betterend.aeternium_sword_blade": "太古合金剑刃", + "item.betterend.aeternium_sword_handle": "太古合金剑柄", "item.betterend.leather_stripe": "皮革条纹", "item.betterend.leather_wrapped_stick": "皮革包装棒", "item.betterend.elytra_armored": "装甲鞘翅", + "item.betterend.elytra_crystalite": "鞘翅融晶合金", + "item.betterend.enchanted_membrane": "附魔膜", "effect.betterend.end_veil": "末地面纱", "enchantment.betterend.end_veil": "末地面纱", "item.minecraft.potion.effect.end_veil": "末地面纱药水", @@ -145,7 +147,7 @@ "block.betterend.violecite_pillar": "紫罗兰石柱", "block.betterend.violecite_plate": "紫罗兰石压力板", "block.betterend.violecite_slab": "紫罗兰石台阶", - "block.betterend.violecite_tiles": "紫罗兰石瓷砖", + "block.betterend.violecite_tiles": "紫罗兰石瓦", "block.betterend.violecite_stairs": "紫罗兰石楼梯", "block.betterend.violecite_polished": "磨制紫罗兰石", "block.betterend.violecite_wall": "紫罗兰石墙", @@ -159,7 +161,7 @@ "block.betterend.flavolite_pillar": "苍黄石柱", "block.betterend.flavolite_plate": "苍黄石压力板", "block.betterend.flavolite_slab": "苍黄石台阶", - "block.betterend.flavolite_tiles": "苍黄石瓷砖", + "block.betterend.flavolite_tiles": "苍黄石瓦", "block.betterend.flavolite_stairs": "苍黄石楼梯", "block.betterend.flavolite_polished": "磨制苍黄石", "block.betterend.flavolite_wall": "苍黄石墙", @@ -354,25 +356,25 @@ "block.betterend.thallasium_bulb_lantern_white": "白色铊灯泡灯笼", "block.betterend.thallasium_bulb_lantern_yellow": "黄色铊灯泡灯笼", "block.betterend.bushy_grass": "丛藓", - "block.betterend.brimstone": "硫磺石", - "block.betterend.sulphuric_rock": "硫磺岩", - "block.betterend.sulphuric_rock_bricks": "硫磺岩砖", - "block.betterend.sulphuric_rock_bricks_slab": "硫磺岩砖台阶", - "block.betterend.sulphuric_rock_bricks_stairs": "硫磺岩砖楼梯", - "block.betterend.sulphuric_rock_bricks_wall": "硫磺岩砖墙", - "block.betterend.sulphuric_rock_button": "硫磺岩按钮", - "block.betterend.sulphuric_rock_lantern": "硫磺岩灯笼", - "block.betterend.sulphuric_rock_pedestal": "硫磺岩基座", - "block.betterend.sulphuric_rock_pillar": "硫磺岩柱", - "block.betterend.sulphuric_rock_plate": "硫磺岩压力板", - "block.betterend.sulphuric_rock_polished": "磨制硫磺岩", - "block.betterend.sulphuric_rock_slab": "硫磺岩台阶", - "block.betterend.sulphuric_rock_stairs": "硫磺岩楼梯", - "block.betterend.sulphuric_rock_tiles": "硫磺岩瓷砖", - "block.betterend.sulphuric_rock_wall": "硫磺岩墙", - "block.betterend.sulphur_crystal": "硫磺结晶", - "item.betterend.crystalline_sulphur": "硫磺", - "biome.betterend.sulphur_springs": "硫磺矿泉", + "block.betterend.brimstone": "硫黄", + "block.betterend.sulphuric_rock": "硫黄岩", + "block.betterend.sulphuric_rock_bricks": "硫黄岩砖", + "block.betterend.sulphuric_rock_bricks_slab": "硫黄岩砖台阶", + "block.betterend.sulphuric_rock_bricks_stairs": "硫黄岩砖楼梯", + "block.betterend.sulphuric_rock_bricks_wall": "硫黄岩砖墙", + "block.betterend.sulphuric_rock_button": "硫黄岩按钮", + "block.betterend.sulphuric_rock_lantern": "硫黄岩灯笼", + "block.betterend.sulphuric_rock_pedestal": "硫黄岩基座", + "block.betterend.sulphuric_rock_pillar": "硫黄岩柱", + "block.betterend.sulphuric_rock_plate": "硫黄岩压力板", + "block.betterend.sulphuric_rock_polished": "磨制硫黄岩", + "block.betterend.sulphuric_rock_slab": "硫黄岩台阶", + "block.betterend.sulphuric_rock_stairs": "硫黄岩楼梯", + "block.betterend.sulphuric_rock_tiles": "硫黄岩瓦", + "block.betterend.sulphuric_rock_wall": "硫黄岩墙", + "block.betterend.sulphur_crystal": "硫黄结晶", + "item.betterend.crystalline_sulphur": "硫黄", + "biome.betterend.sulphur_springs": "硫黄矿泉", "block.betterend.hydralux_petal_block": "水生勒克斯花瓣块", "block.betterend.hydralux_petal_block_black": "黑色花瓣块", "block.betterend.hydralux_petal_block_blue": "蓝色花瓣块", @@ -529,6 +531,7 @@ "entity.betterend.silk_moth": "蚕", "item.betterend.silk_fiber": "蚕丝", "item.betterend.spawn_egg_silk_moth": "蚕刷怪蛋", + "item.betterend.thallasium_raw": "Raw Thallasium", "block.betterend.thallasium_ore": "铊矿", "item.betterend.thallasium_axe": "铊斧头", "item.betterend.thallasium_hoe": "铊锄", @@ -589,7 +592,7 @@ "block.betterend.charcoal_block": "木碳块", "block.betterend.end_stone_furnace": "末地石熔炉", "block.betterend.flavolite_furnace": "苍黄石熔炉", - "block.betterend.sulphuric_rock_furnace": "硫磺熔炉", + "block.betterend.sulphuric_rock_furnace": "硫黄岩熔炉", "block.betterend.violecite_furnace": "紫罗兰石熔炉", "item.betterend.terminite_axe_head": "终界斧头部", "item.betterend.terminite_hoe_head": "终界锄头部", @@ -736,9 +739,13 @@ "block.betterend.neon_cactus": "霓虹仙人掌", "item.betterend.cave_pumpkin_pie": "洞穴南瓜饼", "item.betterend.music_disc_strange_and_alien": "§b音乐光盘§r", + "item.betterend.music_disc_strange_and_alien.desc": "§5Firel§r - §fStrange And Alien§r", "item.betterend.music_disc_grasping_at_stars": "§b音乐光盘§r", + "item.betterend.music_disc_grasping_at_stars.desc": "§5Firel§r - §fGrasping At Stars§r", "item.betterend.music_disc_endseeker": "§b音乐光盘§r", + "item.betterend.music_disc_endseeker.desc": "§5Firel§r - §fEndseeker§r", "item.betterend.music_disc_eo_dracona": "§b音乐光盘§r", + "item.betterend.music_disc_eo_dracona.desc": "§5Firel§r - §fEo Dracona§r", "block.betterend.hydralux_petal_block_amber": "琥珀花瓣块", "block.betterend.hydralux_petal_block_beige": "米色花瓣块", "block.betterend.hydralux_petal_block_cream": "奶油花瓣块", @@ -774,5 +781,40 @@ "item.betterend.blossom_berry_jelly": "开花浆果果冻", "item.betterend.aeternium_forged_plate": "太古合金锻造盘", "item.betterend.terminite_forged_plate": "终界锻造盘", - "item.betterend.thallasium_forged_plate": "铊锻造盘" + "item.betterend.thallasium_forged_plate": "铊锻造盘", + "attribute.name.generic.blindness_resistance": "失明防御", + "tooltip.armor.crystalite_set": "设置奖励:再生 I", + "tooltip.armor.crystalite_chest": "效果:挖掘速度 I", + "tooltip.armor.crystalite_boots": "效果:迅捷 I", + "block.betterend.azure_jadestone_flower_pot": "蓝晶花盆", + "block.betterend.endstone_flower_pot": "末地花盆", + "block.betterend.flavolite_flower_pot": "苍黄石花盆", + "block.betterend.sandy_jadestone_flower_pot": "沙玉花盆", + "block.betterend.sulphuric_rock_flower_pot": "硫黄岩花盆", + "block.betterend.violecite_flower_pot": "紫罗兰石花盆", + "block.betterend.virid_jadestone_flower_pot": "翠碧玉石花盆", + "block.betterend.umbralith": "灰暗石", + "block.betterend.umbralith_bricks": "灰暗石砖", + "block.betterend.umbralith_bricks_slab": "灰暗石砖台阶", + "block.betterend.umbralith_bricks_stairs": "灰暗石砖楼梯", + "block.betterend.umbralith_bricks_wall": "灰暗石砖墙", + "block.betterend.umbralith_button": "灰暗石按钮", + "block.betterend.umbralith_flower_pot": "灰暗石花盆", + "block.betterend.umbralith_furnace": "灰暗石熔炉", + "block.betterend.umbralith_lantern": "灰暗石灯笼", + "block.betterend.umbralith_pedestal": "灰暗石基座", + "block.betterend.umbralith_pillar": "灰暗石柱", + "block.betterend.umbralith_plate": "灰暗石压力板", + "block.betterend.umbralith_polished": "磨制灰暗石", + "block.betterend.umbralith_slab": "灰暗石台阶", + "block.betterend.umbralith_stairs": "灰暗石楼梯", + "block.betterend.umbralith_tiles": "灰暗石瓦", + "block.betterend.umbralith_wall": "灰暗石墙", + "biome.betterend.umbra_valley": "灰暗谷", + "block.betterend.inflexia": "曲转草", + "block.betterend.pallidium_full": "蒿石(完全覆盖)", + "block.betterend.pallidium_heavy": "蒿石(基本覆盖)", + "block.betterend.pallidium_thin": "蒿石(部分覆盖)", + "block.betterend.pallidium_tiny": "蒿石(略微覆盖)", + "block.betterend.flammalix": "燃草" } diff --git a/src/main/resources/assets/betterend/materialmaps/block/smaragdant_crystal_shard.json b/src/main/resources/assets/betterend/materialmaps/block/smaragdant_crystal_shard.json new file mode 100644 index 00000000..c2b812b6 --- /dev/null +++ b/src/main/resources/assets/betterend/materialmaps/block/smaragdant_crystal_shard.json @@ -0,0 +1,3 @@ +{ + "defaultMaterial": "betterend:glow_all" +} diff --git a/src/main/resources/assets/betterend/models/block/amber_grass_potted.json b/src/main/resources/assets/betterend/models/block/amber_grass_potted.json new file mode 100644 index 00000000..9b669549 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/amber_grass_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/amber_grass_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/amber_root_seed_potted.json b/src/main/resources/assets/betterend/models/block/amber_root_seed_potted.json new file mode 100644 index 00000000..3bce217c --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/amber_root_seed_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/amber_root_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/blooming_cooksonia_potted.json b/src/main/resources/assets/betterend/models/block/blooming_cooksonia_potted.json new file mode 100644 index 00000000..b3abaa7d --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/blooming_cooksonia_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/blooming_cooksonia_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/bolux_mushroom_potted.json b/src/main/resources/assets/betterend/models/block/bolux_mushroom_potted.json new file mode 100644 index 00000000..5730313a --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/bolux_mushroom_potted.json @@ -0,0 +1,45 @@ +{ + "__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio", + "textures": { + "particle": "betterend:block/bolux_mushroom", + "texture": "betterend:block/bolux_mushroom" + }, + "elements": [ + { + "__comment": "Box1", + "from": [ 4, 3, 4 ], + "to": [ 12, 7, 12 ], + "faces": { + "down": { "uv": [ 0, 8, 8, 16 ], "texture": "#texture" }, + "up": { "uv": [ 8, 0, 16, 8 ], "texture": "#texture" }, + "north": { "uv": [ 8, 12, 16, 16 ], "texture": "#texture" }, + "south": { "uv": [ 8, 12, 16, 16 ], "texture": "#texture" }, + "west": { "uv": [ 8, 12, 16, 16 ], "texture": "#texture" }, + "east": { "uv": [ 8, 12, 16, 16 ], "texture": "#texture" } + } + }, + { + "__comment": "Box1", + "from": [ 5, 7, 5 ], + "to": [ 11, 8, 11 ], + "faces": { + "up": { "uv": [ 9, 1, 15, 7 ], "texture": "#texture" }, + "north": { "uv": [ 9, 11, 15, 12 ], "texture": "#texture" }, + "south": { "uv": [ 9, 11, 15, 12 ], "texture": "#texture" }, + "west": { "uv": [ 9, 11, 15, 12 ], "texture": "#texture" }, + "east": { "uv": [ 9, 11, 15, 12 ], "texture": "#texture" } + } + }, + { + "__comment": "Box1", + "from": [ 7, 0, 7 ], + "to": [ 9, 3, 9 ], + "faces": { + "north": { "uv": [ 0, 0, 2, 3 ], "texture": "#texture" }, + "south": { "uv": [ 0, 0, 2, 3 ], "texture": "#texture" }, + "west": { "uv": [ 2, 0, 0, 3 ], "texture": "#texture" }, + "east": { "uv": [ 2, 0, 0, 3 ], "texture": "#texture" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/bushy_grass_potted.json b/src/main/resources/assets/betterend/models/block/bushy_grass_potted.json new file mode 100644 index 00000000..e9e9c134 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/bushy_grass_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/bushy_grass_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/cave_grass_potted.json b/src/main/resources/assets/betterend/models/block/cave_grass_potted.json new file mode 100644 index 00000000..618a68dc --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/cave_grass_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/cave_grass_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/chorus_grass_potted.json b/src/main/resources/assets/betterend/models/block/chorus_grass_potted.json new file mode 100644 index 00000000..f7a83d0c --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/chorus_grass_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/chorus_grass_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/chorus_mushroom_seed_potted.json b/src/main/resources/assets/betterend/models/block/chorus_mushroom_seed_potted.json new file mode 100644 index 00000000..58cf9e2d --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/chorus_mushroom_seed_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/chorus_mushroom_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/clawfern_potted.json b/src/main/resources/assets/betterend/models/block/clawfern_potted.json new file mode 100644 index 00000000..9ac28aa5 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/clawfern_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/clawfern_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/crystal_grass_potted.json b/src/main/resources/assets/betterend/models/block/crystal_grass_potted.json new file mode 100644 index 00000000..96fd61d3 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/crystal_grass_potted.json @@ -0,0 +1,95 @@ +{ + "__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio", + "textures": { + "particle": "betterend:block/crystal_grass_2", + "texture": "betterend:block/crystal_grass_2" + }, + "elements": [ + { + "__comment": "PlaneX1", + "from": [ 5, 0, 4.5 ], + "to": [ 5.001, 9, 9.5 ], + "rotation": { "origin": [ 5, 0, 4.5 ], "axis": "y", "angle": 45 }, + "shade": false, + "faces": { + "west": { "uv": [ 6, 7, 11, 16 ], "texture": "#texture" }, + "east": { "uv": [ 6, 7, 11, 16 ], "texture": "#texture" } + } + }, + { + "__comment": "PlaneX1", + "from": [ 8.5, 0, 4.5 ], + "to": [ 8.501, 9, 9.5 ], + "rotation": { "origin": [ 8.5, 0, 4.5 ], "axis": "y", "angle": -45 }, + "shade": false, + "faces": { + "west": { "uv": [ 6, 7, 11, 16 ], "texture": "#texture" }, + "east": { "uv": [ 6, 7, 11, 16 ], "texture": "#texture" } + } + }, + { + "__comment": "PlaneY4", + "from": [ 4, 8.5, 4 ], + "to": [ 9, 8.501, 9 ], + "shade": false, + "faces": { + "down": { "uv": [ 0, 0, 5, 5 ], "texture": "#texture" }, + "up": { "uv": [ 0, 0, 5, 5 ], "texture": "#texture" } + } + }, + { + "__comment": "PlaneX1", + "from": [ 8.5, -3, 7 ], + "to": [ 8.501, 6, 12 ], + "rotation": { "origin": [ 8.5, -3, 7 ], "axis": "y", "angle": 45 }, + "shade": false, + "faces": { + "west": { "uv": [ 6, 7, 11, 16 ], "texture": "#texture" }, + "east": { "uv": [ 6, 7, 11, 16 ], "texture": "#texture" } + } + }, + { + "__comment": "PlaneX1", + "from": [ 12, -3, 7 ], + "to": [ 12.001, 6, 12 ], + "rotation": { "origin": [ 12, -3, 7 ], "axis": "y", "angle": -45 }, + "shade": false, + "faces": { + "west": { "uv": [ 6, 7, 11, 16 ], "texture": "#texture" }, + "east": { "uv": [ 6, 7, 11, 16 ], "texture": "#texture" } + } + }, + { + "__comment": "PlaneY4", + "from": [ 8, 5.5, 6 ], + "to": [ 13, 5.501, 11 ], + "shade": false, + "faces": { + "down": { "uv": [ 0, 0, 5, 5 ], "texture": "#texture" }, + "up": { "uv": [ 0, 0, 5, 5 ], "texture": "#texture" } + } + }, + { + "__comment": "PlaneX1", + "from": [ 5, -3, 9 ], + "to": [ 5.001, 5, 14 ], + "rotation": { "origin": [ 5, -3, 9 ], "axis": "y", "angle": 45 }, + "shade": false, + "faces": { + "west": { "uv": [ 6, 8, 11, 16 ], "texture": "#texture" }, + "east": { "uv": [ 6, 8, 11, 16 ], "texture": "#texture" } + } + }, + { + "__comment": "PlaneX1", + "from": [ 8, -3, 9.5 ], + "to": [ 8.001, 5, 14.5 ], + "rotation": { "origin": [ 8, -3, 9.5 ], "axis": "y", "angle": -45 }, + "shade": false, + "faces": { + "west": { "uv": [ 6, 8, 11, 16 ], "texture": "#texture" }, + "east": { "uv": [ 6, 8, 11, 16 ], "texture": "#texture" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/crystal_moss_cover.json b/src/main/resources/assets/betterend/models/block/crystal_moss_cover.json new file mode 100644 index 00000000..20d1b74d --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/crystal_moss_cover.json @@ -0,0 +1,41 @@ +{ + "ambientocclusion": false, + "textures": { + "particle": "betterend:block/crystal_moss_cover", + "cover": "betterend:block/crystal_moss_cover" + }, + "elements": [ + { + "from": [ + 0, + 0, + 0.1 + ], + "to": [ + 16, + 16, + 0.1 + ], + "faces": { + "north": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#cover" + }, + "south": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#cover" + } + } + } + ] +} diff --git a/src/main/resources/assets/betterend/models/block/flammalix_1.json b/src/main/resources/assets/betterend/models/block/flammalix_1.json new file mode 100644 index 00000000..990e7d6e --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/flammalix_1.json @@ -0,0 +1,262 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "betterend:block/flammalix", + "particle": "betterend:block/flammalix" + }, + "elements": [ + { + "name": "stem", + "from": [4, 0, 4], + "to": [5, 3, 5], + "faces": { + "north": {"uv": [14, 6, 15, 9], "texture": "#0"}, + "east": {"uv": [14, 6, 15, 9], "texture": "#0"}, + "south": {"uv": [14, 6, 15, 9], "texture": "#0"}, + "west": {"uv": [14, 6, 15, 9], "texture": "#0"} + } + }, + { + "name": "cap_outside", + "from": [2, 3, 2], + "to": [7, 7, 7], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "cap_inside", + "from": [7, 3, 2], + "to": [2, 7, 7], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [3, 4, 3], + "to": [6, 7, 6], + "shade": false, + "faces": { + "north": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "east": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "south": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "west": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "up": {"uv": [1, 6, 4, 9], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [3, 2, 3], + "to": [6, 3, 6], + "shade": false, + "faces": { + "north": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "east": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "south": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "west": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + }, + { + "name": "stem_thick", + "from": [10.5, 0, 5.5], + "to": [12.5, 2, 7.5], + "faces": { + "north": {"uv": [6, 6, 8, 8], "texture": "#0"}, + "east": {"uv": [7, 6, 9, 8], "texture": "#0"}, + "south": {"uv": [6, 6, 8, 8], "texture": "#0"}, + "west": {"uv": [7, 6, 9, 8], "texture": "#0"} + } + }, + { + "name": "stem_upper", + "from": [11, 2, 6], + "to": [12, 5, 7], + "faces": { + "north": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "east": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "south": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "west": {"uv": [14, 4, 15, 7], "texture": "#0"} + } + }, + { + "name": "cap_outside", + "from": [9, 3, 4], + "to": [14, 7, 9], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "cap_inside", + "from": [14, 3, 4], + "to": [9, 7, 9], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [10, 5, 5], + "to": [13, 8, 8], + "shade": false, + "faces": { + "north": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "east": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "south": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "west": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "up": {"uv": [1, 6, 4, 9], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [10, 2, 5], + "to": [13, 3, 8], + "shade": false, + "faces": { + "north": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "east": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "south": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "west": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + }, + { + "name": "stem_thick", + "from": [6, 0, 12], + "to": [8, 3, 14], + "faces": { + "north": {"uv": [6, 6, 8, 9], "texture": "#0"}, + "east": {"uv": [7, 6, 9, 9], "texture": "#0"}, + "south": {"uv": [6, 6, 8, 9], "texture": "#0"}, + "west": {"uv": [7, 6, 9, 9], "texture": "#0"} + } + }, + { + "name": "stem_upper", + "from": [6.5, 4, 12.5], + "to": [7.5, 9, 13.5], + "faces": { + "north": {"uv": [14, 4, 15, 9], "texture": "#0"}, + "east": {"uv": [14, 4, 15, 9], "texture": "#0"}, + "south": {"uv": [14, 4, 15, 9], "texture": "#0"}, + "west": {"uv": [14, 4, 15, 9], "texture": "#0"} + } + }, + { + "name": "cap_outside", + "from": [4, 4, 10], + "to": [10, 8, 16], + "shade": false, + "faces": { + "north": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "east": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "south": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "west": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} + } + }, + { + "name": "cap_inside", + "from": [10, 4, 10], + "to": [4, 8, 16], + "shade": false, + "faces": { + "north": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "east": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "south": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "west": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [5.5, 8, 11.5], + "to": [8.5, 12, 14.5], + "shade": false, + "faces": { + "north": {"uv": [13, 0, 16, 4], "texture": "#0"}, + "east": {"uv": [13, 0, 16, 4], "texture": "#0"}, + "south": {"uv": [13, 0, 16, 4], "texture": "#0"}, + "west": {"uv": [13, 0, 16, 4], "texture": "#0"}, + "up": {"uv": [1, 6, 4, 9], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + }, + { + "name": "bottom", + "from": [5, 3, 11], + "to": [9, 4, 15], + "shade": false, + "faces": { + "north": {"uv": [7, 4, 11, 5], "texture": "#0"}, + "east": {"uv": [7, 4, 11, 5], "texture": "#0"}, + "south": {"uv": [7, 4, 11, 5], "texture": "#0"}, + "west": {"uv": [7, 4, 11, 5], "texture": "#0"}, + "down": {"uv": [1, 11, 5, 15], "texture": "#0"} + } + } + ], + "groups": [ + { + "name": "small", + "origin": [0, 0, 0], + "color": 0, + "children": [0, + { + "name": "cap", + "origin": [8, 8, 8], + "color": 0, + "children": [1, 2] + }, 3, 4] + }, + { + "name": "medium", + "origin": [0, 0, 0], + "color": 0, + "children": [5, 6, + { + "name": "cap", + "origin": [8, 8, 8], + "color": 0, + "children": [7, 8] + }, 9, 10] + }, + { + "name": "large", + "origin": [0, 0, 0], + "color": 0, + "children": [11, 12, + { + "name": "cap", + "origin": [8, 8, 8], + "color": 0, + "children": [13, 14] + }, 15, 16] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/flammalix_2.json b/src/main/resources/assets/betterend/models/block/flammalix_2.json new file mode 100644 index 00000000..efb49fc3 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/flammalix_2.json @@ -0,0 +1,186 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "betterend:block/flammalix", + "particle": "betterend:block/flammalix" + }, + "elements": [ + { + "name": "stem_thick", + "from": [9.5, 0, 2.5], + "to": [11.5, 2, 4.5], + "faces": { + "north": {"uv": [6, 6, 8, 8], "texture": "#0"}, + "east": {"uv": [7, 6, 9, 8], "texture": "#0"}, + "south": {"uv": [6, 6, 8, 8], "texture": "#0"}, + "west": {"uv": [7, 6, 9, 8], "texture": "#0"} + } + }, + { + "name": "stem_upper", + "from": [10, 2, 3], + "to": [11, 5, 4], + "faces": { + "north": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "east": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "south": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "west": {"uv": [14, 4, 15, 7], "texture": "#0"} + } + }, + { + "name": "cap_outside", + "from": [8, 3, 1], + "to": [13, 7, 6], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "cap_inside", + "from": [13, 3, 1], + "to": [8, 7, 6], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [9, 5, 2], + "to": [12, 8, 5], + "shade": false, + "faces": { + "north": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "east": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "south": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "west": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "up": {"uv": [1, 6, 4, 9], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [9, 2, 2], + "to": [12, 3, 5], + "shade": false, + "faces": { + "north": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "east": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "south": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "west": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + }, + { + "name": "stem_thick", + "from": [4, 0, 10], + "to": [6, 3, 12], + "faces": { + "north": {"uv": [6, 6, 8, 9], "texture": "#0"}, + "east": {"uv": [7, 6, 9, 9], "texture": "#0"}, + "south": {"uv": [6, 6, 8, 9], "texture": "#0"}, + "west": {"uv": [7, 6, 9, 9], "texture": "#0"} + } + }, + { + "name": "stem_upper", + "from": [4.5, 4, 10.5], + "to": [5.5, 9, 11.5], + "faces": { + "north": {"uv": [14, 4, 15, 9], "texture": "#0"}, + "east": {"uv": [14, 4, 15, 9], "texture": "#0"}, + "south": {"uv": [14, 4, 15, 9], "texture": "#0"}, + "west": {"uv": [14, 4, 15, 9], "texture": "#0"} + } + }, + { + "name": "cap_outside", + "from": [2, 4, 8], + "to": [8, 8, 14], + "shade": false, + "faces": { + "north": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "east": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "south": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "west": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} + } + }, + { + "name": "cap_inside", + "from": [8, 4, 8], + "to": [2, 8, 14], + "shade": false, + "faces": { + "north": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "east": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "south": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "west": {"uv": [6, 0, 12, 4], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [3.5, 8, 9.5], + "to": [6.5, 12, 12.5], + "shade": false, + "faces": { + "north": {"uv": [13, 0, 16, 4], "texture": "#0"}, + "east": {"uv": [13, 0, 16, 4], "texture": "#0"}, + "south": {"uv": [13, 0, 16, 4], "texture": "#0"}, + "west": {"uv": [13, 0, 16, 4], "texture": "#0"}, + "up": {"uv": [1, 6, 4, 9], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + }, + { + "name": "bottom", + "from": [3, 3, 9], + "to": [7, 4, 13], + "shade": false, + "faces": { + "north": {"uv": [7, 4, 11, 5], "texture": "#0"}, + "east": {"uv": [7, 4, 11, 5], "texture": "#0"}, + "south": {"uv": [7, 4, 11, 5], "texture": "#0"}, + "west": {"uv": [7, 4, 11, 5], "texture": "#0"}, + "down": {"uv": [1, 11, 5, 15], "texture": "#0"} + } + } + ], + "groups": [ + { + "name": "medium", + "origin": [0, 0, 0], + "color": 0, + "children": [0, 1, + { + "name": "cap", + "origin": [8, 8, 8], + "color": 0, + "children": [2, 3] + }, 4, 5] + }, + { + "name": "large", + "origin": [0, 0, 0], + "color": 0, + "children": [6, 7, + { + "name": "cap", + "origin": [8, 8, 8], + "color": 0, + "children": [8, 9] + }, 10, 11] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/flammalix_3.json b/src/main/resources/assets/betterend/models/block/flammalix_3.json new file mode 100644 index 00000000..4be4def9 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/flammalix_3.json @@ -0,0 +1,175 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "betterend:block/flammalix", + "particle": "betterend:block/flammalix" + }, + "elements": [ + { + "name": "stem", + "from": [4, 0, 4], + "to": [5, 3, 5], + "faces": { + "north": {"uv": [14, 6, 15, 9], "texture": "#0"}, + "east": {"uv": [14, 6, 15, 9], "texture": "#0"}, + "south": {"uv": [14, 6, 15, 9], "texture": "#0"}, + "west": {"uv": [14, 6, 15, 9], "texture": "#0"} + } + }, + { + "name": "cap_outside", + "from": [2, 3, 2], + "to": [7, 7, 7], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "cap_inside", + "from": [7, 3, 2], + "to": [2, 7, 7], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [3, 4, 3], + "to": [6, 7, 6], + "shade": false, + "faces": { + "north": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "east": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "south": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "west": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "up": {"uv": [1, 6, 4, 9], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [3, 2, 3], + "to": [6, 3, 6], + "shade": false, + "faces": { + "north": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "east": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "south": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "west": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + }, + { + "name": "stem_thick", + "from": [10.5, 0, 10.5], + "to": [12.5, 2, 12.5], + "faces": { + "north": {"uv": [6, 6, 8, 8], "texture": "#0"}, + "east": {"uv": [7, 6, 9, 8], "texture": "#0"}, + "south": {"uv": [6, 6, 8, 8], "texture": "#0"}, + "west": {"uv": [7, 6, 9, 8], "texture": "#0"} + } + }, + { + "name": "stem_upper", + "from": [11, 2, 11], + "to": [12, 5, 12], + "faces": { + "north": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "east": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "south": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "west": {"uv": [14, 4, 15, 7], "texture": "#0"} + } + }, + { + "name": "cap_outside", + "from": [9, 3, 9], + "to": [14, 7, 14], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "cap_inside", + "from": [14, 3, 9], + "to": [9, 7, 14], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [10, 5, 10], + "to": [13, 8, 13], + "shade": false, + "faces": { + "north": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "east": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "south": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "west": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "up": {"uv": [1, 6, 4, 9], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [10, 2, 10], + "to": [13, 3, 13], + "shade": false, + "faces": { + "north": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "east": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "south": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "west": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + } + ], + "groups": [ + { + "name": "small", + "origin": [0, 0, 0], + "color": 0, + "children": [0, + { + "name": "cap", + "origin": [8, 8, 8], + "color": 0, + "children": [1, 2] + }, 3, 4] + }, + { + "name": "medium", + "origin": [0, 0, 0], + "color": 0, + "children": [5, 6, + { + "name": "cap", + "origin": [8, 8, 8], + "color": 0, + "children": [7, 8] + }, 9, 10] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/flammalix_4.json b/src/main/resources/assets/betterend/models/block/flammalix_4.json new file mode 100644 index 00000000..be931203 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/flammalix_4.json @@ -0,0 +1,99 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "betterend:block/flammalix", + "particle": "betterend:block/flammalix" + }, + "elements": [ + { + "name": "stem_thick", + "from": [7.5, 0, 8.5], + "to": [9.5, 2, 10.5], + "faces": { + "north": {"uv": [6, 6, 8, 8], "texture": "#0"}, + "east": {"uv": [7, 6, 9, 8], "texture": "#0"}, + "south": {"uv": [6, 6, 8, 8], "texture": "#0"}, + "west": {"uv": [7, 6, 9, 8], "texture": "#0"} + } + }, + { + "name": "stem_upper", + "from": [8, 2, 9], + "to": [9, 5, 10], + "faces": { + "north": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "east": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "south": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "west": {"uv": [14, 4, 15, 7], "texture": "#0"} + } + }, + { + "name": "cap_outside", + "from": [6, 3, 7], + "to": [11, 7, 12], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "cap_inside", + "from": [11, 3, 7], + "to": [6, 7, 12], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [7, 5, 8], + "to": [10, 8, 11], + "shade": false, + "faces": { + "north": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "east": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "south": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "west": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "up": {"uv": [1, 6, 4, 9], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [7, 2, 8], + "to": [10, 3, 11], + "shade": false, + "faces": { + "north": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "east": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "south": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "west": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + } + ], + "groups": [ + { + "name": "medium", + "origin": [0, 0, 0], + "color": 0, + "children": [0, 1, + { + "name": "cap", + "origin": [8, 8, 8], + "color": 0, + "children": [2, 3] + }, 4, 5] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/flammalix_potted.json b/src/main/resources/assets/betterend/models/block/flammalix_potted.json new file mode 100644 index 00000000..a0dbdec6 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/flammalix_potted.json @@ -0,0 +1,99 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "betterend:block/flammalix", + "particle": "betterend:block/flammalix" + }, + "elements": [ + { + "name": "stem_thick", + "from": [7, 0, 7], + "to": [9, 2, 9], + "faces": { + "north": {"uv": [6, 6, 8, 8], "texture": "#0"}, + "east": {"uv": [7, 6, 9, 8], "texture": "#0"}, + "south": {"uv": [6, 6, 8, 8], "texture": "#0"}, + "west": {"uv": [7, 6, 9, 8], "texture": "#0"} + } + }, + { + "name": "stem_upper", + "from": [7.5, 2, 7.5], + "to": [8.5, 5, 8.5], + "faces": { + "north": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "east": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "south": {"uv": [14, 4, 15, 7], "texture": "#0"}, + "west": {"uv": [14, 4, 15, 7], "texture": "#0"} + } + }, + { + "name": "cap_outside", + "from": [5.5, 3, 5.5], + "to": [10.5, 7, 10.5], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "cap_inside", + "from": [10.5, 3, 5.5], + "to": [5.5, 7, 10.5], + "shade": false, + "faces": { + "north": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 5, 4], "texture": "#0"}, + "down": {"uv": [0, 5, 5, 10], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [6.5, 5, 6.5], + "to": [9.5, 8, 9.5], + "shade": false, + "faces": { + "north": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "east": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "south": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "west": {"uv": [13, 0, 16, 3], "texture": "#0"}, + "up": {"uv": [1, 6, 4, 9], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + }, + { + "name": "bulb", + "from": [6.5, 2, 6.5], + "to": [9.5, 3, 9.5], + "shade": false, + "faces": { + "north": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "east": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "south": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "west": {"uv": [1, 4, 4, 5], "texture": "#0"}, + "down": {"uv": [1, 6, 4, 9], "texture": "#0"} + } + } + ], + "groups": [ + { + "name": "medium", + "origin": [0, 0, 0], + "color": 0, + "children": [0, 1, + { + "name": "cap", + "origin": [8, 8, 8], + "color": 0, + "children": [2, 3] + }, 4, 5] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/fracturn_potted.json b/src/main/resources/assets/betterend/models/block/fracturn_potted.json new file mode 100644 index 00000000..a0e565f8 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/fracturn_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/fracturn_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/globulagus_potted.json b/src/main/resources/assets/betterend/models/block/globulagus_potted.json new file mode 100644 index 00000000..c028d9af --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/globulagus_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/globulagus_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/inflexia_potted.json b/src/main/resources/assets/betterend/models/block/inflexia_potted.json new file mode 100644 index 00000000..aa15c800 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/inflexia_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/inflexia_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/jungle_grass_potted.json b/src/main/resources/assets/betterend/models/block/jungle_grass_potted.json new file mode 100644 index 00000000..ad6ab68f --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/jungle_grass_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/jungle_grass_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/lamellarium_potted.json b/src/main/resources/assets/betterend/models/block/lamellarium_potted.json new file mode 100644 index 00000000..745763a0 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/lamellarium_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/lamellarium_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/lit_pedestal_bottom.json b/src/main/resources/assets/betterend/models/block/lit_pedestal_bottom.json new file mode 100644 index 00000000..747e639b --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/lit_pedestal_bottom.json @@ -0,0 +1,47 @@ +{ + "parent": "minecraft:block/block", + "textures": { + "particle": "#base" + }, + "elements": [ + { + "__comment": "basin_1", + "from": [ 0, 0, 0 ], + "to": [ 16, 3, 16 ], + "shade": false, + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom" }, + "north": { "uv": [ 0, 0, 16, 3 ], "texture": "#bottom" }, + "south": { "uv": [ 0, 0, 16, 3 ], "texture": "#bottom" }, + "west": { "uv": [ 0, 0, 16, 3 ], "texture": "#bottom" }, + "east": { "uv": [ 0, 0, 16, 3 ], "texture": "#bottom" } + } + }, + { + "__comment": "basin_2", + "from": [ 2, 3, 2 ], + "to": [ 14, 4, 14 ], + "shade": false, + "faces": { + "up": { "uv": [ 2, 2, 14, 14 ], "texture": "#bottom" }, + "north": { "uv": [ 3, 3, 14, 4 ], "texture": "#bottom" }, + "south": { "uv": [ 3, 3, 14, 4 ], "texture": "#bottom" }, + "west": { "uv": [ 3, 3, 14, 4 ], "texture": "#bottom" }, + "east": { "uv": [ 3, 3, 14, 4 ], "texture": "#bottom" } + } + }, + { + "__comment": "pillar", + "from": [ 3, 4, 3 ], + "to": [ 13, 16, 13 ], + "shade": false, + "faces": { + "north": { "uv": [ 3, 4, 13, 16 ], "texture": "#pillar" }, + "south": { "uv": [ 3, 4, 13, 16 ], "texture": "#pillar" }, + "west": { "uv": [ 3, 4, 13, 16 ], "texture": "#pillar" }, + "east": { "uv": [ 3, 4, 13, 16 ], "texture": "#pillar" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/lit_pedestal_column.json b/src/main/resources/assets/betterend/models/block/lit_pedestal_column.json new file mode 100644 index 00000000..651265cd --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/lit_pedestal_column.json @@ -0,0 +1,74 @@ +{ + "parent": "minecraft:block/block", + "textures": { + "particle": "#base" + }, + "elements": [ + { + "__comment": "basin_1", + "from": [ 0, 0, 0 ], + "to": [ 16, 3, 16 ], + "shade": false, + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom" }, + "north": { "uv": [ 0, 0, 16, 3 ], "texture": "#bottom" }, + "south": { "uv": [ 0, 0, 16, 3 ], "texture": "#bottom" }, + "west": { "uv": [ 0, 0, 16, 3 ], "texture": "#bottom" }, + "east": { "uv": [ 0, 0, 16, 3 ], "texture": "#bottom" } + } + }, + { + "__comment": "basin_2", + "from": [ 2, 3, 2 ], + "to": [ 14, 4, 14 ], + "shade": false, + "faces": { + "up": { "uv": [ 2, 2, 14, 14 ], "texture": "#bottom" }, + "north": { "uv": [ 3, 3, 14, 4 ], "texture": "#bottom" }, + "south": { "uv": [ 3, 3, 14, 4 ], "texture": "#bottom" }, + "west": { "uv": [ 3, 3, 14, 4 ], "texture": "#bottom" }, + "east": { "uv": [ 3, 3, 14, 4 ], "texture": "#bottom" } + } + }, + { + "__comment": "pillar", + "from": [ 3, 4, 3 ], + "to": [ 13, 13, 13 ], + "shade": false, + "faces": { + "north": { "uv": [ 3, 4, 13, 14 ], "texture": "#pillar" }, + "south": { "uv": [ 3, 4, 13, 14 ], "texture": "#pillar" }, + "west": { "uv": [ 3, 4, 13, 14 ], "texture": "#pillar" }, + "east": { "uv": [ 3, 4, 13, 14 ], "texture": "#pillar" } + } + }, + { + "__comment": "top", + "from": [ 2, 13, 2 ], + "to": [ 14, 14, 14 ], + "shade": false, + "faces": { + "down": { "uv": [ 2, 2, 14, 14 ], "texture": "#base" }, + "north": { "uv": [ 2, 13, 14, 14 ], "texture": "#base" }, + "south": { "uv": [ 2, 13, 14, 14 ], "texture": "#base" }, + "west": { "uv": [ 2, 13, 14, 14 ], "texture": "#base" }, + "east": { "uv": [ 2, 13, 14, 14 ], "texture": "#base" } + } + }, + { + "__comment": "top", + "from": [ 1, 14, 1 ], + "to": [ 15, 16, 15 ], + "shade": false, + "faces": { + "down": { "uv": [ 1, 1, 15, 15 ], "texture": "#base" }, + "up": { "uv": [ 1, 1, 15, 15 ], "texture": "#base", "cullface": "up" }, + "north": { "uv": [ 1, 14, 15, 16 ], "texture": "#base" }, + "south": { "uv": [ 1, 14, 15, 16 ], "texture": "#base" }, + "west": { "uv": [ 1, 14, 15, 16 ], "texture": "#base" }, + "east": { "uv": [ 1, 14, 15, 16 ], "texture": "#base" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/lit_pedestal_column_top.json b/src/main/resources/assets/betterend/models/block/lit_pedestal_column_top.json new file mode 100644 index 00000000..3a88e975 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/lit_pedestal_column_top.json @@ -0,0 +1,47 @@ +{ + "parent": "minecraft:block/block", + "textures": { + "particle": "#base" + }, + "elements": [ + { + "__comment": "pillar", + "from": [ 3, 0, 3 ], + "to": [ 13, 13, 13 ], + "shade": false, + "faces": { + "north": { "uv": [ 3, 0, 13, 14 ], "texture": "#pillar" }, + "south": { "uv": [ 3, 0, 13, 14 ], "texture": "#pillar" }, + "west": { "uv": [ 3, 0, 13, 14 ], "texture": "#pillar" }, + "east": { "uv": [ 3, 0, 13, 14 ], "texture": "#pillar" } + } + }, + { + "__comment": "top", + "from": [ 2, 13, 2 ], + "to": [ 14, 14, 14 ], + "shade": false, + "faces": { + "down": { "uv": [ 2, 2, 14, 14 ], "texture": "#base" }, + "north": { "uv": [ 2, 13, 14, 14 ], "texture": "#base" }, + "south": { "uv": [ 2, 13, 14, 14 ], "texture": "#base" }, + "west": { "uv": [ 2, 13, 14, 14 ], "texture": "#base" }, + "east": { "uv": [ 2, 13, 14, 14 ], "texture": "#base" } + } + }, + { + "__comment": "top", + "from": [ 1, 14, 1 ], + "to": [ 15, 16, 15 ], + "shade": false, + "faces": { + "down": { "uv": [ 1, 1, 15, 15 ], "texture": "#base" }, + "up": { "uv": [ 1, 1, 15, 15 ], "texture": "#base", "cullface": "up" }, + "north": { "uv": [ 1, 14, 15, 16 ], "texture": "#base" }, + "south": { "uv": [ 1, 14, 15, 16 ], "texture": "#base" }, + "west": { "uv": [ 1, 14, 15, 16 ], "texture": "#base" }, + "east": { "uv": [ 1, 14, 15, 16 ], "texture": "#base" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/lit_pedestal_default.json b/src/main/resources/assets/betterend/models/block/lit_pedestal_default.json new file mode 100644 index 00000000..b4dfd5e7 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/lit_pedestal_default.json @@ -0,0 +1,61 @@ +{ + "parent": "minecraft:block/block", + "textures": { + "particle": "#base" + }, + "elements": [ + { + "__comment": "basin_1", + "from": [ 0, 0, 0 ], + "to": [ 16, 3, 16 ], + "shade": false, + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom" }, + "north": { "uv": [ 0, 0, 16, 3 ], "texture": "#bottom" }, + "south": { "uv": [ 0, 0, 16, 3 ], "texture": "#bottom" }, + "west": { "uv": [ 0, 0, 16, 3 ], "texture": "#bottom" }, + "east": { "uv": [ 0, 0, 16, 3 ], "texture": "#bottom" } + } + }, + { + "__comment": "basin_2", + "from": [ 2, 3, 2 ], + "to": [ 14, 4, 14 ], + "shade": false, + "faces": { + "up": { "uv": [ 2, 2, 14, 14 ], "texture": "#bottom" }, + "north": { "uv": [ 3, 3, 14, 4 ], "texture": "#bottom" }, + "south": { "uv": [ 3, 3, 14, 4 ], "texture": "#bottom" }, + "west": { "uv": [ 3, 3, 14, 4 ], "texture": "#bottom" }, + "east": { "uv": [ 3, 3, 14, 4 ], "texture": "#bottom" } + } + }, + { + "__comment": "pillar", + "from": [ 3, 4, 3 ], + "to": [ 13, 12, 13 ], + "shade": false, + "faces": { + "north": { "uv": [ 3, 4, 13, 12 ], "texture": "#pillar" }, + "south": { "uv": [ 3, 4, 13, 12 ], "texture": "#pillar" }, + "west": { "uv": [ 3, 4, 13, 12 ], "texture": "#pillar" }, + "east": { "uv": [ 3, 4, 13, 12 ], "texture": "#pillar" } + } + }, + { + "__comment": "top", + "from": [ 1, 12, 1 ], + "to": [ 15, 14, 15 ], + "shade": false, + "faces": { + "down": { "uv": [ 1, 1, 15, 15 ], "texture": "#base" }, + "up": { "uv": [ 1, 1, 15, 15 ], "texture": "#top" }, + "north": { "uv": [ 1, 12, 15, 14 ], "texture": "#base" }, + "south": { "uv": [ 1, 12, 15, 14 ], "texture": "#base" }, + "west": { "uv": [ 1, 12, 15, 14 ], "texture": "#base" }, + "east": { "uv": [ 1, 12, 15, 14 ], "texture": "#base" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/lit_pedestal_pillar.json b/src/main/resources/assets/betterend/models/block/lit_pedestal_pillar.json new file mode 100644 index 00000000..797d66ce --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/lit_pedestal_pillar.json @@ -0,0 +1,20 @@ +{ + "parent": "minecraft:block/block", + "textures": { + "particle": "#pillar" + }, + "elements": [ + { + "__comment": "pillar", + "from": [ 3, 0, 3 ], + "to": [ 13, 16, 13 ], + "shade": false, + "faces": { + "north": { "uv": [ 3, 0, 13, 16 ], "texture": "#pillar" }, + "south": { "uv": [ 3, 0, 13, 16 ], "texture": "#pillar" }, + "west": { "uv": [ 3, 0, 13, 16 ], "texture": "#pillar" }, + "east": { "uv": [ 3, 0, 13, 16 ], "texture": "#pillar" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/lit_pedestal_top.json b/src/main/resources/assets/betterend/models/block/lit_pedestal_top.json new file mode 100644 index 00000000..5886f233 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/lit_pedestal_top.json @@ -0,0 +1,34 @@ +{ + "parent": "minecraft:block/block", + "textures": { + "particle": "#base" + }, + "elements": [ + { + "__comment": "pillar", + "from": [ 3, 0, 3 ], + "to": [ 13, 8, 13 ], + "shade": false, + "faces": { + "north": { "uv": [ 3, 0, 13, 8 ], "texture": "#pillar" }, + "south": { "uv": [ 3, 0, 13, 8 ], "texture": "#pillar" }, + "west": { "uv": [ 3, 0, 13, 8 ], "texture": "#pillar" }, + "east": { "uv": [ 3, 0, 13, 8 ], "texture": "#pillar" } + } + }, + { + "__comment": "top", + "from": [ 1, 8, 1 ], + "to": [ 15, 10, 15 ], + "shade": false, + "faces": { + "down": { "uv": [ 1, 1, 15, 15 ], "texture": "#base" }, + "up": { "uv": [ 1, 1, 15, 15 ], "texture": "#top" }, + "north": { "uv": [ 1, 8, 15, 10 ], "texture": "#base" }, + "south": { "uv": [ 1, 8, 15, 10 ], "texture": "#base" }, + "west": { "uv": [ 1, 8, 15, 10 ], "texture": "#base" }, + "east": { "uv": [ 1, 8, 15, 10 ], "texture": "#base" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/lit_stairs.json b/src/main/resources/assets/betterend/models/block/lit_stairs.json new file mode 100644 index 00000000..45326109 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/lit_stairs.json @@ -0,0 +1,50 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "display": { + "gui": { + "rotation": [ 30, 135, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.625, 0.625, 0.625 ] + }, + "head": { + "rotation": [ 0, -90, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 1, 1, 1 ] + }, + "thirdperson_lefthand": { + "rotation": [ 75, -135, 0 ], + "translation": [ 0, 2.5, 0], + "scale": [ 0.375, 0.375, 0.375 ] + } + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 8, 16 ], + "shade": false, + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "north": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "north" }, + "south": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "south" }, + "west": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "west" }, + "east": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "east" } + } + }, + { + "from": [ 8, 8, 0 ], + "to": [ 16, 16, 16 ], + "shade": false, + "faces": { + "up": { "uv": [ 8, 0, 16, 16 ], "texture": "#top", "cullface": "up" }, + "north": { "uv": [ 0, 0, 8, 8 ], "texture": "#side", "cullface": "north" }, + "south": { "uv": [ 8, 0, 16, 8 ], "texture": "#side", "cullface": "south" }, + "west": { "uv": [ 0, 0, 16, 8 ], "texture": "#side" }, + "east": { "uv": [ 0, 0, 16, 8 ], "texture": "#side", "cullface": "east" } + } + } + ] +} diff --git a/src/main/resources/assets/betterend/models/block/lit_stairs_inner.json b/src/main/resources/assets/betterend/models/block/lit_stairs_inner.json new file mode 100644 index 00000000..d9ee9b90 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/lit_stairs_inner.json @@ -0,0 +1,44 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 8, 16 ], + "shade": false, + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "north": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "north" }, + "south": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "south" }, + "west": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "west" }, + "east": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "east" } + } + }, + { + "from": [ 8, 8, 0 ], + "to": [ 16, 16, 16 ], + "shade": false, + "faces": { + "up": { "uv": [ 8, 0, 16, 16 ], "texture": "#top", "cullface": "up" }, + "north": { "uv": [ 0, 0, 8, 8 ], "texture": "#side", "cullface": "north" }, + "south": { "uv": [ 8, 0, 16, 8 ], "texture": "#side", "cullface": "south" }, + "west": { "uv": [ 0, 0, 16, 8 ], "texture": "#side" }, + "east": { "uv": [ 0, 0, 16, 8 ], "texture": "#side", "cullface": "east" } + } + }, + { + "from": [ 0, 8, 8 ], + "to": [ 8, 16, 16 ], + "shade": false, + "faces": { + "up": { "uv": [ 0, 8, 8, 16 ], "texture": "#top", "cullface": "up" }, + "north": { "uv": [ 8, 0, 16, 8 ], "texture": "#side" }, + "south": { "uv": [ 0, 0, 8, 8 ], "texture": "#side", "cullface": "south" }, + "west": { "uv": [ 8, 0, 16, 8 ], "texture": "#side", "cullface": "west" } + } + } + ] +} diff --git a/src/main/resources/assets/betterend/models/block/lit_stairs_outer.json b/src/main/resources/assets/betterend/models/block/lit_stairs_outer.json new file mode 100644 index 00000000..13725a18 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/lit_stairs_outer.json @@ -0,0 +1,33 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 8, 16 ], + "shade": false, + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "north": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "north" }, + "south": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "south" }, + "west": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "west" }, + "east": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "east" } + } + }, + { + "from": [ 8, 8, 8 ], + "to": [ 16, 16, 16 ], + "shade": false, + "faces": { + "up": { "uv": [ 8, 8, 16, 16 ], "texture": "#top", "cullface": "up" }, + "north": { "uv": [ 0, 0, 8, 8 ], "texture": "#side" }, + "south": { "uv": [ 8, 0, 16, 8 ], "texture": "#side", "cullface": "south" }, + "west": { "uv": [ 8, 0, 16, 8 ], "texture": "#side" }, + "east": { "uv": [ 0, 0, 8, 8 ], "texture": "#side", "cullface": "east" } + } + } + ] +} diff --git a/src/main/resources/assets/betterend/models/block/lit_wall_post.json b/src/main/resources/assets/betterend/models/block/lit_wall_post.json new file mode 100644 index 00000000..48859b0c --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/lit_wall_post.json @@ -0,0 +1,21 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#wall" + }, + "elements": [ + { "from": [ 4, 0, 4 ], + "to": [ 12, 16, 12 ], + "shade": false, + "faces": { + "down": { "texture": "#wall", "cullface": "down" }, + "up": { "texture": "#wall", "cullface": "up" }, + "north": { "texture": "#wall" }, + "south": { "texture": "#wall" }, + "west": { "texture": "#wall" }, + "east": { "texture": "#wall" } + }, + "__comment": "Center post" + } + ] +} diff --git a/src/main/resources/assets/betterend/models/block/lit_wall_side.json b/src/main/resources/assets/betterend/models/block/lit_wall_side.json new file mode 100644 index 00000000..27d8698c --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/lit_wall_side.json @@ -0,0 +1,20 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#wall" + }, + "elements": [ + { "from": [ 5, 0, 0 ], + "to": [ 11, 14, 8 ], + "shade": false, + "faces": { + "down": { "texture": "#wall", "cullface": "down" }, + "up": { "texture": "#wall" }, + "north": { "texture": "#wall", "cullface": "north" }, + "west": { "texture": "#wall" }, + "east": { "texture": "#wall" } + }, + "__comment": "wall" + } + ] +} diff --git a/src/main/resources/assets/betterend/models/block/lit_wall_side_tall.json b/src/main/resources/assets/betterend/models/block/lit_wall_side_tall.json new file mode 100644 index 00000000..ee0dfab1 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/lit_wall_side_tall.json @@ -0,0 +1,19 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#wall" + }, + "elements": [ + { "from": [ 5, 0, 0 ], + "to": [ 11, 16, 8 ], + "shade": false, + "faces": { + "down": { "texture": "#wall", "cullface": "down" }, + "up": { "texture": "#wall", "cullface": "up"}, + "north": { "texture": "#wall", "cullface": "north" }, + "west": { "texture": "#wall" }, + "east": { "texture": "#wall" } + } + } + ] +} diff --git a/src/main/resources/assets/betterend/models/block/murkweed_potted.json b/src/main/resources/assets/betterend/models/block/murkweed_potted.json new file mode 100644 index 00000000..07ec3599 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/murkweed_potted.json @@ -0,0 +1,163 @@ +{ + "__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio", + "parent": "block/block", + "textures": { + "particle": "betterend:block/murkweed", + "texture": "betterend:block/murkweed" + }, + "elements": [ + { + "__comment": "Box1", + "from": [ 5, 11, 3 ], + "to": [ 9, 15, 7 ], + "faces": { + "down": { "uv": [ 4, 12, 8, 16 ], "texture": "#texture" }, + "up": { "uv": [ 0, 8, 4, 12 ], "texture": "#texture" }, + "north": { "uv": [ 0, 12, 4, 16 ], "texture": "#texture" }, + "south": { "uv": [ 0, 12, 4, 16 ], "texture": "#texture" }, + "west": { "uv": [ 0, 12, 4, 16 ], "texture": "#texture" }, + "east": { "uv": [ 0, 12, 4, 16 ], "texture": "#texture" } + } + }, + { + "__comment": "Box1", + "from": [ 6, 15, 4 ], + "to": [ 8, 15.5, 6 ], + "faces": { + "north": { "uv": [ 1, 7.5, 3, 8 ], "texture": "#texture" }, + "south": { "uv": [ 1, 7.5, 3, 8 ], "texture": "#texture" }, + "west": { "uv": [ 1, 7.5, 3, 8 ], "texture": "#texture" }, + "east": { "uv": [ 1, 7.5, 3, 8 ], "texture": "#texture" } + } + }, + { + "__comment": "Box1", + "from": [ 5.5, 15.5, 3.5 ], + "to": [ 8.5, 16, 6.5 ], + "faces": { + "down": { "uv": [ 0, 4, 3, 7 ], "texture": "#texture" }, + "up": { "uv": [ 0, 4, 3, 7 ], "texture": "#texture" }, + "north": { "uv": [ 0, 6.5, 3, 7 ], "texture": "#texture" }, + "south": { "uv": [ 0, 6.5, 3, 7 ], "texture": "#texture" }, + "west": { "uv": [ 0, 6.5, 3, 7 ], "texture": "#texture" }, + "east": { "uv": [ 0, 6.5, 3, 7 ], "texture": "#texture" } + } + }, + { + "__comment": "PlaneX4", + "from": [ 5, 0, 2.5 ], + "to": [ 5.001, 11, 8.5 ], + "rotation": { "origin": [ 5, 0, 2.5 ], "axis": "y", "angle": 45 }, + "shade": false, + "faces": { + "west": { "uv": [ 10, 0, 16, 16 ], "texture": "#texture" }, + "east": { "uv": [ 10, 0, 16, 16 ], "texture": "#texture" } + } + }, + { + "__comment": "PlaneX4", + "from": [ 9, 0, 2.5 ], + "to": [ 9.000999, 11, 8.5 ], + "rotation": { "origin": [ 9, 0, 2.5 ], "axis": "y", "angle": -45 }, + "shade": false, + "faces": { + "west": { "uv": [ 10, 0, 16, 12 ], "texture": "#texture" }, + "east": { "uv": [ 10, 0, 16, 12 ], "texture": "#texture" } + } + }, + { + "__comment": "PlaneX4", + "from": [ 9, 0, 6.5 ], + "to": [ 9.000999, 9, 12.5 ], + "rotation": { "origin": [ 9, 0, 6.5 ], "axis": "y", "angle": 45 }, + "shade": false, + "faces": { + "west": { "uv": [ 10, 4, 16, 13 ], "texture": "#texture" }, + "east": { "uv": [ 10, 4, 16, 13 ], "texture": "#texture" } + } + }, + { + "__comment": "PlaneX4", + "from": [ 13, 0, 6.5 ], + "to": [ 13.001, 9, 12.5 ], + "rotation": { "origin": [ 13, 0, 6.5 ], "axis": "y", "angle": -45 }, + "shade": false, + "faces": { + "west": { "uv": [ 10, 4, 16, 13 ], "texture": "#texture" }, + "east": { "uv": [ 10, 4, 16, 13 ], "texture": "#texture" } + } + }, + { + "__comment": "PlaneX4", + "from": [ 4.5, 0, 7.5 ], + "to": [ 4.501, 5, 13.5 ], + "rotation": { "origin": [ 4.5, 0, 7.5 ], "axis": "y", "angle": 45 }, + "shade": false, + "faces": { + "west": { "uv": [ 10, 8, 16, 13 ], "texture": "#texture" }, + "east": { "uv": [ 10, 8, 16, 13 ], "texture": "#texture" } + } + }, + { + "__comment": "PlaneX4", + "from": [ 8.5, 0, 7.5 ], + "to": [ 8.500999, 5, 13.5 ], + "rotation": { "origin": [ 8.5, 0, 7.5 ], "axis": "y", "angle": -45 }, + "shade": false, + "faces": { + "west": { "uv": [ 10, 8, 16, 13 ], "texture": "#texture" }, + "east": { "uv": [ 10, 8, 16, 13 ], "texture": "#texture" } + } + }, + { + "__comment": "Box1", + "from": [ 9, 9, 7 ], + "to": [ 13, 13, 11 ], + "faces": { + "down": { "uv": [ 4, 12, 8, 16 ], "texture": "#texture" }, + "up": { "uv": [ 0, 8, 4, 12 ], "texture": "#texture" }, + "north": { "uv": [ 0, 12, 4, 16 ], "texture": "#texture" }, + "south": { "uv": [ 0, 12, 4, 16 ], "texture": "#texture" }, + "west": { "uv": [ 0, 12, 4, 16 ], "texture": "#texture" }, + "east": { "uv": [ 0, 12, 4, 16 ], "texture": "#texture" } + } + }, + { + "__comment": "Box1", + "from": [ 10, 13, 9 ], + "to": [ 12, 13.5, 11 ], + "faces": { + "north": { "uv": [ 1, 7.5, 3, 8 ], "texture": "#texture" }, + "south": { "uv": [ 1, 7.5, 3, 8 ], "texture": "#texture" }, + "west": { "uv": [ 1, 7.5, 3, 8 ], "texture": "#texture" }, + "east": { "uv": [ 1, 7.5, 3, 8 ], "texture": "#texture" } + } + }, + { + "__comment": "Box1", + "from": [ 9.5, 13.5, 7.5 ], + "to": [ 12.5, 14, 10.5 ], + "faces": { + "down": { "uv": [ 0, 4, 3, 7 ], "texture": "#texture" }, + "up": { "uv": [ 0, 4, 3, 7 ], "texture": "#texture" }, + "north": { "uv": [ 0, 6.5, 3, 7 ], "texture": "#texture" }, + "south": { "uv": [ 0, 6.5, 3, 7 ], "texture": "#texture" }, + "west": { "uv": [ 0, 6.5, 3, 7 ], "texture": "#texture" }, + "east": { "uv": [ 0, 6.5, 3, 7 ], "texture": "#texture" } + } + }, + { + "__comment": "Box1", + "from": [ 5, 5, 8 ], + "to": [ 8, 9, 11 ], + "faces": { + "down": { "uv": [ 4, 12, 7, 15 ], "texture": "#texture" }, + "up": { "uv": [ 0, 8, 3, 11 ], "texture": "#texture" }, + "north": { "uv": [ 0, 12, 4, 16 ], "texture": "#texture" }, + "south": { "uv": [ 0, 12, 4, 16 ], "texture": "#texture" }, + "west": { "uv": [ 0, 12, 4, 16 ], "texture": "#texture" }, + "east": { "uv": [ 0, 12, 4, 16 ], "texture": "#texture" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/neon_cactus_potted.json b/src/main/resources/assets/betterend/models/block/neon_cactus_potted.json new file mode 100644 index 00000000..b194651f --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/neon_cactus_potted.json @@ -0,0 +1,45 @@ +{ + "__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio", + "textures": { + "particle": "betterend:block/neon_cactus_small_side", + "side": "betterend:block/neon_cactus_small_side_moss", + "top": "betterend:block/neon_cactus_small_top" + }, + "elements": [ + { + "__comment": "Box1", + "from": [ 6, 0, 6 ], + "to": [ 10, 8, 10 ], + "shade": false, + "faces": { + "up": { "uv": [ 6, 6, 10, 10 ], "texture": "#top" }, + "north": { "uv": [ 7, 6, 11, 14 ], "texture": "#side" }, + "south": { "uv": [ 7, 6, 11, 14 ], "texture": "#side" }, + "west": { "uv": [ 5, 6, 9, 14 ], "texture": "#side" }, + "east": { "uv": [ 5, 6, 9, 14 ], "texture": "#side" } + } + }, + { + "__comment": "PlaneX2", + "from": [ 4, 0, 4 ], + "to": [ 4.001, 8, 15.5 ], + "rotation": { "origin": [ 4, 0, 4 ], "axis": "y", "angle": 45 }, + "shade": false, + "faces": { + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#side" }, + "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#side" } + } + }, + { + "__comment": "PlaneX2", + "from": [ 12, 0, 4 ], + "to": [ 12.001, 8, 15.5 ], + "rotation": { "origin": [ 12, 0, 4 ], "axis": "y", "angle": -45 }, + "shade": false, + "faces": { + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#side" }, + "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#side" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/neon_cactus_slab.json b/src/main/resources/assets/betterend/models/block/neon_cactus_slab.json index 22fb196b..ccd83a76 100644 --- a/src/main/resources/assets/betterend/models/block/neon_cactus_slab.json +++ b/src/main/resources/assets/betterend/models/block/neon_cactus_slab.json @@ -1,5 +1,5 @@ { - "parent": "block/slab", + "parent": "betterend:block/slab_noshade", "textures": { "bottom": "betterend:block/neon_cactus_block_top", "top": "betterend:block/neon_cactus_block_top", diff --git a/src/main/resources/assets/betterend/models/block/neon_cactus_stairs.json b/src/main/resources/assets/betterend/models/block/neon_cactus_stairs.json index 0a0df2b2..bae5dffd 100644 --- a/src/main/resources/assets/betterend/models/block/neon_cactus_stairs.json +++ b/src/main/resources/assets/betterend/models/block/neon_cactus_stairs.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:block/stairs", + "parent": "betterend:block/lit_stairs", "textures": { "bottom": "betterend:block/neon_cactus_block_top", "top": "betterend:block/neon_cactus_block_top", diff --git a/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_inner.json b/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_inner.json index 78d80cc5..2eecc8e2 100644 --- a/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_inner.json +++ b/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_inner.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:block/inner_stairs", + "parent": "betterend:block/lit_stairs_inner", "textures": { "bottom": "betterend:block/neon_cactus_block_top", "top": "betterend:block/neon_cactus_block_top", diff --git a/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_outer.json b/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_outer.json index 01f12961..ead881f0 100644 --- a/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_outer.json +++ b/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_outer.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:block/outer_stairs", + "parent": "betterend:block/lit_stairs_outer", "textures": { "bottom": "betterend:block/neon_cactus_block_top", "top": "betterend:block/neon_cactus_block_top", diff --git a/src/main/resources/assets/betterend/models/block/pillar_noshade.json b/src/main/resources/assets/betterend/models/block/pillar_noshade.json new file mode 100644 index 00000000..cf1bd8de --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/pillar_noshade.json @@ -0,0 +1,21 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "shade": false, + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#end", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#end", "cullface": "up" }, + "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "north" }, + "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "south" }, + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "west" }, + "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "east" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/shadow_plant_potted.json b/src/main/resources/assets/betterend/models/block/shadow_plant_potted.json new file mode 100644 index 00000000..747d552e --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/shadow_plant_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/shadow_plant_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/block/slab_noshade.json b/src/main/resources/assets/betterend/models/block/slab_noshade.json new file mode 100644 index 00000000..e629ba9e --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/slab_noshade.json @@ -0,0 +1,20 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { "from": [ 0, 0, 0 ], + "to": [ 16, 8, 16 ], + "shade": false, + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "north": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "north" }, + "south": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "south" }, + "west": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "west" }, + "east": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "east" } + } + } + ] +} diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_bricks_stairs.json b/src/main/resources/assets/betterend/models/block/smaragdant_bricks_stairs.json new file mode 100644 index 00000000..6200b8c2 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_bricks_stairs.json @@ -0,0 +1,8 @@ +{ + "parent": "betterend:block/lit_stairs", + "textures": { + "bottom": "betterend:block/smaragdant_crystal_bricks", + "top": "betterend:block/smaragdant_crystal_bricks", + "side": "betterend:block/smaragdant_crystal_bricks" + } +} diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_bricks_stairs_inner.json b/src/main/resources/assets/betterend/models/block/smaragdant_bricks_stairs_inner.json new file mode 100644 index 00000000..f0ac1df0 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_bricks_stairs_inner.json @@ -0,0 +1,8 @@ +{ + "parent": "betterend:block/lit_stairs_inner", + "textures": { + "bottom": "betterend:block/smaragdant_crystal_bricks", + "top": "betterend:block/smaragdant_crystal_bricks", + "side": "betterend:block/smaragdant_crystal_bricks" + } +} diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_bricks_stairs_outer.json b/src/main/resources/assets/betterend/models/block/smaragdant_bricks_stairs_outer.json new file mode 100644 index 00000000..ed02dfcd --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_bricks_stairs_outer.json @@ -0,0 +1,8 @@ +{ + "parent": "betterend:block/lit_stairs_outer", + "textures": { + "bottom": "betterend:block/smaragdant_crystal_bricks", + "top": "betterend:block/smaragdant_crystal_bricks", + "side": "betterend:block/smaragdant_crystal_bricks" + } +} diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_crystal_bricks_wall_post.json b/src/main/resources/assets/betterend/models/block/smaragdant_crystal_bricks_wall_post.json new file mode 100644 index 00000000..e74131d0 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_crystal_bricks_wall_post.json @@ -0,0 +1,6 @@ +{ + "parent": "betterend:block/lit_wall_post", + "textures": { + "wall": "betterend:block/smaragdant_crystal_bricks" + } +} diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_crystal_bricks_wall_side.json b/src/main/resources/assets/betterend/models/block/smaragdant_crystal_bricks_wall_side.json new file mode 100644 index 00000000..ad9b2c94 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_crystal_bricks_wall_side.json @@ -0,0 +1,6 @@ +{ + "parent": "betterend:block/lit_wall_side", + "textures": { + "wall": "betterend:block/smaragdant_crystal_bricks" + } +} diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_crystal_bricks_wall_side_tall.json b/src/main/resources/assets/betterend/models/block/smaragdant_crystal_bricks_wall_side_tall.json new file mode 100644 index 00000000..c49dacb0 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_crystal_bricks_wall_side_tall.json @@ -0,0 +1,6 @@ +{ + "parent": "betterend:block/lit_wall_side_tall", + "textures": { + "wall": "betterend:block/smaragdant_crystal_bricks" + } +} diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_crystal_wall_post.json b/src/main/resources/assets/betterend/models/block/smaragdant_crystal_wall_post.json new file mode 100644 index 00000000..c5e167df --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_crystal_wall_post.json @@ -0,0 +1,23 @@ +{ + "parent": "block/block", + "textures": { + "side": "betterend:block/smaragdant_crystal_side", + "top": "betterend:block/smaragdant_crystal_top", + "particle": "#side" + }, + "elements": [ + { + "from": [ 4, -0.01, 4 ], + "to": [ 12, 16, 12 ], + "shade": false, + "faces": { + "down": { "uv": [ 4, 4, 12, 12 ], "texture": "#top", "cullface": "down" }, + "up": { "uv": [ 4, 4, 12, 12 ], "texture": "#top", "cullface": "up" }, + "north": { "uv": [ 4, 0, 12, 16 ], "texture": "#side" }, + "south": { "uv": [ 4, 0, 12, 16 ], "texture": "#side" }, + "west": { "uv": [ 4, 0, 12, 16 ], "texture": "#side" }, + "east": { "uv": [ 4, 0, 12, 16 ], "texture": "#side" } + } + } + ] +} diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_crystal_wall_side.json b/src/main/resources/assets/betterend/models/block/smaragdant_crystal_wall_side.json new file mode 100644 index 00000000..4bba9abf --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_crystal_wall_side.json @@ -0,0 +1,21 @@ +{ + "textures": { + "wall": "betterend:block/smaragdant_crystal_side", + "top": "betterend:block/smaragdant_crystal_top", + "particle": "#wall" + }, + "elements": [ + { + "from": [ 5, 0, 0 ], + "to": [ 11, 14, 8 ], + "shade": false, + "faces": { + "down": { "texture": "#top", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#wall", "cullface": "north" }, + "west": { "texture": "#wall" }, + "east": { "texture": "#wall" } + } + } + ] +} diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_crystal_wall_side_tall.json b/src/main/resources/assets/betterend/models/block/smaragdant_crystal_wall_side_tall.json new file mode 100644 index 00000000..dac2fa44 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_crystal_wall_side_tall.json @@ -0,0 +1,21 @@ +{ + "textures": { + "wall": "betterend:block/smaragdant_crystal_side", + "top": "betterend:block/smaragdant_crystal_top", + "particle": "#wall" + }, + "elements": [ + { + "from": [ 5, 0, 0 ], + "to": [ 11, 16, 8 ], + "shade": false, + "faces": { + "down": { "texture": "#top", "cullface": "down" }, + "up": { "texture": "#top", "cullface": "up"}, + "north": { "texture": "#wall", "cullface": "north" }, + "west": { "texture": "#wall" }, + "east": { "texture": "#wall" } + } + } + ] +} diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_bottom.json b/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_bottom.json new file mode 100644 index 00000000..d4f4423b --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_bottom.json @@ -0,0 +1,8 @@ +{ + "parent": "betterend:block/lit_pedestal_bottom", + "textures": { + "base": "betterend:block/smaragdant_crystal_side", + "pillar": "betterend:block/smaragdant_crystal_pillar_side", + "bottom": "betterend:block/smaragdant_crystal_polished" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_column.json b/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_column.json new file mode 100644 index 00000000..aba32bf3 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_column.json @@ -0,0 +1,8 @@ +{ + "parent": "betterend:block/lit_pedestal_column", + "textures": { + "base": "betterend:block/smaragdant_crystal_side", + "pillar": "betterend:block/smaragdant_crystal_pillar_side", + "bottom": "betterend:block/smaragdant_crystal_polished" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_column_top.json b/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_column_top.json new file mode 100644 index 00000000..2f8a7add --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_column_top.json @@ -0,0 +1,7 @@ +{ + "parent": "betterend:block/lit_pedestal_column_top", + "textures": { + "base": "betterend:block/smaragdant_crystal_side", + "pillar": "betterend:block/smaragdant_crystal_pillar_side" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_default.json b/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_default.json new file mode 100644 index 00000000..07e36ccc --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_default.json @@ -0,0 +1,9 @@ +{ + "parent": "betterend:block/lit_pedestal_default", + "textures": { + "top": "betterend:block/smaragdant_crystal_polished", + "base": "betterend:block/smaragdant_crystal_side", + "pillar": "betterend:block/smaragdant_crystal_pillar_side", + "bottom": "betterend:block/smaragdant_crystal_polished" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_pillar.json b/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_pillar.json new file mode 100644 index 00000000..2041fe88 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_pillar.json @@ -0,0 +1,6 @@ +{ + "parent": "betterend:block/lit_pedestal_pillar", + "textures": { + "pillar": "betterend:block/smaragdant_crystal_pillar_side" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_top.json b/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_top.json new file mode 100644 index 00000000..7f586614 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_pedestal_top.json @@ -0,0 +1,8 @@ +{ + "parent": "betterend:block/lit_pedestal_top", + "textures": { + "top": "betterend:block/smaragdant_crystal_polished", + "base": "betterend:block/smaragdant_crystal_side", + "pillar": "betterend:block/smaragdant_crystal_pillar_side" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_slab.json b/src/main/resources/assets/betterend/models/block/smaragdant_slab.json new file mode 100644 index 00000000..19f5cca8 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_slab.json @@ -0,0 +1,8 @@ +{ + "parent": "betterend:block/slab_noshade", + "textures": { + "bottom": "betterend:block/smaragdant_crystal_top", + "top": "betterend:block/smaragdant_crystal_top", + "side": "betterend:block/smaragdant_crystal_side" + } +} diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_stairs.json b/src/main/resources/assets/betterend/models/block/smaragdant_stairs.json new file mode 100644 index 00000000..288366da --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_stairs.json @@ -0,0 +1,8 @@ +{ + "parent": "betterend:block/lit_stairs", + "textures": { + "bottom": "betterend:block/smaragdant_crystal_top", + "top": "betterend:block/smaragdant_crystal_top", + "side": "betterend:block/smaragdant_crystal_side" + } +} diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_stairs_inner.json b/src/main/resources/assets/betterend/models/block/smaragdant_stairs_inner.json new file mode 100644 index 00000000..2339f001 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_stairs_inner.json @@ -0,0 +1,8 @@ +{ + "parent": "betterend:block/lit_stairs_inner", + "textures": { + "bottom": "betterend:block/smaragdant_crystal_top", + "top": "betterend:block/smaragdant_crystal_top", + "side": "betterend:block/smaragdant_crystal_side" + } +} diff --git a/src/main/resources/assets/betterend/models/block/smaragdant_stairs_outer.json b/src/main/resources/assets/betterend/models/block/smaragdant_stairs_outer.json new file mode 100644 index 00000000..380d63db --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/smaragdant_stairs_outer.json @@ -0,0 +1,8 @@ +{ + "parent": "betterend:block/lit_stairs_outer", + "textures": { + "bottom": "betterend:block/smaragdant_crystal_top", + "top": "betterend:block/smaragdant_crystal_top", + "side": "betterend:block/smaragdant_crystal_side" + } +} diff --git a/src/main/resources/assets/betterend/models/block/umbralith_1.json b/src/main/resources/assets/betterend/models/block/umbralith_1.json new file mode 100644 index 00000000..8db9f234 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/umbralith_1.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "betterend:block/umbralith" + } +} diff --git a/src/main/resources/assets/betterend/models/block/umbralith_2.json b/src/main/resources/assets/betterend/models/block/umbralith_2.json new file mode 100644 index 00000000..61f6c8a9 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/umbralith_2.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "betterend:block/umbralith_2" + } +} diff --git a/src/main/resources/assets/betterend/models/block/umbralith_3.json b/src/main/resources/assets/betterend/models/block/umbralith_3.json new file mode 100644 index 00000000..d6992e52 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/umbralith_3.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "betterend:block/umbralith_3" + } +} diff --git a/src/main/resources/assets/betterend/models/block/umbralith_4.json b/src/main/resources/assets/betterend/models/block/umbralith_4.json new file mode 100644 index 00000000..ff896e16 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/umbralith_4.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "betterend:block/umbralith_4" + } +} diff --git a/src/main/resources/assets/betterend/models/block/umbralith_5.json b/src/main/resources/assets/betterend/models/block/umbralith_5.json new file mode 100644 index 00000000..c9136b9b --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/umbralith_5.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "betterend:block/umbralith_5" + } +} diff --git a/src/main/resources/assets/betterend/models/block/umbralith_6.json b/src/main/resources/assets/betterend/models/block/umbralith_6.json new file mode 100644 index 00000000..63ce05b1 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/umbralith_6.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "betterend:block/umbralith_6" + } +} diff --git a/src/main/resources/assets/betterend/models/block/umbralith_7.json b/src/main/resources/assets/betterend/models/block/umbralith_7.json new file mode 100644 index 00000000..b1b81960 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/umbralith_7.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "betterend:block/umbralith_7" + } +} diff --git a/src/main/resources/assets/betterend/models/block/vaiolush_fern_potted.json b/src/main/resources/assets/betterend/models/block/vaiolush_fern_potted.json new file mode 100644 index 00000000..5a915f54 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/vaiolush_fern_potted.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cross", + "textures": { + "cross": "betterend:block/vaiolush_fern_potted" + } +} diff --git a/src/main/resources/assets/betterend/models/item/crystal_moss_cover.json b/src/main/resources/assets/betterend/models/item/crystal_moss_cover.json new file mode 100644 index 00000000..60fdc61c --- /dev/null +++ b/src/main/resources/assets/betterend/models/item/crystal_moss_cover.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "betterend:block/crystal_moss_cover" + } +} diff --git a/src/main/resources/assets/minecraft/models/item/custom_chorus_flower.json b/src/main/resources/assets/betterend/models/item/custom_chorus_flower.json similarity index 94% rename from src/main/resources/assets/minecraft/models/item/custom_chorus_flower.json rename to src/main/resources/assets/betterend/models/item/custom_chorus_flower.json index c26d27c1..30047d60 100644 --- a/src/main/resources/assets/minecraft/models/item/custom_chorus_flower.json +++ b/src/main/resources/assets/betterend/models/item/custom_chorus_flower.json @@ -1,3 +1,3 @@ -{ - "parent": "betterend:block/chorus_plant_flower" -} +{ + "parent": "betterend:block/chorus_plant_flower" +} diff --git a/src/main/resources/assets/minecraft/models/item/custom_chorus_plant.json b/src/main/resources/assets/betterend/models/item/custom_chorus_plant.json similarity index 94% rename from src/main/resources/assets/minecraft/models/item/custom_chorus_plant.json rename to src/main/resources/assets/betterend/models/item/custom_chorus_plant.json index 70794d60..96bfea4d 100644 --- a/src/main/resources/assets/minecraft/models/item/custom_chorus_plant.json +++ b/src/main/resources/assets/betterend/models/item/custom_chorus_plant.json @@ -1,3 +1,3 @@ -{ - "parent": "betterend:block/chorus_plant_center" -} +{ + "parent": "betterend:block/chorus_plant_center" +} diff --git a/src/main/resources/assets/betterend/models/item/smaragdant_crystal_bricks_stairs.json b/src/main/resources/assets/betterend/models/item/smaragdant_crystal_bricks_stairs.json new file mode 100644 index 00000000..92b2603b --- /dev/null +++ b/src/main/resources/assets/betterend/models/item/smaragdant_crystal_bricks_stairs.json @@ -0,0 +1,3 @@ +{ + "parent": "betterend:block/smaragdant_bricks_stairs" +} diff --git a/src/main/resources/assets/betterend/models/item/smaragdant_crystal_bricks_wall.json b/src/main/resources/assets/betterend/models/item/smaragdant_crystal_bricks_wall.json new file mode 100644 index 00000000..b89dc3ef --- /dev/null +++ b/src/main/resources/assets/betterend/models/item/smaragdant_crystal_bricks_wall.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/wall_inventory", + "textures": { + "wall": "betterend:block/smaragdant_crystal_bricks" + } +} diff --git a/src/main/resources/assets/betterend/models/item/smaragdant_crystal_pedestal.json b/src/main/resources/assets/betterend/models/item/smaragdant_crystal_pedestal.json new file mode 100644 index 00000000..ca50eb45 --- /dev/null +++ b/src/main/resources/assets/betterend/models/item/smaragdant_crystal_pedestal.json @@ -0,0 +1,3 @@ +{ + "parent": "betterend:block/smaragdant_pedestal_default" +} diff --git a/src/main/resources/assets/betterend/models/item/smaragdant_crystal_slab.json b/src/main/resources/assets/betterend/models/item/smaragdant_crystal_slab.json new file mode 100644 index 00000000..1099667b --- /dev/null +++ b/src/main/resources/assets/betterend/models/item/smaragdant_crystal_slab.json @@ -0,0 +1,3 @@ +{ + "parent": "betterend:block/smaragdant_slab" +} diff --git a/src/main/resources/assets/betterend/models/item/smaragdant_crystal_stairs.json b/src/main/resources/assets/betterend/models/item/smaragdant_crystal_stairs.json new file mode 100644 index 00000000..7af759c0 --- /dev/null +++ b/src/main/resources/assets/betterend/models/item/smaragdant_crystal_stairs.json @@ -0,0 +1,3 @@ +{ + "parent": "betterend:block/smaragdant_stairs" +} diff --git a/src/main/resources/assets/betterend/models/item/smaragdant_crystal_wall.json b/src/main/resources/assets/betterend/models/item/smaragdant_crystal_wall.json new file mode 100644 index 00000000..4391b325 --- /dev/null +++ b/src/main/resources/assets/betterend/models/item/smaragdant_crystal_wall.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/wall_inventory", + "textures": { + "wall": "betterend:block/smaragdant_crystal_side" + } +} diff --git a/src/main/resources/assets/betterend/patterns/block/flower_pot.json b/src/main/resources/assets/betterend/patterns/block/flower_pot.json new file mode 100644 index 00000000..55088bf3 --- /dev/null +++ b/src/main/resources/assets/betterend/patterns/block/flower_pot.json @@ -0,0 +1,71 @@ +{ + "__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio", + "parent": "block/block", + "textures": { + "particle": "betterend:block/%texture%", + "texture": "betterend:block/%texture%" + }, + "elements": [ + { + "__comment": "Box1", + "from": [ 4, 7, 4 ], + "to": [ 12, 8, 12 ], + "faces": { + "down": { "uv": [ 8, 0, 16, 8 ], "texture": "#texture" }, + "up": { "uv": [ 8, 0, 16, 8 ], "texture": "#texture" }, + "north": { "uv": [ 0, 0, 8, 1 ], "texture": "#texture" }, + "south": { "uv": [ 0, 0, 8, 1 ], "texture": "#texture" }, + "west": { "uv": [ 0, 0, 8, 1 ], "texture": "#texture" }, + "east": { "uv": [ 0, 0, 8, 1 ], "texture": "#texture" } + } + }, + { + "__comment": "Box1", + "from": [ 5, 0, 5 ], + "to": [ 11, 1, 11 ], + "faces": { + "down": { "uv": [ 9, 9, 15, 15 ], "texture": "#texture", "cullface": "down" }, + "up": { "uv": [ 9, 9, 15, 15 ], "texture": "#texture" }, + "north": { "uv": [ 1, 7, 7, 8 ], "texture": "#texture" }, + "south": { "uv": [ 1, 7, 7, 8 ], "texture": "#texture" }, + "west": { "uv": [ 1, 7, 7, 8 ], "texture": "#texture" }, + "east": { "uv": [ 1, 7, 7, 8 ], "texture": "#texture" } + } + }, + { + "__comment": "Box1", + "from": [ 4, 1, 4 ], + "to": [ 12, 6, 12 ], + "faces": { + "down": { "uv": [ 8, 8, 16, 16 ], "texture": "#texture" }, + "up": { "uv": [ 8, 0, 16, 8 ], "texture": "#texture" }, + "north": { "uv": [ 0, 2, 8, 7 ], "texture": "#texture" }, + "south": { "uv": [ 0, 2, 8, 7 ], "texture": "#texture" }, + "west": { "uv": [ 0, 2, 8, 7 ], "texture": "#texture" }, + "east": { "uv": [ 0, 2, 8, 7 ], "texture": "#texture" } + } + }, + { + "__comment": "Box1", + "from": [ 4.5, 6, 4.5 ], + "to": [ 11.5, 7, 11.5 ], + "faces": { + "north": { "uv": [ 0.5, 1, 7.5, 2 ], "texture": "#texture" }, + "south": { "uv": [ 0.5, 1, 7.5, 2 ], "texture": "#texture" }, + "west": { "uv": [ 0.5, 1, 7.5, 2 ], "texture": "#texture" }, + "east": { "uv": [ 0.5, 1, 7.5, 2 ], "texture": "#texture" } + } + }, + { + "__comment": "Box14", + "from": [ 11, 8, 11 ], + "to": [ 5, 1, 5 ], + "faces": { + "north": { "uv": [ 1, 0, 7, 7 ], "texture": "#texture" }, + "south": { "uv": [ 1, 0, 7, 7 ], "texture": "#texture" }, + "west": { "uv": [ 1, 0, 7, 7 ], "texture": "#texture" }, + "east": { "uv": [ 1, 0, 7, 7 ], "texture": "#texture" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/patterns/block/flower_pot_soil.json b/src/main/resources/assets/betterend/patterns/block/flower_pot_soil.json new file mode 100644 index 00000000..224858f1 --- /dev/null +++ b/src/main/resources/assets/betterend/patterns/block/flower_pot_soil.json @@ -0,0 +1,17 @@ +{ + "__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio", + "textures": { + "particle": "betterend:block/%texture%", + "texture": "betterend:block/%texture%" + }, + "elements": [ + { + "__comment": "PlaneY1", + "from": [ 5, 7.5, 5 ], + "to": [ 11, 7.501, 11 ], + "faces": { + "up": { "uv": [ 5, 5, 11, 11 ], "texture": "#texture" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/patterns/block/potted_leaves.json b/src/main/resources/assets/betterend/patterns/block/potted_leaves.json new file mode 100644 index 00000000..8e2446f5 --- /dev/null +++ b/src/main/resources/assets/betterend/patterns/block/potted_leaves.json @@ -0,0 +1,35 @@ +{ + "__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio", + "textures": { + "particle": "betterend:block/%leaves%", + "stem": "betterend:block/%stem%", + "leaves": "betterend:block/%leaves%" + }, + "elements": [ + { + "__comment": "Box1", + "from": [ 3, 2, 3 ], + "to": [ 13, 12, 13 ], + "faces": { + "down": { "uv": [ 3, 3, 13, 13 ], "texture": "#leaves" }, + "up": { "uv": [ 3, 3, 13, 13 ], "texture": "#leaves" }, + "north": { "uv": [ 3, 3, 13, 13 ], "texture": "#leaves" }, + "south": { "uv": [ 3, 3, 13, 13 ], "texture": "#leaves" }, + "west": { "uv": [ 3, 3, 13, 13 ], "texture": "#leaves" }, + "east": { "uv": [ 3, 3, 13, 13 ], "texture": "#leaves" } + } + }, + { + "__comment": "Box1", + "from": [ 7, 0, 7 ], + "to": [ 9, 8, 9 ], + "faces": { + "up": { "uv": [ 7, 7, 9, 9 ], "texture": "#stem" }, + "north": { "uv": [ 7, 8, 9, 16 ], "texture": "#stem" }, + "south": { "uv": [ 7, 8, 9, 16 ], "texture": "#stem" }, + "west": { "uv": [ 7, 8, 9, 16 ], "texture": "#stem" }, + "east": { "uv": [ 7, 8, 9, 16 ], "texture": "#stem" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/sounds.json b/src/main/resources/assets/betterend/sounds.json index f0abe0dd..d44fd81c 100644 --- a/src/main/resources/assets/betterend/sounds.json +++ b/src/main/resources/assets/betterend/sounds.json @@ -219,6 +219,24 @@ } ] }, + "betterend.ambient.amber_land": { + "category": "ambient", + "sounds": [ + { + "name": "betterend:ambient/amber_land", + "stream": true + } + ] + }, + "betterend.ambient.umbra_valley": { + "category": "ambient", + "sounds": [ + { + "name": "betterend:ambient/umbra_valley", + "stream": true + } + ] + }, "betterend.entity.dragonfly": { "category": "entity", diff --git a/src/main/resources/assets/betterend/sounds/ambient/amber_land.ogg b/src/main/resources/assets/betterend/sounds/ambient/amber_land.ogg new file mode 100644 index 00000000..6b830cdb Binary files /dev/null and b/src/main/resources/assets/betterend/sounds/ambient/amber_land.ogg differ diff --git a/src/main/resources/assets/betterend/sounds/ambient/umbra_valley.ogg b/src/main/resources/assets/betterend/sounds/ambient/umbra_valley.ogg new file mode 100644 index 00000000..24c47c41 Binary files /dev/null and b/src/main/resources/assets/betterend/sounds/ambient/umbra_valley.ogg differ diff --git a/src/main/resources/assets/betterend/textures/block/aeridium.png b/src/main/resources/assets/betterend/textures/block/aeridium.png index ad97e778..17a33d94 100644 Binary files a/src/main/resources/assets/betterend/textures/block/aeridium.png and b/src/main/resources/assets/betterend/textures/block/aeridium.png differ diff --git a/src/main/resources/assets/betterend/textures/block/aeridium_e.png b/src/main/resources/assets/betterend/textures/block/aeridium_e.png index e3a7da6f..58437781 100644 Binary files a/src/main/resources/assets/betterend/textures/block/aeridium_e.png and b/src/main/resources/assets/betterend/textures/block/aeridium_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_back.png b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_back.png index 42d59708..bb067de0 100644 Binary files a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_back.png and b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_back.png differ diff --git a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_bottom.png b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_bottom.png index fbf5143b..be7e6940 100644 Binary files a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_bottom.png and b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_front.png b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_front.png index 9b2d22b6..7f6d0bed 100644 Binary files a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_front.png and b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_panel.png b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_panel.png index afdcd731..23e3472f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_panel.png and b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_panel.png differ diff --git a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_top_0.png b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_top_0.png index b206f373..51f7a0c9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_top_0.png and b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_top_0.png differ diff --git a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_top_1.png b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_top_1.png index 84380c58..a8f3fbfb 100644 Binary files a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_top_1.png and b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_top_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_top_2.png b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_top_2.png index 3e8e4f66..c350e957 100644 Binary files a/src/main/resources/assets/betterend/textures/block/aeternium_anvil_top_2.png and b/src/main/resources/assets/betterend/textures/block/aeternium_anvil_top_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/aeternium_block.png b/src/main/resources/assets/betterend/textures/block/aeternium_block.png index eae91fe3..f1bcfd01 100644 Binary files a/src/main/resources/assets/betterend/textures/block/aeternium_block.png and b/src/main/resources/assets/betterend/textures/block/aeternium_block.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amaranita_cap.png b/src/main/resources/assets/betterend/textures/block/amaranita_cap.png index 6b7fddd1..401157b9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amaranita_cap.png and b/src/main/resources/assets/betterend/textures/block/amaranita_cap.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amaranita_fur.png b/src/main/resources/assets/betterend/textures/block/amaranita_fur.png index e735e76d..ba1cf0c8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amaranita_fur.png and b/src/main/resources/assets/betterend/textures/block/amaranita_fur.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amaranita_hymenophore.png b/src/main/resources/assets/betterend/textures/block/amaranita_hymenophore.png index c25e3b08..790e74bb 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amaranita_hymenophore.png and b/src/main/resources/assets/betterend/textures/block/amaranita_hymenophore.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amaranita_hymenophore_fur.png b/src/main/resources/assets/betterend/textures/block/amaranita_hymenophore_fur.png index 8148cff5..8401e5da 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amaranita_hymenophore_fur.png and b/src/main/resources/assets/betterend/textures/block/amaranita_hymenophore_fur.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amaranita_hyphae_side.png b/src/main/resources/assets/betterend/textures/block/amaranita_hyphae_side.png index 2f4f4f63..a79e668f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amaranita_hyphae_side.png and b/src/main/resources/assets/betterend/textures/block/amaranita_hyphae_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amaranita_hyphae_top.png b/src/main/resources/assets/betterend/textures/block/amaranita_hyphae_top.png index e236e4d2..d6aa0e08 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amaranita_hyphae_top.png and b/src/main/resources/assets/betterend/textures/block/amaranita_hyphae_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amaranita_lantern.png b/src/main/resources/assets/betterend/textures/block/amaranita_lantern.png index dc669adb..bcaa73c2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amaranita_lantern.png and b/src/main/resources/assets/betterend/textures/block/amaranita_lantern.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amaranita_stem_middle.png b/src/main/resources/assets/betterend/textures/block/amaranita_stem_middle.png index 69ad1cad..af2df081 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amaranita_stem_middle.png and b/src/main/resources/assets/betterend/textures/block/amaranita_stem_middle.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amaranita_stem_roots.png b/src/main/resources/assets/betterend/textures/block/amaranita_stem_roots.png index f7317e51..2325249d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amaranita_stem_roots.png and b/src/main/resources/assets/betterend/textures/block/amaranita_stem_roots.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amaranita_stem_top.png b/src/main/resources/assets/betterend/textures/block/amaranita_stem_top.png index cb26d739..f4499f4e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amaranita_stem_top.png and b/src/main/resources/assets/betterend/textures/block/amaranita_stem_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amber_block.png b/src/main/resources/assets/betterend/textures/block/amber_block.png index 37c7e6e8..09bff026 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amber_block.png and b/src/main/resources/assets/betterend/textures/block/amber_block.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amber_grass.png b/src/main/resources/assets/betterend/textures/block/amber_grass.png index c78817cf..ce185a31 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amber_grass.png and b/src/main/resources/assets/betterend/textures/block/amber_grass.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amber_grass_potted.png b/src/main/resources/assets/betterend/textures/block/amber_grass_potted.png new file mode 100644 index 00000000..ca6b4005 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/amber_grass_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amber_moss_path_top.png b/src/main/resources/assets/betterend/textures/block/amber_moss_path_top.png index 740ed96e..737dd634 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amber_moss_path_top.png and b/src/main/resources/assets/betterend/textures/block/amber_moss_path_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amber_moss_side_1.png b/src/main/resources/assets/betterend/textures/block/amber_moss_side_1.png index cbf62819..08fa045b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amber_moss_side_1.png and b/src/main/resources/assets/betterend/textures/block/amber_moss_side_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amber_moss_side_2.png b/src/main/resources/assets/betterend/textures/block/amber_moss_side_2.png index 6d7b516a..4dd69984 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amber_moss_side_2.png and b/src/main/resources/assets/betterend/textures/block/amber_moss_side_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amber_moss_side_3.png b/src/main/resources/assets/betterend/textures/block/amber_moss_side_3.png index e59c23ce..4647e293 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amber_moss_side_3.png and b/src/main/resources/assets/betterend/textures/block/amber_moss_side_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amber_ore.png b/src/main/resources/assets/betterend/textures/block/amber_ore.png index 01f7bac4..9a350f66 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amber_ore.png and b/src/main/resources/assets/betterend/textures/block/amber_ore.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amber_root_0.png b/src/main/resources/assets/betterend/textures/block/amber_root_0.png index bccbce93..c86a64ce 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amber_root_0.png and b/src/main/resources/assets/betterend/textures/block/amber_root_0.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amber_root_1.png b/src/main/resources/assets/betterend/textures/block/amber_root_1.png index 7ca89b63..78e4bcbb 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amber_root_1.png and b/src/main/resources/assets/betterend/textures/block/amber_root_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amber_root_2.png b/src/main/resources/assets/betterend/textures/block/amber_root_2.png index 1a05d5f9..e7994694 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amber_root_2.png and b/src/main/resources/assets/betterend/textures/block/amber_root_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amber_root_3.png b/src/main/resources/assets/betterend/textures/block/amber_root_3.png index e9e6b445..979afbeb 100644 Binary files a/src/main/resources/assets/betterend/textures/block/amber_root_3.png and b/src/main/resources/assets/betterend/textures/block/amber_root_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/amber_root_potted.png b/src/main/resources/assets/betterend/textures/block/amber_root_potted.png new file mode 100644 index 00000000..e20493d5 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/amber_root_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/andesite_lantern_side.png b/src/main/resources/assets/betterend/textures/block/andesite_lantern_side.png index 4dc49ecd..408ad8d5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/andesite_lantern_side.png and b/src/main/resources/assets/betterend/textures/block/andesite_lantern_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/aurant_polypore.png b/src/main/resources/assets/betterend/textures/block/aurant_polypore.png index f3f94190..373b084e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/aurant_polypore.png and b/src/main/resources/assets/betterend/textures/block/aurant_polypore.png differ diff --git a/src/main/resources/assets/betterend/textures/block/aurant_polypore_e.png b/src/main/resources/assets/betterend/textures/block/aurant_polypore_e.png index 7d19a8a3..f5182e60 100644 Binary files a/src/main/resources/assets/betterend/textures/block/aurant_polypore_e.png and b/src/main/resources/assets/betterend/textures/block/aurant_polypore_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/aurora_crystal.png b/src/main/resources/assets/betterend/textures/block/aurora_crystal.png index 58a4de41..0f71be6d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/aurora_crystal.png and b/src/main/resources/assets/betterend/textures/block/aurora_crystal.png differ diff --git a/src/main/resources/assets/betterend/textures/block/azure_jadestone.png b/src/main/resources/assets/betterend/textures/block/azure_jadestone.png index b77aa314..2515a024 100644 Binary files a/src/main/resources/assets/betterend/textures/block/azure_jadestone.png and b/src/main/resources/assets/betterend/textures/block/azure_jadestone.png differ diff --git a/src/main/resources/assets/betterend/textures/block/azure_jadestone_flower_pot.png b/src/main/resources/assets/betterend/textures/block/azure_jadestone_flower_pot.png new file mode 100644 index 00000000..12390578 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/azure_jadestone_flower_pot.png differ diff --git a/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_front.png b/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_front.png index 85243b6b..d350e5f0 100644 Binary files a/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_front.png and b/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_front_on.png b/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_front_on.png index 8be6d6db..a88e392c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_front_on.png and b/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_front_on.png differ diff --git a/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_side.png b/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_side.png index d6f4c239..ca8c1602 100644 Binary files a/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_side.png and b/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_top.png b/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_top.png index 097f9402..509a9ba0 100644 Binary files a/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_top.png and b/src/main/resources/assets/betterend/textures/block/azure_jadestone_furnace_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/azure_jadestone_lantern_bottom.png b/src/main/resources/assets/betterend/textures/block/azure_jadestone_lantern_bottom.png index 690edaf9..e5669e06 100644 Binary files a/src/main/resources/assets/betterend/textures/block/azure_jadestone_lantern_bottom.png and b/src/main/resources/assets/betterend/textures/block/azure_jadestone_lantern_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/azure_jadestone_lantern_side.png b/src/main/resources/assets/betterend/textures/block/azure_jadestone_lantern_side.png index 4e406618..eebdce48 100644 Binary files a/src/main/resources/assets/betterend/textures/block/azure_jadestone_lantern_side.png and b/src/main/resources/assets/betterend/textures/block/azure_jadestone_lantern_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/azure_jadestone_lantern_top.png b/src/main/resources/assets/betterend/textures/block/azure_jadestone_lantern_top.png index 68aec9bd..9e235895 100644 Binary files a/src/main/resources/assets/betterend/textures/block/azure_jadestone_lantern_top.png and b/src/main/resources/assets/betterend/textures/block/azure_jadestone_lantern_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/blackstone_lantern_bottom.png b/src/main/resources/assets/betterend/textures/block/blackstone_lantern_bottom.png index 6756c1dd..73dbb03b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/blackstone_lantern_bottom.png and b/src/main/resources/assets/betterend/textures/block/blackstone_lantern_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/blackstone_lantern_side.png b/src/main/resources/assets/betterend/textures/block/blackstone_lantern_side.png index 8bde80b8..91bacf11 100644 Binary files a/src/main/resources/assets/betterend/textures/block/blackstone_lantern_side.png and b/src/main/resources/assets/betterend/textures/block/blackstone_lantern_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/blackstone_lantern_top.png b/src/main/resources/assets/betterend/textures/block/blackstone_lantern_top.png index f7d5f2b0..3b09e50c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/blackstone_lantern_top.png and b/src/main/resources/assets/betterend/textures/block/blackstone_lantern_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/blooming_cooksonia.png b/src/main/resources/assets/betterend/textures/block/blooming_cooksonia.png index 4cc6d5d8..c6f628bc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/blooming_cooksonia.png and b/src/main/resources/assets/betterend/textures/block/blooming_cooksonia.png differ diff --git a/src/main/resources/assets/betterend/textures/block/blooming_cooksonia_e.png b/src/main/resources/assets/betterend/textures/block/blooming_cooksonia_e.png index dbb75d68..2fdb0256 100644 Binary files a/src/main/resources/assets/betterend/textures/block/blooming_cooksonia_e.png and b/src/main/resources/assets/betterend/textures/block/blooming_cooksonia_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/blooming_cooksonia_potted.png b/src/main/resources/assets/betterend/textures/block/blooming_cooksonia_potted.png new file mode 100644 index 00000000..ae614749 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/blooming_cooksonia_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/blooming_cooksonia_potted_e.png b/src/main/resources/assets/betterend/textures/block/blooming_cooksonia_potted_e.png new file mode 100644 index 00000000..440aabfc Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/blooming_cooksonia_potted_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/blossom_berry_flower.png b/src/main/resources/assets/betterend/textures/block/blossom_berry_flower.png index ba9f2ee4..ce408433 100644 Binary files a/src/main/resources/assets/betterend/textures/block/blossom_berry_flower.png and b/src/main/resources/assets/betterend/textures/block/blossom_berry_flower.png differ diff --git a/src/main/resources/assets/betterend/textures/block/blossom_berry_seed_1.png b/src/main/resources/assets/betterend/textures/block/blossom_berry_seed_1.png index fe5bdee0..5080dd5e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/blossom_berry_seed_1.png and b/src/main/resources/assets/betterend/textures/block/blossom_berry_seed_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/blossom_berry_seed_2.png b/src/main/resources/assets/betterend/textures/block/blossom_berry_seed_2.png index 6b4242aa..7a7d2992 100644 Binary files a/src/main/resources/assets/betterend/textures/block/blossom_berry_seed_2.png and b/src/main/resources/assets/betterend/textures/block/blossom_berry_seed_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bolux_mushroom.png b/src/main/resources/assets/betterend/textures/block/bolux_mushroom.png index 8b869fa1..d259982e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bolux_mushroom.png and b/src/main/resources/assets/betterend/textures/block/bolux_mushroom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bolux_mushroom_e.png b/src/main/resources/assets/betterend/textures/block/bolux_mushroom_e.png index d90e929b..0bcf6f3f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bolux_mushroom_e.png and b/src/main/resources/assets/betterend/textures/block/bolux_mushroom_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_moss_bulbs.png b/src/main/resources/assets/betterend/textures/block/bulb_moss_bulbs.png index 185bb491..68ccceb3 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_moss_bulbs.png and b/src/main/resources/assets/betterend/textures/block/bulb_moss_bulbs.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_moss_bulbs_e.png b/src/main/resources/assets/betterend/textures/block/bulb_moss_bulbs_e.png index 55896402..4106a750 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_moss_bulbs_e.png and b/src/main/resources/assets/betterend/textures/block/bulb_moss_bulbs_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_moss_leaves.png b/src/main/resources/assets/betterend/textures/block/bulb_moss_leaves.png index 9881ee0a..5465b27a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_moss_leaves.png and b/src/main/resources/assets/betterend/textures/block/bulb_moss_leaves.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine.png b/src/main/resources/assets/betterend/textures/block/bulb_vine.png index 33fbcd10..a9ab55f8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine_fur.png b/src/main/resources/assets/betterend/textures/block/bulb_vine_fur.png index 3c39a774..90c1c075 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine_fur.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine_fur.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_bulb.png b/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_bulb.png index ea2f464a..e1d3a8db 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_bulb.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_bulb.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_bulb_e.png b/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_bulb_e.png index ea2f464a..e1d3a8db 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_bulb_e.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_bulb_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_overlay.png b/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_overlay.png index 8a3c1a3a..2ffa45a8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_overlay.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_overlay.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_overlay_e.png b/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_overlay_e.png index 8a3c1a3a..2ffa45a8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_overlay_e.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine_lantern_overlay_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine_middle.png b/src/main/resources/assets/betterend/textures/block/bulb_vine_middle.png index 23c43ab4..e5ce1b7c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine_middle.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine_middle.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_0.png b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_0.png index 08e67c4d..87662ff5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_0.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_0.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_1.png b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_1.png index a008b8ca..033e22e5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_1.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_1_e.png b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_1_e.png index 6430c866..c3848630 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_1_e.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_1_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_2.png b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_2.png index 3c46d166..0dc3c7cb 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_2.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_2_e.png b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_2_e.png index 511e9552..7c8ab9c3 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_2_e.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_2_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_3.png b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_3.png index 91beb0f1..5a15491f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_3.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_3_e.png b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_3_e.png index 651708a1..41213791 100644 Binary files a/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_3_e.png and b/src/main/resources/assets/betterend/textures/block/bulb_vine_seed_3_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/bushy_grass_potted.png b/src/main/resources/assets/betterend/textures/block/bushy_grass_potted.png new file mode 100644 index 00000000..0cd78fc1 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/bushy_grass_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_1.png b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_1.png index 0270aade..e8147836 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_1.png and b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_2.png b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_2.png index 232ab77d..a79a3fbf 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_2.png and b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_2_e.png b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_2_e.png index e2ebfeaa..b331f988 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_2_e.png and b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_2_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_3.png b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_3.png index 2261d204..f1f6b543 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_3.png and b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_3_e.png b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_3_e.png index f61e82a1..154913a3 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_3_e.png and b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_3_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_4.png b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_4.png index 99bb6a69..12fe93d9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_4.png and b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_4_e.png b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_4_e.png index 5cd9b25f..2b0e9247 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_4_e.png and b/src/main/resources/assets/betterend/textures/block/cave_bush_leaves_4_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_grass_1.png b/src/main/resources/assets/betterend/textures/block/cave_grass_1.png index fba927d7..c0356dec 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_grass_1.png and b/src/main/resources/assets/betterend/textures/block/cave_grass_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_grass_2.png b/src/main/resources/assets/betterend/textures/block/cave_grass_2.png index dde241fe..2ad3bca5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_grass_2.png and b/src/main/resources/assets/betterend/textures/block/cave_grass_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_grass_potted.png b/src/main/resources/assets/betterend/textures/block/cave_grass_potted.png new file mode 100644 index 00000000..bf379c2a Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/cave_grass_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_moss_side.png b/src/main/resources/assets/betterend/textures/block/cave_moss_side.png index 97aabc14..48c59b5e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_moss_side.png and b/src/main/resources/assets/betterend/textures/block/cave_moss_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_moss_top.png b/src/main/resources/assets/betterend/textures/block/cave_moss_top.png index 14eb1bae..7ae0ef4c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_moss_top.png and b/src/main/resources/assets/betterend/textures/block/cave_moss_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_lantern_bottom.png b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_lantern_bottom.png index 6c35ab7d..06a23b5a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_lantern_bottom.png and b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_lantern_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_lantern_side.png b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_lantern_side.png index 96e2e1f4..db30aa24 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_lantern_side.png and b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_lantern_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_side.png b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_side.png index 1a75960f..b46d2e62 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_side.png and b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_0.png b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_0.png index 01b6a719..9e761742 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_0.png and b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_0.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_1.png b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_1.png index 71f6391c..c3b72b15 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_1.png and b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_2.png b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_2.png index 7944679b..57abbd90 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_2.png and b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_3.png b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_3.png index 9b3607bd..c66cace9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_3.png and b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_stem_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_top.png b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_top.png index 821029c3..859f30be 100644 Binary files a/src/main/resources/assets/betterend/textures/block/cave_pumpkin_top.png and b/src/main/resources/assets/betterend/textures/block/cave_pumpkin_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/charcoal_block.png b/src/main/resources/assets/betterend/textures/block/charcoal_block.png index 8b3696b5..43ad3c8f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/charcoal_block.png and b/src/main/resources/assets/betterend/textures/block/charcoal_block.png differ diff --git a/src/main/resources/assets/betterend/textures/block/charnia_cyan.png b/src/main/resources/assets/betterend/textures/block/charnia_cyan.png index d038d3b3..cc93ab69 100644 Binary files a/src/main/resources/assets/betterend/textures/block/charnia_cyan.png and b/src/main/resources/assets/betterend/textures/block/charnia_cyan.png differ diff --git a/src/main/resources/assets/betterend/textures/block/charnia_green.png b/src/main/resources/assets/betterend/textures/block/charnia_green.png index 44851676..1443c1bd 100644 Binary files a/src/main/resources/assets/betterend/textures/block/charnia_green.png and b/src/main/resources/assets/betterend/textures/block/charnia_green.png differ diff --git a/src/main/resources/assets/betterend/textures/block/charnia_light_blue.png b/src/main/resources/assets/betterend/textures/block/charnia_light_blue.png index 1c68449b..c5754706 100644 Binary files a/src/main/resources/assets/betterend/textures/block/charnia_light_blue.png and b/src/main/resources/assets/betterend/textures/block/charnia_light_blue.png differ diff --git a/src/main/resources/assets/betterend/textures/block/charnia_orange.png b/src/main/resources/assets/betterend/textures/block/charnia_orange.png index db9ad3c2..35256a3c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/charnia_orange.png and b/src/main/resources/assets/betterend/textures/block/charnia_orange.png differ diff --git a/src/main/resources/assets/betterend/textures/block/charnia_purple.png b/src/main/resources/assets/betterend/textures/block/charnia_purple.png index f9901429..7e607ad1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/charnia_purple.png and b/src/main/resources/assets/betterend/textures/block/charnia_purple.png differ diff --git a/src/main/resources/assets/betterend/textures/block/charnia_red.png b/src/main/resources/assets/betterend/textures/block/charnia_red.png index eff3dcbe..152a3290 100644 Binary files a/src/main/resources/assets/betterend/textures/block/charnia_red.png and b/src/main/resources/assets/betterend/textures/block/charnia_red.png differ diff --git a/src/main/resources/assets/betterend/textures/block/chorus_grass_potted.png b/src/main/resources/assets/betterend/textures/block/chorus_grass_potted.png new file mode 100644 index 00000000..7c51f013 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/chorus_grass_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/chorus_mushroom_0.png b/src/main/resources/assets/betterend/textures/block/chorus_mushroom_0.png index 8162484c..6d58e8fd 100644 Binary files a/src/main/resources/assets/betterend/textures/block/chorus_mushroom_0.png and b/src/main/resources/assets/betterend/textures/block/chorus_mushroom_0.png differ diff --git a/src/main/resources/assets/betterend/textures/block/chorus_mushroom_2.png b/src/main/resources/assets/betterend/textures/block/chorus_mushroom_2.png index dcd8ddd9..609accf4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/chorus_mushroom_2.png and b/src/main/resources/assets/betterend/textures/block/chorus_mushroom_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/chorus_mushroom_3.png b/src/main/resources/assets/betterend/textures/block/chorus_mushroom_3.png index 5cfacd08..15ca654e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/chorus_mushroom_3.png and b/src/main/resources/assets/betterend/textures/block/chorus_mushroom_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/chorus_mushroom_potted.png b/src/main/resources/assets/betterend/textures/block/chorus_mushroom_potted.png new file mode 100644 index 00000000..1e7559cd Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/chorus_mushroom_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/chorus_nylium_path_top.png b/src/main/resources/assets/betterend/textures/block/chorus_nylium_path_top.png index dc0ea52d..6691aa7f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/chorus_nylium_path_top.png and b/src/main/resources/assets/betterend/textures/block/chorus_nylium_path_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/chorus_nylium_side.png b/src/main/resources/assets/betterend/textures/block/chorus_nylium_side.png index 5e41736f..4c256a8a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/chorus_nylium_side.png and b/src/main/resources/assets/betterend/textures/block/chorus_nylium_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/chorus_nylium_top.png b/src/main/resources/assets/betterend/textures/block/chorus_nylium_top.png index 46a6bded..27a59ac5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/chorus_nylium_top.png and b/src/main/resources/assets/betterend/textures/block/chorus_nylium_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/chorus_plant.png b/src/main/resources/assets/betterend/textures/block/chorus_plant.png index 828b15af..2cb4a85f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/chorus_plant.png and b/src/main/resources/assets/betterend/textures/block/chorus_plant.png differ diff --git a/src/main/resources/assets/betterend/textures/block/chorus_plant_2.png b/src/main/resources/assets/betterend/textures/block/chorus_plant_2.png index 0858a3b9..d80ab0ef 100644 Binary files a/src/main/resources/assets/betterend/textures/block/chorus_plant_2.png and b/src/main/resources/assets/betterend/textures/block/chorus_plant_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/chorus_plant_flower_bottom.png b/src/main/resources/assets/betterend/textures/block/chorus_plant_flower_bottom.png index 0211bbac..f3fd4918 100644 Binary files a/src/main/resources/assets/betterend/textures/block/chorus_plant_flower_bottom.png and b/src/main/resources/assets/betterend/textures/block/chorus_plant_flower_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/chorus_plant_flower_top.png b/src/main/resources/assets/betterend/textures/block/chorus_plant_flower_top.png index 4ecfbb72..dcc38ba9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/chorus_plant_flower_top.png and b/src/main/resources/assets/betterend/textures/block/chorus_plant_flower_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/clawfern.png b/src/main/resources/assets/betterend/textures/block/clawfern.png index 80214371..955c0fcd 100644 Binary files a/src/main/resources/assets/betterend/textures/block/clawfern.png and b/src/main/resources/assets/betterend/textures/block/clawfern.png differ diff --git a/src/main/resources/assets/betterend/textures/block/clawfern_potted.png b/src/main/resources/assets/betterend/textures/block/clawfern_potted.png new file mode 100644 index 00000000..6ea0d05f Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/clawfern_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/creeping_moss_spores.png b/src/main/resources/assets/betterend/textures/block/creeping_moss_spores.png index 02967e53..6b23f698 100644 Binary files a/src/main/resources/assets/betterend/textures/block/creeping_moss_spores.png and b/src/main/resources/assets/betterend/textures/block/creeping_moss_spores.png differ diff --git a/src/main/resources/assets/betterend/textures/block/crystal_grass_2.png b/src/main/resources/assets/betterend/textures/block/crystal_grass_2.png index 57d33eef..7d4ef32f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/crystal_grass_2.png and b/src/main/resources/assets/betterend/textures/block/crystal_grass_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/crystal_grass_4.png b/src/main/resources/assets/betterend/textures/block/crystal_grass_4.png index 517d3b0b..0cbffbba 100644 Binary files a/src/main/resources/assets/betterend/textures/block/crystal_grass_4.png and b/src/main/resources/assets/betterend/textures/block/crystal_grass_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/crystal_grass_5.png b/src/main/resources/assets/betterend/textures/block/crystal_grass_5.png index 0cebf007..f6b71d47 100644 Binary files a/src/main/resources/assets/betterend/textures/block/crystal_grass_5.png and b/src/main/resources/assets/betterend/textures/block/crystal_grass_5.png differ diff --git a/src/main/resources/assets/betterend/textures/block/crystal_moss_cover.png b/src/main/resources/assets/betterend/textures/block/crystal_moss_cover.png new file mode 100644 index 00000000..7cf966ed Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/crystal_moss_cover.png differ diff --git a/src/main/resources/assets/betterend/textures/block/crystal_moss_cover.png.mcmeta b/src/main/resources/assets/betterend/textures/block/crystal_moss_cover.png.mcmeta new file mode 100644 index 00000000..a5e7ebfa --- /dev/null +++ b/src/main/resources/assets/betterend/textures/block/crystal_moss_cover.png.mcmeta @@ -0,0 +1,6 @@ +{ + "animation": { + "frametime": 32, + "interpolate": true + } +} diff --git a/src/main/resources/assets/betterend/textures/block/dense_emerald_ice.png b/src/main/resources/assets/betterend/textures/block/dense_emerald_ice.png index e15cbaa2..c009cb67 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dense_emerald_ice.png and b/src/main/resources/assets/betterend/textures/block/dense_emerald_ice.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dense_snow.png b/src/main/resources/assets/betterend/textures/block/dense_snow.png index efbdb369..e6bd8330 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dense_snow.png and b/src/main/resources/assets/betterend/textures/block/dense_snow.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dense_vine.png b/src/main/resources/assets/betterend/textures/block/dense_vine.png index afab6cad..045cbdb0 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dense_vine.png and b/src/main/resources/assets/betterend/textures/block/dense_vine.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dense_vine_bottom.png b/src/main/resources/assets/betterend/textures/block/dense_vine_bottom.png index 26e92dc2..d5ccb1f2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dense_vine_bottom.png and b/src/main/resources/assets/betterend/textures/block/dense_vine_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_bone_block.png b/src/main/resources/assets/betterend/textures/block/dragon_bone_block.png index f238dda9..fc46f1a3 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_bone_block.png and b/src/main/resources/assets/betterend/textures/block/dragon_bone_block.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_bone_block_side.png b/src/main/resources/assets/betterend/textures/block/dragon_bone_block_side.png index 564ba177..c7eb460e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_bone_block_side.png and b/src/main/resources/assets/betterend/textures/block/dragon_bone_block_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_bone_block_top.png b/src/main/resources/assets/betterend/textures/block/dragon_bone_block_top.png index 3b204813..ba4fbf13 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_bone_block_top.png and b/src/main/resources/assets/betterend/textures/block/dragon_bone_block_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_barrel_top_open.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_barrel_top_open.png index 4b84f3a8..cd92a98e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_barrel_top_open.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_barrel_top_open.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_bookshelf.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_bookshelf.png index 3100943b..1130d672 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_bookshelf.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_bookshelf.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_composter_bottom.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_composter_bottom.png index e19cae90..77ed1c14 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_composter_bottom.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_composter_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_composter_side.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_composter_side.png index 7096c72d..d3ee8ce4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_composter_side.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_composter_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_composter_top.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_composter_top.png index dd049d0c..2b261f0b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_composter_top.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_composter_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_crafting_table_front.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_crafting_table_front.png index e4b0ca73..59202dd9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_crafting_table_front.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_crafting_table_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_crafting_table_side.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_crafting_table_side.png index 25f4f4ca..eca07d98 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_crafting_table_side.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_crafting_table_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_crafting_table_top.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_crafting_table_top.png index 7ad56b30..1883b2f5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_crafting_table_top.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_crafting_table_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_leaves.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_leaves.png index 05fbb1ac..ae764ead 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_leaves.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_leaves.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_log_side_2.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_log_side_2.png index c7fb2be0..b5e76c6d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_log_side_2.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_log_side_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_log_side_3.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_log_side_3.png index 5a70c312..52836190 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_log_side_3.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_log_side_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_log_side_4.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_log_side_4.png index 3e25118c..bb932882 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_log_side_4.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_log_side_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_log_top.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_log_top.png index 93f7fbfc..e17490a4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_log_top.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_planks.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_planks.png index 8a9ed37c..6f11a40c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_planks.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_planks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_sapling.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_sapling.png index 601ca187..45e14a8f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_sapling.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_sapling.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_stripped_log_side.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_stripped_log_side.png index f13d8e70..3dc84c13 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_stripped_log_side.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_stripped_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/dragon_tree_stripped_log_top.png b/src/main/resources/assets/betterend/textures/block/dragon_tree_stripped_log_top.png index 2d35fefa..27808db6 100644 Binary files a/src/main/resources/assets/betterend/textures/block/dragon_tree_stripped_log_top.png and b/src/main/resources/assets/betterend/textures/block/dragon_tree_stripped_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/emerald_ice.png b/src/main/resources/assets/betterend/textures/block/emerald_ice.png index 67b46600..1b75cb9e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/emerald_ice.png and b/src/main/resources/assets/betterend/textures/block/emerald_ice.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lily_leaf.png b/src/main/resources/assets/betterend/textures/block/end_lily_leaf.png index 7c13c283..742a04cb 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lily_leaf.png and b/src/main/resources/assets/betterend/textures/block/end_lily_leaf.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lily_leaf_dried.png b/src/main/resources/assets/betterend/textures/block/end_lily_leaf_dried.png index eb671ff2..6cc1df65 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lily_leaf_dried.png and b/src/main/resources/assets/betterend/textures/block/end_lily_leaf_dried.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lily_leaf_small.png b/src/main/resources/assets/betterend/textures/block/end_lily_leaf_small.png index 160df978..50af136c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lily_leaf_small.png and b/src/main/resources/assets/betterend/textures/block/end_lily_leaf_small.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lily_roots.png b/src/main/resources/assets/betterend/textures/block/end_lily_roots.png index aeb08eec..23e8d674 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lily_roots.png and b/src/main/resources/assets/betterend/textures/block/end_lily_roots.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lily_stem.png b/src/main/resources/assets/betterend/textures/block/end_lily_stem.png index 58581159..eceaaae5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lily_stem.png and b/src/main/resources/assets/betterend/textures/block/end_lily_stem.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_4.png b/src/main/resources/assets/betterend/textures/block/end_lotus_4.png index 578a3f03..557dc1bf 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_4.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_barrel_bottom.png b/src/main/resources/assets/betterend/textures/block/end_lotus_barrel_bottom.png index 42b733e5..fc94bdab 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_barrel_bottom.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_barrel_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_barrel_top.png b/src/main/resources/assets/betterend/textures/block/end_lotus_barrel_top.png index 44a75f2f..55e02cb1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_barrel_top.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_barrel_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_barrel_top_open.png b/src/main/resources/assets/betterend/textures/block/end_lotus_barrel_top_open.png index cbd97421..b4fa284f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_barrel_top_open.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_barrel_top_open.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_center.png b/src/main/resources/assets/betterend/textures/block/end_lotus_center.png index dd388ff8..a7c54ebb 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_center.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_center.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_center_2.png b/src/main/resources/assets/betterend/textures/block/end_lotus_center_2.png index 2254a18a..cdfd4fbe 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_center_2.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_center_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_center_2_e.png b/src/main/resources/assets/betterend/textures/block/end_lotus_center_2_e.png index 0bb66e45..a5e492bc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_center_2_e.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_center_2_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_center_e.png b/src/main/resources/assets/betterend/textures/block/end_lotus_center_e.png index f8c7e2e8..dfb1638a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_center_e.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_center_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_composter_bottom.png b/src/main/resources/assets/betterend/textures/block/end_lotus_composter_bottom.png index b720c226..45f7751b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_composter_bottom.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_composter_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_composter_side.png b/src/main/resources/assets/betterend/textures/block/end_lotus_composter_side.png index 303bf5ae..7d3a2b1b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_composter_side.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_composter_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_composter_top.png b/src/main/resources/assets/betterend/textures/block/end_lotus_composter_top.png index 315296fd..07f72aab 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_composter_top.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_composter_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_crafting_table_front.png b/src/main/resources/assets/betterend/textures/block/end_lotus_crafting_table_front.png index c1d3c5e4..5d191e93 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_crafting_table_front.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_crafting_table_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_crafting_table_top.png b/src/main/resources/assets/betterend/textures/block/end_lotus_crafting_table_top.png index 1a8f2759..049de61f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_crafting_table_top.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_crafting_table_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_door_bottom.png b/src/main/resources/assets/betterend/textures/block/end_lotus_door_bottom.png index 5cd2bb6b..50f8a411 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_door_bottom.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_door_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_door_top.png b/src/main/resources/assets/betterend/textures/block/end_lotus_door_top.png index 1e41acc0..759e5bd8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_door_top.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_door_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_center.png b/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_center.png index d6dd184c..46e03e0c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_center.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_center.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_corner.png b/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_corner.png index a8126c78..d3b33e7d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_corner.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_corner.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_cutout.png b/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_cutout.png index f3f2b748..d5851cc2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_cutout.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_cutout.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_side.png b/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_side.png index 70d1c67b..dd49f021 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_side.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_leaf_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_log_side.png b/src/main/resources/assets/betterend/textures/block/end_lotus_log_side.png index 461c85aa..0fe3f1f8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_log_side.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_petal.png b/src/main/resources/assets/betterend/textures/block/end_lotus_petal.png index 5834c996..cfbaa4cc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_petal.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_petal.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_petal_2.png b/src/main/resources/assets/betterend/textures/block/end_lotus_petal_2.png index 7f688b67..fa5888e5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_petal_2.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_petal_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_petal_2_e.png b/src/main/resources/assets/betterend/textures/block/end_lotus_petal_2_e.png index 7f688b67..fa5888e5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_petal_2_e.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_petal_2_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_petal_e.png b/src/main/resources/assets/betterend/textures/block/end_lotus_petal_e.png index 5834c996..cfbaa4cc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_petal_e.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_petal_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_stem.png b/src/main/resources/assets/betterend/textures/block/end_lotus_stem.png index b3d6ae69..6204c60a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_stem.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_stem.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_lotus_stripped_log_top.png b/src/main/resources/assets/betterend/textures/block/end_lotus_stripped_log_top.png index a9e6becf..c77ef193 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_lotus_stripped_log_top.png and b/src/main/resources/assets/betterend/textures/block/end_lotus_stripped_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_moss_side.png b/src/main/resources/assets/betterend/textures/block/end_moss_side.png index cc0449f7..b720e5f6 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_moss_side.png and b/src/main/resources/assets/betterend/textures/block/end_moss_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_moss_top.png b/src/main/resources/assets/betterend/textures/block/end_moss_top.png index de6139a4..a3ddcc5c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_moss_top.png and b/src/main/resources/assets/betterend/textures/block/end_moss_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_portal.png b/src/main/resources/assets/betterend/textures/block/end_portal.png index 4c79d3e2..d5ccc52a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_portal.png and b/src/main/resources/assets/betterend/textures/block/end_portal.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_portal_grey.png b/src/main/resources/assets/betterend/textures/block/end_portal_grey.png index c04fe031..9a90f2ed 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_portal_grey.png and b/src/main/resources/assets/betterend/textures/block/end_portal_grey.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_furnace_front.png b/src/main/resources/assets/betterend/textures/block/end_stone_furnace_front.png index 65e87503..3d219682 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_furnace_front.png and b/src/main/resources/assets/betterend/textures/block/end_stone_furnace_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_furnace_glow.png b/src/main/resources/assets/betterend/textures/block/end_stone_furnace_glow.png index 58dcd4a1..a04be26e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_furnace_glow.png and b/src/main/resources/assets/betterend/textures/block/end_stone_furnace_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_furnace_glow_e.png b/src/main/resources/assets/betterend/textures/block/end_stone_furnace_glow_e.png index 58dcd4a1..a04be26e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_furnace_glow_e.png and b/src/main/resources/assets/betterend/textures/block/end_stone_furnace_glow_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_furnace_top.png b/src/main/resources/assets/betterend/textures/block/end_stone_furnace_top.png index 5b79a56e..31c24e68 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_furnace_top.png and b/src/main/resources/assets/betterend/textures/block/end_stone_furnace_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_smelter_front.png b/src/main/resources/assets/betterend/textures/block/end_stone_smelter_front.png index 1ee9ea3c..2f878d06 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_smelter_front.png and b/src/main/resources/assets/betterend/textures/block/end_stone_smelter_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_smelter_front_on.png b/src/main/resources/assets/betterend/textures/block/end_stone_smelter_front_on.png index 47c3f431..cc91fda9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_smelter_front_on.png and b/src/main/resources/assets/betterend/textures/block/end_stone_smelter_front_on.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_smelter_side.png b/src/main/resources/assets/betterend/textures/block/end_stone_smelter_side.png index 3abdc94f..9640c177 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_smelter_side.png and b/src/main/resources/assets/betterend/textures/block/end_stone_smelter_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_smelter_top.png b/src/main/resources/assets/betterend/textures/block/end_stone_smelter_top.png index 71f47f4f..34e3641a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_smelter_top.png and b/src/main/resources/assets/betterend/textures/block/end_stone_smelter_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_0.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_0.png index 21690cf5..706e1ea8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_0.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_0.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_1.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_1.png index ef790765..2d958753 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_1.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_2.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_2.png index 03cc818c..cc57f448 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_2.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_3.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_3.png index 06558e52..d751a5bc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_3.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_4.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_4.png index 141e59ee..0718aba9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_4.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_5.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_5.png index 6b3820e6..03453357 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_5.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_5.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_6.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_6.png index 0a73d8fa..49aa5320 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_6.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_6.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_7.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_7.png index e92f5a5a..4942f495 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_7.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_7.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_0.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_0.png index 24de0bb9..1a2c308e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_0.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_0.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_1.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_1.png index e025e06f..8d2dbe04 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_1.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_2.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_2.png index 9ea8fc49..def8630d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_2.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_3.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_3.png index 8c01d85c..6dce32ea 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_3.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_4.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_4.png index 807efa04..645ffe49 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_4.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_5.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_5.png index 1e387a9f..48e7c37b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_5.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_5.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_6.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_6.png index 6484f928..b90a1dd3 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_6.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_6.png differ diff --git a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_7.png b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_7.png index 563537ca..5d666972 100644 Binary files a/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_7.png and b/src/main/resources/assets/betterend/textures/block/end_stone_stalactite_cavemoss_7.png differ diff --git a/src/main/resources/assets/betterend/textures/block/ender_block.png b/src/main/resources/assets/betterend/textures/block/ender_block.png index 929bdec1..be43bf85 100644 Binary files a/src/main/resources/assets/betterend/textures/block/ender_block.png and b/src/main/resources/assets/betterend/textures/block/ender_block.png differ diff --git a/src/main/resources/assets/betterend/textures/block/ender_ore.png b/src/main/resources/assets/betterend/textures/block/ender_ore.png index d2bd1136..ea514c8a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/ender_ore.png and b/src/main/resources/assets/betterend/textures/block/ender_ore.png differ diff --git a/src/main/resources/assets/betterend/textures/block/endstone_dust.png b/src/main/resources/assets/betterend/textures/block/endstone_dust.png index 6b98cde8..facaa574 100644 Binary files a/src/main/resources/assets/betterend/textures/block/endstone_dust.png and b/src/main/resources/assets/betterend/textures/block/endstone_dust.png differ diff --git a/src/main/resources/assets/betterend/textures/block/endstone_flower_pot.png b/src/main/resources/assets/betterend/textures/block/endstone_flower_pot.png new file mode 100644 index 00000000..631545a8 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/endstone_flower_pot.png differ diff --git a/src/main/resources/assets/betterend/textures/block/filalux_bottom.png b/src/main/resources/assets/betterend/textures/block/filalux_bottom.png index 73f9e380..332e71a5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/filalux_bottom.png and b/src/main/resources/assets/betterend/textures/block/filalux_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/filalux_bottom_e.png b/src/main/resources/assets/betterend/textures/block/filalux_bottom_e.png index dc94f6b6..bce11d35 100644 Binary files a/src/main/resources/assets/betterend/textures/block/filalux_bottom_e.png and b/src/main/resources/assets/betterend/textures/block/filalux_bottom_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/filalux_lantern.png b/src/main/resources/assets/betterend/textures/block/filalux_lantern.png index d217989c..ae72b082 100644 Binary files a/src/main/resources/assets/betterend/textures/block/filalux_lantern.png and b/src/main/resources/assets/betterend/textures/block/filalux_lantern.png differ diff --git a/src/main/resources/assets/betterend/textures/block/filalux_lantern_e.png b/src/main/resources/assets/betterend/textures/block/filalux_lantern_e.png index 02fe0302..8b829289 100644 Binary files a/src/main/resources/assets/betterend/textures/block/filalux_lantern_e.png and b/src/main/resources/assets/betterend/textures/block/filalux_lantern_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/filalux_middle.png b/src/main/resources/assets/betterend/textures/block/filalux_middle.png index 2a7dddbb..f8daf0ff 100644 Binary files a/src/main/resources/assets/betterend/textures/block/filalux_middle.png and b/src/main/resources/assets/betterend/textures/block/filalux_middle.png differ diff --git a/src/main/resources/assets/betterend/textures/block/filalux_wings.png b/src/main/resources/assets/betterend/textures/block/filalux_wings.png index 081170d4..74748177 100644 Binary files a/src/main/resources/assets/betterend/textures/block/filalux_wings.png and b/src/main/resources/assets/betterend/textures/block/filalux_wings.png differ diff --git a/src/main/resources/assets/betterend/textures/block/filalux_wings_large.png b/src/main/resources/assets/betterend/textures/block/filalux_wings_large.png index 06ba9fd1..49b7603d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/filalux_wings_large.png and b/src/main/resources/assets/betterend/textures/block/filalux_wings_large.png differ diff --git a/src/main/resources/assets/betterend/textures/block/filalux_wings_top.png b/src/main/resources/assets/betterend/textures/block/filalux_wings_top.png index 00f90595..6a7eeb18 100644 Binary files a/src/main/resources/assets/betterend/textures/block/filalux_wings_top.png and b/src/main/resources/assets/betterend/textures/block/filalux_wings_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/filalux_wings_top_bottom.png b/src/main/resources/assets/betterend/textures/block/filalux_wings_top_bottom.png index bc399f47..83e72da6 100644 Binary files a/src/main/resources/assets/betterend/textures/block/filalux_wings_top_bottom.png and b/src/main/resources/assets/betterend/textures/block/filalux_wings_top_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/filalux_wings_top_side.png b/src/main/resources/assets/betterend/textures/block/filalux_wings_top_side.png index 62661b9a..8ff78904 100644 Binary files a/src/main/resources/assets/betterend/textures/block/filalux_wings_top_side.png and b/src/main/resources/assets/betterend/textures/block/filalux_wings_top_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flamaea_1.png b/src/main/resources/assets/betterend/textures/block/flamaea_1.png index d7fb8cef..ca8a7ece 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flamaea_1.png and b/src/main/resources/assets/betterend/textures/block/flamaea_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flamaea_1_e.png b/src/main/resources/assets/betterend/textures/block/flamaea_1_e.png index e246a96e..edf19d93 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flamaea_1_e.png and b/src/main/resources/assets/betterend/textures/block/flamaea_1_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flamaea_2.png b/src/main/resources/assets/betterend/textures/block/flamaea_2.png index 0b3486f9..61a1dfe2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flamaea_2.png and b/src/main/resources/assets/betterend/textures/block/flamaea_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flamaea_2_e.png b/src/main/resources/assets/betterend/textures/block/flamaea_2_e.png index d6b109e7..0eb18392 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flamaea_2_e.png and b/src/main/resources/assets/betterend/textures/block/flamaea_2_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flamaea_3.png b/src/main/resources/assets/betterend/textures/block/flamaea_3.png index 4404b30e..869153ee 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flamaea_3.png and b/src/main/resources/assets/betterend/textures/block/flamaea_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flamaea_3_e.png b/src/main/resources/assets/betterend/textures/block/flamaea_3_e.png index c2071744..d6b00e67 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flamaea_3_e.png and b/src/main/resources/assets/betterend/textures/block/flamaea_3_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flamaea_4.png b/src/main/resources/assets/betterend/textures/block/flamaea_4.png index 098f1fd3..c54c97ff 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flamaea_4.png and b/src/main/resources/assets/betterend/textures/block/flamaea_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flamaea_4_e.png b/src/main/resources/assets/betterend/textures/block/flamaea_4_e.png index 46c461bf..cf48e948 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flamaea_4_e.png and b/src/main/resources/assets/betterend/textures/block/flamaea_4_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flamaea_5.png b/src/main/resources/assets/betterend/textures/block/flamaea_5.png index 52458b41..bbfeb9f1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flamaea_5.png and b/src/main/resources/assets/betterend/textures/block/flamaea_5.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flamaea_5_e.png b/src/main/resources/assets/betterend/textures/block/flamaea_5_e.png index 3d1d907e..b5892af4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flamaea_5_e.png and b/src/main/resources/assets/betterend/textures/block/flamaea_5_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flammalix.png b/src/main/resources/assets/betterend/textures/block/flammalix.png new file mode 100644 index 00000000..2757c703 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/flammalix.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flammalix_e.png b/src/main/resources/assets/betterend/textures/block/flammalix_e.png new file mode 100644 index 00000000..d93c8b0c Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/flammalix_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite.png b/src/main/resources/assets/betterend/textures/block/flavolite.png index 25e7f824..f259025e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite.png and b/src/main/resources/assets/betterend/textures/block/flavolite.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_bricks.png b/src/main/resources/assets/betterend/textures/block/flavolite_bricks.png index 9446fb39..39d09783 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_bricks.png and b/src/main/resources/assets/betterend/textures/block/flavolite_bricks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_flower_pot.png b/src/main/resources/assets/betterend/textures/block/flavolite_flower_pot.png new file mode 100644 index 00000000..53379ba5 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/flavolite_flower_pot.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_furnace_front.png b/src/main/resources/assets/betterend/textures/block/flavolite_furnace_front.png index dfb223f4..7bd185fa 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_furnace_front.png and b/src/main/resources/assets/betterend/textures/block/flavolite_furnace_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_furnace_side.png b/src/main/resources/assets/betterend/textures/block/flavolite_furnace_side.png index 1d51de8a..cc94cf18 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_furnace_side.png and b/src/main/resources/assets/betterend/textures/block/flavolite_furnace_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_furnace_top.png b/src/main/resources/assets/betterend/textures/block/flavolite_furnace_top.png index b4c4cf32..3c6d5964 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_furnace_top.png and b/src/main/resources/assets/betterend/textures/block/flavolite_furnace_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_lantern_bottom.png b/src/main/resources/assets/betterend/textures/block/flavolite_lantern_bottom.png index 51971a4c..0344cedf 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_lantern_bottom.png and b/src/main/resources/assets/betterend/textures/block/flavolite_lantern_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_lantern_side.png b/src/main/resources/assets/betterend/textures/block/flavolite_lantern_side.png index ed2b6472..7144e90e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_lantern_side.png and b/src/main/resources/assets/betterend/textures/block/flavolite_lantern_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_lantern_top.png b/src/main/resources/assets/betterend/textures/block/flavolite_lantern_top.png index a244b4c7..476e7edf 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_lantern_top.png and b/src/main/resources/assets/betterend/textures/block/flavolite_lantern_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_pillar_side.png b/src/main/resources/assets/betterend/textures/block/flavolite_pillar_side.png index 28ec0820..3f2e5468 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_pillar_side.png and b/src/main/resources/assets/betterend/textures/block/flavolite_pillar_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_pillar_top.png b/src/main/resources/assets/betterend/textures/block/flavolite_pillar_top.png index 1c4024c9..0330151f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_pillar_top.png and b/src/main/resources/assets/betterend/textures/block/flavolite_pillar_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_polished.png b/src/main/resources/assets/betterend/textures/block/flavolite_polished.png index 8f239b70..14c07cf6 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_polished.png and b/src/main/resources/assets/betterend/textures/block/flavolite_polished.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_1.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_1.png index 2aed9bca..65d25895 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_1.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_2.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_2.png index 59bc7f79..e87cbc4d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_2.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_3.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_3.png index c3c624c5..3d141ea0 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_3.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_4.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_4.png index a6d93c16..92535d5a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_4.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_5.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_5.png index a4b35d2f..bba189b1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_5.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_5.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_6.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_6.png index 40bdc614..85170808 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_6.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_6.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_7.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_7.png index b7cbe8a5..c1b4ab1f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_7.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_7.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_8.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_8.png index 60792f55..dc9dede3 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_8.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_8.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_9.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_9.png index 849732b6..e331457f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_9.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_9.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_1.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_1.png index bfb72505..b14bdaf5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_1.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_2.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_2.png index ed85bea7..121e0234 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_2.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_3.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_3.png index 1370b369..a524e70a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_3.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_3_e.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_3_e.png index e7e499f5..1888c21c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_3_e.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_3_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_4.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_4.png index 1735bdd3..026459d9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_4.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_5.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_5.png index d945f546..9b3011ea 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_5.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_5.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_5_e.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_5_e.png index 43650b68..3cb0c3de 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_5_e.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_5_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_6.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_6.png index 32ed4e93..3ff4d6ec 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_6.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_6.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_6_e.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_6_e.png index e8dc3118..e72392f0 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_6_e.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_6_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_7.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_7.png index 437974a9..09c8a20f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_7.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_7.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_7_e.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_7_e.png index 4c12cc22..3da6fdd2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_7_e.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_7_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_8.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_8.png index 85e2fe33..8b9a330b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_8.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_8.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_9.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_9.png index 48c287d3..536e26ea 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_9.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_9.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_9_e.png b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_9_e.png index 46ed7538..06d8aa01 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_9_e.png and b/src/main/resources/assets/betterend/textures/block/flavolite_runed_active_9_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/flavolite_tiles.png b/src/main/resources/assets/betterend/textures/block/flavolite_tiles.png index e9880db0..3ee5436a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/flavolite_tiles.png and b/src/main/resources/assets/betterend/textures/block/flavolite_tiles.png differ diff --git a/src/main/resources/assets/betterend/textures/block/fracturn.png b/src/main/resources/assets/betterend/textures/block/fracturn.png index 8159716a..a8412057 100644 Binary files a/src/main/resources/assets/betterend/textures/block/fracturn.png and b/src/main/resources/assets/betterend/textures/block/fracturn.png differ diff --git a/src/main/resources/assets/betterend/textures/block/fracturn_e.png b/src/main/resources/assets/betterend/textures/block/fracturn_e.png index 3e739d5b..a2152d21 100644 Binary files a/src/main/resources/assets/betterend/textures/block/fracturn_e.png and b/src/main/resources/assets/betterend/textures/block/fracturn_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/fracturn_potted.png b/src/main/resources/assets/betterend/textures/block/fracturn_potted.png new file mode 100644 index 00000000..bc5a5409 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/fracturn_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/fracturn_potted_e.png b/src/main/resources/assets/betterend/textures/block/fracturn_potted_e.png new file mode 100644 index 00000000..1f1dcfd6 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/fracturn_potted_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/geyser_top.png b/src/main/resources/assets/betterend/textures/block/geyser_top.png index 28b67d57..0fc22b0f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/geyser_top.png and b/src/main/resources/assets/betterend/textures/block/geyser_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/globulagus.png b/src/main/resources/assets/betterend/textures/block/globulagus.png index b2782275..cd8e5fcc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/globulagus.png and b/src/main/resources/assets/betterend/textures/block/globulagus.png differ diff --git a/src/main/resources/assets/betterend/textures/block/globulagus_potted.png b/src/main/resources/assets/betterend/textures/block/globulagus_potted.png new file mode 100644 index 00000000..f9fe85fd Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/globulagus_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/glowing_pillar_roots_bottom.png b/src/main/resources/assets/betterend/textures/block/glowing_pillar_roots_bottom.png index 2bd85ed6..4166fd3f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/glowing_pillar_roots_bottom.png and b/src/main/resources/assets/betterend/textures/block/glowing_pillar_roots_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/gold_chandelier_ceil.png b/src/main/resources/assets/betterend/textures/block/gold_chandelier_ceil.png index bf3c870e..95bdb260 100644 Binary files a/src/main/resources/assets/betterend/textures/block/gold_chandelier_ceil.png and b/src/main/resources/assets/betterend/textures/block/gold_chandelier_ceil.png differ diff --git a/src/main/resources/assets/betterend/textures/block/gold_chandelier_floor.png b/src/main/resources/assets/betterend/textures/block/gold_chandelier_floor.png index 05e83ea4..adf1c0cb 100644 Binary files a/src/main/resources/assets/betterend/textures/block/gold_chandelier_floor.png and b/src/main/resources/assets/betterend/textures/block/gold_chandelier_floor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/gold_chandelier_wall.png b/src/main/resources/assets/betterend/textures/block/gold_chandelier_wall.png index 27182e7a..4e1c0a1a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/gold_chandelier_wall.png and b/src/main/resources/assets/betterend/textures/block/gold_chandelier_wall.png differ diff --git a/src/main/resources/assets/betterend/textures/block/granite_lantern_bottom.png b/src/main/resources/assets/betterend/textures/block/granite_lantern_bottom.png index fe236bd8..45f112bd 100644 Binary files a/src/main/resources/assets/betterend/textures/block/granite_lantern_bottom.png and b/src/main/resources/assets/betterend/textures/block/granite_lantern_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/granite_lantern_side.png b/src/main/resources/assets/betterend/textures/block/granite_lantern_side.png index ebd6ccc0..f90d94bd 100644 Binary files a/src/main/resources/assets/betterend/textures/block/granite_lantern_side.png and b/src/main/resources/assets/betterend/textures/block/granite_lantern_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/granite_lantern_top.png b/src/main/resources/assets/betterend/textures/block/granite_lantern_top.png index c7fa1bb1..654ce79b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/granite_lantern_top.png and b/src/main/resources/assets/betterend/textures/block/granite_lantern_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_bookshelf.png b/src/main/resources/assets/betterend/textures/block/helix_tree_bookshelf.png index 98a0e07c..8afd8c59 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_bookshelf.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_bookshelf.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_composter_bottom.png b/src/main/resources/assets/betterend/textures/block/helix_tree_composter_bottom.png index 800f725e..8b34262f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_composter_bottom.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_composter_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_composter_side.png b/src/main/resources/assets/betterend/textures/block/helix_tree_composter_side.png index 4ee19572..22a1c276 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_composter_side.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_composter_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_composter_top.png b/src/main/resources/assets/betterend/textures/block/helix_tree_composter_top.png index 3375742d..aa8963dd 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_composter_top.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_composter_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_bottom.png b/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_bottom.png index d2066d0f..4c197387 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_bottom.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_front.png b/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_front.png index 27ee53d3..485b9abf 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_front.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_side.png b/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_side.png index 754e6f39..6cacf8ef 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_side.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_top.png b/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_top.png index 3ca07e10..509fac94 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_top.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_crafting_table_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_door_bottom.png b/src/main/resources/assets/betterend/textures/block/helix_tree_door_bottom.png index e49ab911..9856bccd 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_door_bottom.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_door_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_door_top.png b/src/main/resources/assets/betterend/textures/block/helix_tree_door_top.png index 3038eceb..457f27ad 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_door_top.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_door_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_log_side.png b/src/main/resources/assets/betterend/textures/block/helix_tree_log_side.png index 93245192..041fd139 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_log_side.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_log_top.png b/src/main/resources/assets/betterend/textures/block/helix_tree_log_top.png index e93d8cfd..475ab027 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_log_top.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_planks.png b/src/main/resources/assets/betterend/textures/block/helix_tree_planks.png index 19a0ce73..d824ef4b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_planks.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_planks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_sapling.png b/src/main/resources/assets/betterend/textures/block/helix_tree_sapling.png index 4ad7d9dc..911be1e2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_sapling.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_sapling.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_stripped_log_side.png b/src/main/resources/assets/betterend/textures/block/helix_tree_stripped_log_side.png index a75ae1ad..b9ffe039 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_stripped_log_side.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_stripped_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_stripped_log_top.png b/src/main/resources/assets/betterend/textures/block/helix_tree_stripped_log_top.png index e727ea1f..a6c46704 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_stripped_log_top.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_stripped_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/helix_tree_trapdoor.png b/src/main/resources/assets/betterend/textures/block/helix_tree_trapdoor.png index 3f19d0ac..0386aa0e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/helix_tree_trapdoor.png and b/src/main/resources/assets/betterend/textures/block/helix_tree_trapdoor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_bloom_bottom.png b/src/main/resources/assets/betterend/textures/block/hydralux_bloom_bottom.png index d642c9cc..52ed57dc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_bloom_bottom.png and b/src/main/resources/assets/betterend/textures/block/hydralux_bloom_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_bloom_top.png b/src/main/resources/assets/betterend/textures/block/hydralux_bloom_top.png index 032a4608..6c2f0529 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_bloom_top.png and b/src/main/resources/assets/betterend/textures/block/hydralux_bloom_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bottom.png b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bottom.png index 9cae5188..fcf05ac6 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bottom.png and b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bottom_e.png b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bottom_e.png index b15af0e5..ea0feec4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bottom_e.png and b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bottom_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud.png b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud.png index 2e2d54ce..38770084 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud.png and b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_bottom.png b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_bottom.png index 2ea7f8ac..8e577d39 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_bottom.png and b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_side.png b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_side.png index d9492fc0..7de03a1e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_side.png and b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_side_e.png b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_side_e.png index d9492fc0..7de03a1e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_side_e.png and b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_side_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_top.png b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_top.png index f625b709..b945c552 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_top.png and b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_top_e.png b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_top_e.png index f625b709..b945c552 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_top_e.png and b/src/main/resources/assets/betterend/textures/block/hydralux_flower_bud_petal_top_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_flower_petal.png b/src/main/resources/assets/betterend/textures/block/hydralux_flower_petal.png index 892bfa06..30150f22 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_flower_petal.png and b/src/main/resources/assets/betterend/textures/block/hydralux_flower_petal.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_flower_petal_e.png b/src/main/resources/assets/betterend/textures/block/hydralux_flower_petal_e.png index 892bfa06..30150f22 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_flower_petal_e.png and b/src/main/resources/assets/betterend/textures/block/hydralux_flower_petal_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_petal_block.png b/src/main/resources/assets/betterend/textures/block/hydralux_petal_block.png index df55a3f7..0f9557b8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_petal_block.png and b/src/main/resources/assets/betterend/textures/block/hydralux_petal_block.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_petal_block_colored.png b/src/main/resources/assets/betterend/textures/block/hydralux_petal_block_colored.png index 259cf553..596dd886 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_petal_block_colored.png and b/src/main/resources/assets/betterend/textures/block/hydralux_petal_block_colored.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_roots.png b/src/main/resources/assets/betterend/textures/block/hydralux_roots.png index 6d43f753..8ec72837 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_roots.png and b/src/main/resources/assets/betterend/textures/block/hydralux_roots.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_sapling_2.png b/src/main/resources/assets/betterend/textures/block/hydralux_sapling_2.png index e589537a..ddf006a4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_sapling_2.png and b/src/main/resources/assets/betterend/textures/block/hydralux_sapling_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_sapling_2_e.png b/src/main/resources/assets/betterend/textures/block/hydralux_sapling_2_e.png index e9258f7c..b9ee2e04 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_sapling_2_e.png and b/src/main/resources/assets/betterend/textures/block/hydralux_sapling_2_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_sapling_3.png b/src/main/resources/assets/betterend/textures/block/hydralux_sapling_3.png index 7bccc83d..516b3c16 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_sapling_3.png and b/src/main/resources/assets/betterend/textures/block/hydralux_sapling_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_sapling_3_e.png b/src/main/resources/assets/betterend/textures/block/hydralux_sapling_3_e.png index fd52c709..957af6fb 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_sapling_3_e.png and b/src/main/resources/assets/betterend/textures/block/hydralux_sapling_3_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_sapling_4.png b/src/main/resources/assets/betterend/textures/block/hydralux_sapling_4.png index e1bcc6a9..584e2b77 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_sapling_4.png and b/src/main/resources/assets/betterend/textures/block/hydralux_sapling_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_sapling_4_e.png b/src/main/resources/assets/betterend/textures/block/hydralux_sapling_4_e.png index 4ca5bde7..ff912b51 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_sapling_4_e.png and b/src/main/resources/assets/betterend/textures/block/hydralux_sapling_4_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_vine.png b/src/main/resources/assets/betterend/textures/block/hydralux_vine.png index c62b9567..5c34083a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_vine.png and b/src/main/resources/assets/betterend/textures/block/hydralux_vine.png differ diff --git a/src/main/resources/assets/betterend/textures/block/hydralux_vine_bottom.png b/src/main/resources/assets/betterend/textures/block/hydralux_vine_bottom.png index 955ae225..57b5c43b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/hydralux_vine_bottom.png and b/src/main/resources/assets/betterend/textures/block/hydralux_vine_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/inflexia.png b/src/main/resources/assets/betterend/textures/block/inflexia.png new file mode 100644 index 00000000..19b83699 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/inflexia.png differ diff --git a/src/main/resources/assets/betterend/textures/block/inflexia_potted.png b/src/main/resources/assets/betterend/textures/block/inflexia_potted.png new file mode 100644 index 00000000..ad36f264 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/inflexia_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/infusion_pedestal_pillar.png b/src/main/resources/assets/betterend/textures/block/infusion_pedestal_pillar.png index 6f92ef58..17b52155 100644 Binary files a/src/main/resources/assets/betterend/textures/block/infusion_pedestal_pillar.png and b/src/main/resources/assets/betterend/textures/block/infusion_pedestal_pillar.png differ diff --git a/src/main/resources/assets/betterend/textures/block/iron_bulb_vine_lantern_metal.png b/src/main/resources/assets/betterend/textures/block/iron_bulb_vine_lantern_metal.png index 40f80b82..0f754fbe 100644 Binary files a/src/main/resources/assets/betterend/textures/block/iron_bulb_vine_lantern_metal.png and b/src/main/resources/assets/betterend/textures/block/iron_bulb_vine_lantern_metal.png differ diff --git a/src/main/resources/assets/betterend/textures/block/iron_chandelier_ceil.png b/src/main/resources/assets/betterend/textures/block/iron_chandelier_ceil.png index 41913eb2..cbd8eace 100644 Binary files a/src/main/resources/assets/betterend/textures/block/iron_chandelier_ceil.png and b/src/main/resources/assets/betterend/textures/block/iron_chandelier_ceil.png differ diff --git a/src/main/resources/assets/betterend/textures/block/iron_chandelier_floor.png b/src/main/resources/assets/betterend/textures/block/iron_chandelier_floor.png index 692adedf..34fad0b0 100644 Binary files a/src/main/resources/assets/betterend/textures/block/iron_chandelier_floor.png and b/src/main/resources/assets/betterend/textures/block/iron_chandelier_floor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/iron_chandelier_wall.png b/src/main/resources/assets/betterend/textures/block/iron_chandelier_wall.png index b6a04527..7cc40041 100644 Binary files a/src/main/resources/assets/betterend/textures/block/iron_chandelier_wall.png and b/src/main/resources/assets/betterend/textures/block/iron_chandelier_wall.png differ diff --git a/src/main/resources/assets/betterend/textures/block/ivis_vine.png b/src/main/resources/assets/betterend/textures/block/ivis_vine.png index 541854b1..323b26ec 100644 Binary files a/src/main/resources/assets/betterend/textures/block/ivis_vine.png and b/src/main/resources/assets/betterend/textures/block/ivis_vine.png differ diff --git a/src/main/resources/assets/betterend/textures/block/ivis_vine_bottom.png b/src/main/resources/assets/betterend/textures/block/ivis_vine_bottom.png index 6d6d883a..673924de 100644 Binary files a/src/main/resources/assets/betterend/textures/block/ivis_vine_bottom.png and b/src/main/resources/assets/betterend/textures/block/ivis_vine_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_barrel_top_open.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_barrel_top_open.png index 33d8361c..364a8443 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_barrel_top_open.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_barrel_top_open.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_bookshelf.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_bookshelf.png index 8a368a4b..473b6093 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_bookshelf.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_bookshelf.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_cap.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_cap.png index a8e7203f..953a33c3 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_cap.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_cap.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_cap_small.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_cap_small.png index 5a2850bb..056397e2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_cap_small.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_cap_small.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_ceiling_stem.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_ceiling_stem.png index 6cbf057b..e714a9de 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_ceiling_stem.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_ceiling_stem.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_composter_bottom.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_composter_bottom.png index 521619ea..d17deb85 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_composter_bottom.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_composter_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_composter_side.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_composter_side.png index 3ee7f1fb..c9f448e6 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_composter_side.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_composter_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_composter_top.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_composter_top.png index 4a41b359..9c2e9d16 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_composter_top.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_composter_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_bottom.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_bottom.png index 0c419f55..1b8e4849 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_bottom.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_front.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_front.png index 3dc62afd..82277d37 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_front.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_side.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_side.png index 43aee59e..f0506345 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_side.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_top.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_top.png index e0548c49..67594787 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_top.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_crafting_table_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_log_side.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_log_side.png index 13c21ebb..760ca050 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_log_side.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_log_top.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_log_top.png index 5f466430..66ed2077 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_log_top.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_planks.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_planks.png index 6f3e85db..2f34d449 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_planks.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_planks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_stripped_log_top.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_stripped_log_top.png index 71c8f8c6..1ea58485 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_stripped_log_top.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_stripped_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_wall_stem_1.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_wall_stem_1.png index 39b651bc..0180b73d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_wall_stem_1.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_wall_stem_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jellyshroom_wall_stem_2.png b/src/main/resources/assets/betterend/textures/block/jellyshroom_wall_stem_2.png index c188da6f..1a18c394 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jellyshroom_wall_stem_2.png and b/src/main/resources/assets/betterend/textures/block/jellyshroom_wall_stem_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_fern_leaf.png b/src/main/resources/assets/betterend/textures/block/jungle_fern_leaf.png index dc7e77e1..a7f62e00 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jungle_fern_leaf.png and b/src/main/resources/assets/betterend/textures/block/jungle_fern_leaf.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_fern_leaf_2.png b/src/main/resources/assets/betterend/textures/block/jungle_fern_leaf_2.png index 43e53ca6..85ab5e7e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jungle_fern_leaf_2.png and b/src/main/resources/assets/betterend/textures/block/jungle_fern_leaf_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_fern_leaf_3.png b/src/main/resources/assets/betterend/textures/block/jungle_fern_leaf_3.png index a106d397..86cbcb27 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jungle_fern_leaf_3.png and b/src/main/resources/assets/betterend/textures/block/jungle_fern_leaf_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_fern_middle.png b/src/main/resources/assets/betterend/textures/block/jungle_fern_middle.png index 216632c2..e28d8aaf 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jungle_fern_middle.png and b/src/main/resources/assets/betterend/textures/block/jungle_fern_middle.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_fern_middle_2.png b/src/main/resources/assets/betterend/textures/block/jungle_fern_middle_2.png index a327269d..0e8384b4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jungle_fern_middle_2.png and b/src/main/resources/assets/betterend/textures/block/jungle_fern_middle_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_fern_middle_3.png b/src/main/resources/assets/betterend/textures/block/jungle_fern_middle_3.png index fe41f344..b2411761 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jungle_fern_middle_3.png and b/src/main/resources/assets/betterend/textures/block/jungle_fern_middle_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_fern_spore.png b/src/main/resources/assets/betterend/textures/block/jungle_fern_spore.png index 3b4dd02d..5504e57e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jungle_fern_spore.png and b/src/main/resources/assets/betterend/textures/block/jungle_fern_spore.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_grass.png b/src/main/resources/assets/betterend/textures/block/jungle_grass.png index 93e9235e..088cdaf9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jungle_grass.png and b/src/main/resources/assets/betterend/textures/block/jungle_grass.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_grass_2.png b/src/main/resources/assets/betterend/textures/block/jungle_grass_2.png index 7a22e3f4..41591c65 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jungle_grass_2.png and b/src/main/resources/assets/betterend/textures/block/jungle_grass_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_grass_potted.png b/src/main/resources/assets/betterend/textures/block/jungle_grass_potted.png new file mode 100644 index 00000000..62100143 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/jungle_grass_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_moss_path_top.png b/src/main/resources/assets/betterend/textures/block/jungle_moss_path_top.png index a56eb030..eeacaa11 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jungle_moss_path_top.png and b/src/main/resources/assets/betterend/textures/block/jungle_moss_path_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_moss_top.png b/src/main/resources/assets/betterend/textures/block/jungle_moss_top.png index 37505929..ee9a5be1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jungle_moss_top.png and b/src/main/resources/assets/betterend/textures/block/jungle_moss_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_vine.png b/src/main/resources/assets/betterend/textures/block/jungle_vine.png index 7bdcee97..82c144fc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jungle_vine.png and b/src/main/resources/assets/betterend/textures/block/jungle_vine.png differ diff --git a/src/main/resources/assets/betterend/textures/block/jungle_vine_bottom.png b/src/main/resources/assets/betterend/textures/block/jungle_vine_bottom.png index 23ed5823..e3c5055c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/jungle_vine_bottom.png and b/src/main/resources/assets/betterend/textures/block/jungle_vine_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_barrel_bottom.png b/src/main/resources/assets/betterend/textures/block/lacugrove_barrel_bottom.png index d579104c..13da51d8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_barrel_bottom.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_barrel_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_barrel_top.png b/src/main/resources/assets/betterend/textures/block/lacugrove_barrel_top.png index 6c96fdfd..d1d3b834 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_barrel_top.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_barrel_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_barrel_top_open.png b/src/main/resources/assets/betterend/textures/block/lacugrove_barrel_top_open.png index a84d9827..f9cc595e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_barrel_top_open.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_barrel_top_open.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_bookshelf.png b/src/main/resources/assets/betterend/textures/block/lacugrove_bookshelf.png index 3863d4b6..e295ea55 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_bookshelf.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_bookshelf.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_composter_bottom.png b/src/main/resources/assets/betterend/textures/block/lacugrove_composter_bottom.png index cba04b4f..97f921cc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_composter_bottom.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_composter_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_composter_side.png b/src/main/resources/assets/betterend/textures/block/lacugrove_composter_side.png index 7d0c993d..ee3e6459 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_composter_side.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_composter_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_composter_top.png b/src/main/resources/assets/betterend/textures/block/lacugrove_composter_top.png index 22c34cd5..ef723a7f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_composter_top.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_composter_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_bottom.png b/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_bottom.png index a825fd45..9d552188 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_bottom.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_front.png b/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_front.png index a8c996dd..277569d5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_front.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_side.png b/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_side.png index f095ccbc..d6967e11 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_side.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_top.png b/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_top.png index ba026b34..ac74f71b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_top.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_crafting_table_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_door_top.png b/src/main/resources/assets/betterend/textures/block/lacugrove_door_top.png index e40e26ab..97729be9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_door_top.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_door_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_leaves.png b/src/main/resources/assets/betterend/textures/block/lacugrove_leaves.png index a15a1bae..38a70f34 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_leaves.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_leaves.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_log_side.png b/src/main/resources/assets/betterend/textures/block/lacugrove_log_side.png index 6316c535..885e2800 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_log_side.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_log_side_2.png b/src/main/resources/assets/betterend/textures/block/lacugrove_log_side_2.png index 78b85fe4..1e4ddac3 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_log_side_2.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_log_side_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_log_side_3.png b/src/main/resources/assets/betterend/textures/block/lacugrove_log_side_3.png index 9f7a3d7b..d2053e29 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_log_side_3.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_log_side_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_log_side_4.png b/src/main/resources/assets/betterend/textures/block/lacugrove_log_side_4.png index bbc31139..dc310ff0 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_log_side_4.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_log_side_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_log_top.png b/src/main/resources/assets/betterend/textures/block/lacugrove_log_top.png index e1a7f327..0fdbc85a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_log_top.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_planks.png b/src/main/resources/assets/betterend/textures/block/lacugrove_planks.png index e0f13fad..7e3156f1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_planks.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_planks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_sapling.png b/src/main/resources/assets/betterend/textures/block/lacugrove_sapling.png index fa01d469..5f3b90b7 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_sapling.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_sapling.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_stripped_log_side.png b/src/main/resources/assets/betterend/textures/block/lacugrove_stripped_log_side.png index e614419f..b01b7c11 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_stripped_log_side.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_stripped_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_stripped_log_top.png b/src/main/resources/assets/betterend/textures/block/lacugrove_stripped_log_top.png index 4855faaf..b185e26f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_stripped_log_top.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_stripped_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lacugrove_trapdoor.png b/src/main/resources/assets/betterend/textures/block/lacugrove_trapdoor.png index 3bca4da9..69bf2469 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lacugrove_trapdoor.png and b/src/main/resources/assets/betterend/textures/block/lacugrove_trapdoor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lamellarium.png b/src/main/resources/assets/betterend/textures/block/lamellarium.png index e4d035b0..a57759bb 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lamellarium.png and b/src/main/resources/assets/betterend/textures/block/lamellarium.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lamellarium_potted.png b/src/main/resources/assets/betterend/textures/block/lamellarium_potted.png new file mode 100644 index 00000000..fa7d7bfa Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/lamellarium_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_bottom.png b/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_bottom.png index d5a46a27..6072f3e5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_bottom.png and b/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_middle.png b/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_middle.png index 146dc0a2..2894e388 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_middle.png and b/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_middle.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_pre_top.png b/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_pre_top.png index 3f4d8776..e7b37ede 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_pre_top.png and b/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_pre_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_top.png b/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_top.png index df9c89df..70a162be 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_top.png and b/src/main/resources/assets/betterend/textures/block/lanceleaf_leaf_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/large_amaranita_cap_bottom.png b/src/main/resources/assets/betterend/textures/block/large_amaranita_cap_bottom.png index 99902f43..a87e472e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/large_amaranita_cap_bottom.png and b/src/main/resources/assets/betterend/textures/block/large_amaranita_cap_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/large_amaranita_cap_side.png b/src/main/resources/assets/betterend/textures/block/large_amaranita_cap_side.png index 602d4c78..fa114fa7 100644 Binary files a/src/main/resources/assets/betterend/textures/block/large_amaranita_cap_side.png and b/src/main/resources/assets/betterend/textures/block/large_amaranita_cap_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/large_amaranita_cap_top.png b/src/main/resources/assets/betterend/textures/block/large_amaranita_cap_top.png index 8d3d3f74..67fc68f8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/large_amaranita_cap_top.png and b/src/main/resources/assets/betterend/textures/block/large_amaranita_cap_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_barrel_bottom.png b/src/main/resources/assets/betterend/textures/block/lucernia_barrel_bottom.png index 906c92ed..e75be969 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_barrel_bottom.png and b/src/main/resources/assets/betterend/textures/block/lucernia_barrel_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_barrel_side.png b/src/main/resources/assets/betterend/textures/block/lucernia_barrel_side.png index d007b97f..6d9ad50b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_barrel_side.png and b/src/main/resources/assets/betterend/textures/block/lucernia_barrel_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_barrel_top.png b/src/main/resources/assets/betterend/textures/block/lucernia_barrel_top.png index f2a902f8..f6eee97a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_barrel_top.png and b/src/main/resources/assets/betterend/textures/block/lucernia_barrel_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_barrel_top_open.png b/src/main/resources/assets/betterend/textures/block/lucernia_barrel_top_open.png index bc512b06..a3cce982 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_barrel_top_open.png and b/src/main/resources/assets/betterend/textures/block/lucernia_barrel_top_open.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_bookshelf.png b/src/main/resources/assets/betterend/textures/block/lucernia_bookshelf.png index c63e9680..7a1af9f9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_bookshelf.png and b/src/main/resources/assets/betterend/textures/block/lucernia_bookshelf.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_composter_bottom.png b/src/main/resources/assets/betterend/textures/block/lucernia_composter_bottom.png index 3069334e..46c653d5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_composter_bottom.png and b/src/main/resources/assets/betterend/textures/block/lucernia_composter_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_composter_side.png b/src/main/resources/assets/betterend/textures/block/lucernia_composter_side.png index df4985fd..bd2a20d2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_composter_side.png and b/src/main/resources/assets/betterend/textures/block/lucernia_composter_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_composter_top.png b/src/main/resources/assets/betterend/textures/block/lucernia_composter_top.png index a4d670ac..a7a59050 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_composter_top.png and b/src/main/resources/assets/betterend/textures/block/lucernia_composter_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_bottom.png b/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_bottom.png index df64f9ef..656fae59 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_bottom.png and b/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_front.png b/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_front.png index 66534540..b5474571 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_front.png and b/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_side.png b/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_side.png index 96b85558..8bea026f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_side.png and b/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_top.png b/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_top.png index bdd32bf6..14aa27ca 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_top.png and b/src/main/resources/assets/betterend/textures/block/lucernia_crafting_table_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_door_bottom.png b/src/main/resources/assets/betterend/textures/block/lucernia_door_bottom.png index 1709535e..fa40aec4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_door_bottom.png and b/src/main/resources/assets/betterend/textures/block/lucernia_door_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_door_side.png b/src/main/resources/assets/betterend/textures/block/lucernia_door_side.png index 0a528f06..b357cf70 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_door_side.png and b/src/main/resources/assets/betterend/textures/block/lucernia_door_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_door_top.png b/src/main/resources/assets/betterend/textures/block/lucernia_door_top.png index 6ca50c75..e7b90205 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_door_top.png and b/src/main/resources/assets/betterend/textures/block/lucernia_door_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_ladder.png b/src/main/resources/assets/betterend/textures/block/lucernia_ladder.png index 839ba808..75933434 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_ladder.png and b/src/main/resources/assets/betterend/textures/block/lucernia_ladder.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_leaves_1.png b/src/main/resources/assets/betterend/textures/block/lucernia_leaves_1.png index 7dc39a1c..a2c3f619 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_leaves_1.png and b/src/main/resources/assets/betterend/textures/block/lucernia_leaves_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_leaves_2.png b/src/main/resources/assets/betterend/textures/block/lucernia_leaves_2.png index b1f5cf69..d597885d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_leaves_2.png and b/src/main/resources/assets/betterend/textures/block/lucernia_leaves_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_leaves_3.png b/src/main/resources/assets/betterend/textures/block/lucernia_leaves_3.png index 09467dde..53a8b142 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_leaves_3.png and b/src/main/resources/assets/betterend/textures/block/lucernia_leaves_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_leaves_4.png b/src/main/resources/assets/betterend/textures/block/lucernia_leaves_4.png index c2aa8894..6331bbcc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_leaves_4.png and b/src/main/resources/assets/betterend/textures/block/lucernia_leaves_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_log_side.png b/src/main/resources/assets/betterend/textures/block/lucernia_log_side.png index f4866cd5..37402358 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_log_side.png and b/src/main/resources/assets/betterend/textures/block/lucernia_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_log_side_2.png b/src/main/resources/assets/betterend/textures/block/lucernia_log_side_2.png index 8a0b513e..6bfaba6d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_log_side_2.png and b/src/main/resources/assets/betterend/textures/block/lucernia_log_side_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_log_top.png b/src/main/resources/assets/betterend/textures/block/lucernia_log_top.png index 7a2b1aad..6166846f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_log_top.png and b/src/main/resources/assets/betterend/textures/block/lucernia_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_outer_leaves_1.png b/src/main/resources/assets/betterend/textures/block/lucernia_outer_leaves_1.png index be12c9aa..544e3d7b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_outer_leaves_1.png and b/src/main/resources/assets/betterend/textures/block/lucernia_outer_leaves_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_outer_leaves_2.png b/src/main/resources/assets/betterend/textures/block/lucernia_outer_leaves_2.png index 48296cb3..1159b21f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_outer_leaves_2.png and b/src/main/resources/assets/betterend/textures/block/lucernia_outer_leaves_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_outer_leaves_3.png b/src/main/resources/assets/betterend/textures/block/lucernia_outer_leaves_3.png index 8f068b78..9239b981 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_outer_leaves_3.png and b/src/main/resources/assets/betterend/textures/block/lucernia_outer_leaves_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_planks.png b/src/main/resources/assets/betterend/textures/block/lucernia_planks.png index 7d734474..82caf41b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_planks.png and b/src/main/resources/assets/betterend/textures/block/lucernia_planks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_sapling.png b/src/main/resources/assets/betterend/textures/block/lucernia_sapling.png index 6b8ec8ee..949abba4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_sapling.png and b/src/main/resources/assets/betterend/textures/block/lucernia_sapling.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_stripped_log_top.png b/src/main/resources/assets/betterend/textures/block/lucernia_stripped_log_top.png index f16b22c2..fcbae539 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_stripped_log_top.png and b/src/main/resources/assets/betterend/textures/block/lucernia_stripped_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lucernia_trapdoor.png b/src/main/resources/assets/betterend/textures/block/lucernia_trapdoor.png index a484e86f..dd368738 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lucernia_trapdoor.png and b/src/main/resources/assets/betterend/textures/block/lucernia_trapdoor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_1.png b/src/main/resources/assets/betterend/textures/block/lumecorn_1.png index 72bd2b58..387bb9cc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_1.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_2.png b/src/main/resources/assets/betterend/textures/block/lumecorn_2.png index a0e8a291..4012f31e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_2.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_3.png b/src/main/resources/assets/betterend/textures/block/lumecorn_3.png index c9c7b969..6fc509f5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_3.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_3_e.png b/src/main/resources/assets/betterend/textures/block/lumecorn_3_e.png index 8c8f1ebf..88cba6d1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_3_e.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_3_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_big_petal.png b/src/main/resources/assets/betterend/textures/block/lumecorn_big_petal.png index d50e5264..a3de184e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_big_petal.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_big_petal.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_leaf_1.png b/src/main/resources/assets/betterend/textures/block/lumecorn_leaf_1.png index 725ed557..40a46a12 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_leaf_1.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_leaf_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_leaf_2.png b/src/main/resources/assets/betterend/textures/block/lumecorn_leaf_2.png index 1c93b511..c56fb816 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_leaf_2.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_leaf_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_light_bottom.png b/src/main/resources/assets/betterend/textures/block/lumecorn_light_bottom.png index af9e5ea1..eac95c92 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_light_bottom.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_light_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_light_bottom_e.png b/src/main/resources/assets/betterend/textures/block/lumecorn_light_bottom_e.png index af9e5ea1..eac95c92 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_light_bottom_e.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_light_bottom_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_light_middle.png b/src/main/resources/assets/betterend/textures/block/lumecorn_light_middle.png index f592a2fa..67342280 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_light_middle.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_light_middle.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_light_middle_e.png b/src/main/resources/assets/betterend/textures/block/lumecorn_light_middle_e.png index f592a2fa..67342280 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_light_middle_e.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_light_middle_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_light_top.png b/src/main/resources/assets/betterend/textures/block/lumecorn_light_top.png index fbe0ee35..ea76ef21 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_light_top.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_light_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_light_top_e.png b/src/main/resources/assets/betterend/textures/block/lumecorn_light_top_e.png index fbe0ee35..ea76ef21 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_light_top_e.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_light_top_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_light_top_middle.png b/src/main/resources/assets/betterend/textures/block/lumecorn_light_top_middle.png index 33769136..ab20ad70 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_light_top_middle.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_light_top_middle.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_light_top_middle_e.png b/src/main/resources/assets/betterend/textures/block/lumecorn_light_top_middle_e.png index 33769136..ab20ad70 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_light_top_middle_e.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_light_top_middle_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lumecorn_stem.png b/src/main/resources/assets/betterend/textures/block/lumecorn_stem.png index 17081516..4441c150 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lumecorn_stem.png and b/src/main/resources/assets/betterend/textures/block/lumecorn_stem.png differ diff --git a/src/main/resources/assets/betterend/textures/block/lutebus.png b/src/main/resources/assets/betterend/textures/block/lutebus.png index 1f5a2686..c850af59 100644 Binary files a/src/main/resources/assets/betterend/textures/block/lutebus.png and b/src/main/resources/assets/betterend/textures/block/lutebus.png differ diff --git a/src/main/resources/assets/betterend/textures/block/magnula.png b/src/main/resources/assets/betterend/textures/block/magnula.png index 7fe91460..73fe3e7c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/magnula.png and b/src/main/resources/assets/betterend/textures/block/magnula.png differ diff --git a/src/main/resources/assets/betterend/textures/block/magnula_bottom.png b/src/main/resources/assets/betterend/textures/block/magnula_bottom.png index eda6b963..ac2fb89d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/magnula_bottom.png and b/src/main/resources/assets/betterend/textures/block/magnula_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/menger_sponge.png b/src/main/resources/assets/betterend/textures/block/menger_sponge.png index 3e1d2d80..d67d81b5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/menger_sponge.png and b/src/main/resources/assets/betterend/textures/block/menger_sponge.png differ diff --git a/src/main/resources/assets/betterend/textures/block/menger_sponge_wet.png b/src/main/resources/assets/betterend/textures/block/menger_sponge_wet.png index f3e4a5c5..ac0a74a7 100644 Binary files a/src/main/resources/assets/betterend/textures/block/menger_sponge_wet.png and b/src/main/resources/assets/betterend/textures/block/menger_sponge_wet.png differ diff --git a/src/main/resources/assets/betterend/textures/block/missing_tile.png b/src/main/resources/assets/betterend/textures/block/missing_tile.png index 5b31bfae..190a193a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/missing_tile.png and b/src/main/resources/assets/betterend/textures/block/missing_tile.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_dragon_bone_cut.png b/src/main/resources/assets/betterend/textures/block/mossy_dragon_bone_cut.png index d26fcb91..c9034277 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_dragon_bone_cut.png and b/src/main/resources/assets/betterend/textures/block/mossy_dragon_bone_cut.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_dragon_bone_side_hor.png b/src/main/resources/assets/betterend/textures/block/mossy_dragon_bone_side_hor.png index f75dc0fe..365fbed1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_dragon_bone_side_hor.png and b/src/main/resources/assets/betterend/textures/block/mossy_dragon_bone_side_hor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_dragon_bone_side_ver.png b/src/main/resources/assets/betterend/textures/block/mossy_dragon_bone_side_ver.png index 9173717b..993767cf 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_dragon_bone_side_ver.png and b/src/main/resources/assets/betterend/textures/block/mossy_dragon_bone_side_ver.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_bookshelf.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_bookshelf.png index 6a7adfe0..50ac4612 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_bookshelf.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_bookshelf.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_cap.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_cap.png index 975f33c4..2e57fc57 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_cap.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_cap.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_cap_transition.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_cap_transition.png index 4b1d0715..11194c9b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_cap_transition.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_cap_transition.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_composter_bottom.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_composter_bottom.png index 28a2f221..3b17e75d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_composter_bottom.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_composter_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_composter_side.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_composter_side.png index 5743553c..a06cd6f8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_composter_side.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_composter_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_composter_top.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_composter_top.png index f3fbe238..65769aab 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_composter_top.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_composter_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_crafting_table_front.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_crafting_table_front.png index e79e51cd..47e145ca 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_crafting_table_front.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_crafting_table_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_crafting_table_side.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_crafting_table_side.png index 22c5cbbd..b6fc10f8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_crafting_table_side.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_crafting_table_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_crafting_table_top.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_crafting_table_top.png index 6e26f3dc..c305082d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_crafting_table_top.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_crafting_table_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_fur.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_fur.png index 37b40dd5..549a3bc3 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_fur.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_fur.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side.png index 7080537f..b6f03889 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_2.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_2.png index bc9fcd43..cf06c235 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_2.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_3.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_3.png index bdbe83a4..537c3d14 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_3.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_4.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_4.png index 3ffc2512..9758ee03 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_4.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_5.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_5.png index 362854f7..5a05e592 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_5.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_side_5.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_stripped_side.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_stripped_side.png index 587ba5a0..e6f0fbe1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_stripped_side.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_log_stripped_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_planks.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_planks.png index 457056be..785b01f3 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_planks.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_planks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_stripped_log_side_5.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_stripped_log_side_5.png index ff7b0016..d852da52 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_stripped_log_side_5.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_stripped_log_side_5.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_trapdoor.png b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_trapdoor.png index 73c9f0a9..55490f72 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_trapdoor.png and b/src/main/resources/assets/betterend/textures/block/mossy_glowshroom_trapdoor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/mossy_obsidian_side.png b/src/main/resources/assets/betterend/textures/block/mossy_obsidian_side.png index 0b4b3c7d..2d9b9003 100644 Binary files a/src/main/resources/assets/betterend/textures/block/mossy_obsidian_side.png and b/src/main/resources/assets/betterend/textures/block/mossy_obsidian_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/needlegrass_01.png b/src/main/resources/assets/betterend/textures/block/needlegrass_01.png index cf683705..da166ddd 100644 Binary files a/src/main/resources/assets/betterend/textures/block/needlegrass_01.png and b/src/main/resources/assets/betterend/textures/block/needlegrass_01.png differ diff --git a/src/main/resources/assets/betterend/textures/block/needlegrass_02.png b/src/main/resources/assets/betterend/textures/block/needlegrass_02.png index 824d8b3e..0be03068 100644 Binary files a/src/main/resources/assets/betterend/textures/block/needlegrass_02.png and b/src/main/resources/assets/betterend/textures/block/needlegrass_02.png differ diff --git a/src/main/resources/assets/betterend/textures/block/needlegrass_03.png b/src/main/resources/assets/betterend/textures/block/needlegrass_03.png index 93188b2c..38a4aa1f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/needlegrass_03.png and b/src/main/resources/assets/betterend/textures/block/needlegrass_03.png differ diff --git a/src/main/resources/assets/betterend/textures/block/needlegrass_04.png b/src/main/resources/assets/betterend/textures/block/needlegrass_04.png index f4d6a7cc..1cf1c921 100644 Binary files a/src/main/resources/assets/betterend/textures/block/needlegrass_04.png and b/src/main/resources/assets/betterend/textures/block/needlegrass_04.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side.png index 1323e564..ae278be4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_dust.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_dust.png index 0aba31b5..07ef9b88 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_dust.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_dust.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_dust_overlay.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_dust_overlay.png index 264be428..3a8e09ca 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_dust_overlay.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_dust_overlay.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_moss.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_moss.png index e22c2e9a..96cfe29a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_moss.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_moss.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_moss_overlay.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_moss_overlay.png index e6ac60a1..e6303288 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_moss_overlay.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_big_side_moss_overlay.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_block_side.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_block_side.png index 2c681c7d..bd373094 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_block_side.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_block_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_block_top.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_block_top.png index f3c4c0a8..4ac7b373 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_block_top.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_block_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side.png index 7fd0f467..f5e4709a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_dust.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_dust.png index a36b2e48..92a278b5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_dust.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_dust.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_dust_overlay.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_dust_overlay.png index e00a6131..3665c517 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_dust_overlay.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_dust_overlay.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_moss.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_moss.png index 2887aae9..8da6888b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_moss.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_moss.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_moss_overlay.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_moss_overlay.png index 1a10d5eb..84a99c36 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_moss_overlay.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_side_moss_overlay.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_top.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_top.png index 74f13b76..0f2782a4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_top.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_medium_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side.png index cfdd7a22..6ac3ee72 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_dust.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_dust.png index e664cfe6..2c1eb0cf 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_dust.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_dust.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_dust_overlay.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_dust_overlay.png index 9a47ee11..b68f46ea 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_dust_overlay.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_dust_overlay.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_moss.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_moss.png index 5b2b0586..69ee4bba 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_moss.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_moss.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_moss_overlay.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_moss_overlay.png index a296b22f..944f3902 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_moss_overlay.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_small_side_moss_overlay.png differ diff --git a/src/main/resources/assets/betterend/textures/block/neon_cactus_small_top.png b/src/main/resources/assets/betterend/textures/block/neon_cactus_small_top.png index 23414dfe..3d200ae1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/neon_cactus_small_top.png and b/src/main/resources/assets/betterend/textures/block/neon_cactus_small_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/orango.png b/src/main/resources/assets/betterend/textures/block/orango.png index b4f74bc1..63d30f64 100644 Binary files a/src/main/resources/assets/betterend/textures/block/orango.png and b/src/main/resources/assets/betterend/textures/block/orango.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pallidium_full_side.png b/src/main/resources/assets/betterend/textures/block/pallidium_full_side.png new file mode 100644 index 00000000..2411e32b Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/pallidium_full_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pallidium_full_top.png b/src/main/resources/assets/betterend/textures/block/pallidium_full_top.png new file mode 100644 index 00000000..99484442 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/pallidium_full_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pallidium_heavy_side.png b/src/main/resources/assets/betterend/textures/block/pallidium_heavy_side.png new file mode 100644 index 00000000..ce0f0e8c Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/pallidium_heavy_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pallidium_heavy_top.png b/src/main/resources/assets/betterend/textures/block/pallidium_heavy_top.png new file mode 100644 index 00000000..2d10e51f Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/pallidium_heavy_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pallidium_thin_side.png b/src/main/resources/assets/betterend/textures/block/pallidium_thin_side.png new file mode 100644 index 00000000..650b7aaf Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/pallidium_thin_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pallidium_thin_top.png b/src/main/resources/assets/betterend/textures/block/pallidium_thin_top.png new file mode 100644 index 00000000..372221df Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/pallidium_thin_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pallidium_tiny_side.png b/src/main/resources/assets/betterend/textures/block/pallidium_tiny_side.png new file mode 100644 index 00000000..3aab3250 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/pallidium_tiny_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pallidium_tiny_top.png b/src/main/resources/assets/betterend/textures/block/pallidium_tiny_top.png new file mode 100644 index 00000000..488248c4 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/pallidium_tiny_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pink_moss_path_top.png b/src/main/resources/assets/betterend/textures/block/pink_moss_path_top.png index 9c76fae5..de91a403 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pink_moss_path_top.png and b/src/main/resources/assets/betterend/textures/block/pink_moss_path_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pond_anemone.png b/src/main/resources/assets/betterend/textures/block/pond_anemone.png index 48fef70e..a2115e4d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pond_anemone.png and b/src/main/resources/assets/betterend/textures/block/pond_anemone.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pond_anemone_e.png b/src/main/resources/assets/betterend/textures/block/pond_anemone_e.png index 0b21d42b..1b6cfb6e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pond_anemone_e.png and b/src/main/resources/assets/betterend/textures/block/pond_anemone_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/purple_polypore.png b/src/main/resources/assets/betterend/textures/block/purple_polypore.png index 655fb9fb..4f440610 100644 Binary files a/src/main/resources/assets/betterend/textures/block/purple_polypore.png and b/src/main/resources/assets/betterend/textures/block/purple_polypore.png differ diff --git a/src/main/resources/assets/betterend/textures/block/purpur_lantern_bottom.png b/src/main/resources/assets/betterend/textures/block/purpur_lantern_bottom.png index f3ed7066..2a7e59ab 100644 Binary files a/src/main/resources/assets/betterend/textures/block/purpur_lantern_bottom.png and b/src/main/resources/assets/betterend/textures/block/purpur_lantern_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/purpur_lantern_side.png b/src/main/resources/assets/betterend/textures/block/purpur_lantern_side.png index d96ca73e..2821ad7d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/purpur_lantern_side.png and b/src/main/resources/assets/betterend/textures/block/purpur_lantern_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/purpur_lantern_top.png b/src/main/resources/assets/betterend/textures/block/purpur_lantern_top.png index d9781078..18df5e0b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/purpur_lantern_top.png and b/src/main/resources/assets/betterend/textures/block/purpur_lantern_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_barrel_top_open.png b/src/main/resources/assets/betterend/textures/block/pythadendron_barrel_top_open.png index eacb1d41..819875ad 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_barrel_top_open.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_barrel_top_open.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_bookshelf.png b/src/main/resources/assets/betterend/textures/block/pythadendron_bookshelf.png index ee830cc6..a7c1eb27 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_bookshelf.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_bookshelf.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_composter_bottom.png b/src/main/resources/assets/betterend/textures/block/pythadendron_composter_bottom.png index b464e7f5..920bc289 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_composter_bottom.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_composter_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_composter_side.png b/src/main/resources/assets/betterend/textures/block/pythadendron_composter_side.png index bbe963db..2578d2a1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_composter_side.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_composter_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_composter_top.png b/src/main/resources/assets/betterend/textures/block/pythadendron_composter_top.png index 8c80853a..903ec9bb 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_composter_top.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_composter_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_bottom.png b/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_bottom.png index 9cb80e79..c602145b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_bottom.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_front.png b/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_front.png index c922003c..96058cab 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_front.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_side.png b/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_side.png index 5b006bb0..6f613692 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_side.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_top.png b/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_top.png index 6f799ca1..6f92664e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_top.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_crafting_table_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_door_side.png b/src/main/resources/assets/betterend/textures/block/pythadendron_door_side.png index feb975e7..94dd576d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_door_side.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_door_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_leaves.png b/src/main/resources/assets/betterend/textures/block/pythadendron_leaves.png index e4bec2e4..770229ac 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_leaves.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_leaves.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_log_side.png b/src/main/resources/assets/betterend/textures/block/pythadendron_log_side.png index c343d064..3ad2f165 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_log_side.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_log_side_mossy.png b/src/main/resources/assets/betterend/textures/block/pythadendron_log_side_mossy.png index bc53c4c1..d04ed45c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_log_side_mossy.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_log_side_mossy.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_log_side_mossy_2.png b/src/main/resources/assets/betterend/textures/block/pythadendron_log_side_mossy_2.png index ac5e3d3a..b8323919 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_log_side_mossy_2.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_log_side_mossy_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_log_top.png b/src/main/resources/assets/betterend/textures/block/pythadendron_log_top.png index 76dcbdea..73206e69 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_log_top.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_planks.png b/src/main/resources/assets/betterend/textures/block/pythadendron_planks.png index 940cf9d4..3c412f24 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_planks.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_planks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_sapling.png b/src/main/resources/assets/betterend/textures/block/pythadendron_sapling.png index c895622e..b12ef419 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_sapling.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_sapling.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_stripped_log_side.png b/src/main/resources/assets/betterend/textures/block/pythadendron_stripped_log_side.png index 676e3f02..12ad614d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_stripped_log_side.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_stripped_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_stripped_log_top.png b/src/main/resources/assets/betterend/textures/block/pythadendron_stripped_log_top.png index 437096e8..87ec4750 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_stripped_log_top.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_stripped_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/pythadendron_trapdoor.png b/src/main/resources/assets/betterend/textures/block/pythadendron_trapdoor.png index cadb9632..ca7113d2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/pythadendron_trapdoor.png and b/src/main/resources/assets/betterend/textures/block/pythadendron_trapdoor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/quartz_lantern_bottom.png b/src/main/resources/assets/betterend/textures/block/quartz_lantern_bottom.png index fc0421ad..4ac07c5a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/quartz_lantern_bottom.png and b/src/main/resources/assets/betterend/textures/block/quartz_lantern_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/quartz_lantern_top.png b/src/main/resources/assets/betterend/textures/block/quartz_lantern_top.png index ad6f16c8..6e5c5e5f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/quartz_lantern_top.png and b/src/main/resources/assets/betterend/textures/block/quartz_lantern_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/respawn_obelisk_top_and_side.png b/src/main/resources/assets/betterend/textures/block/respawn_obelisk_top_and_side.png index 7832bdb5..988fa52d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/respawn_obelisk_top_and_side.png and b/src/main/resources/assets/betterend/textures/block/respawn_obelisk_top_and_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/rubinea.png b/src/main/resources/assets/betterend/textures/block/rubinea.png index b590bfe8..ea924734 100644 Binary files a/src/main/resources/assets/betterend/textures/block/rubinea.png and b/src/main/resources/assets/betterend/textures/block/rubinea.png differ diff --git a/src/main/resources/assets/betterend/textures/block/rubinea_bottom.png b/src/main/resources/assets/betterend/textures/block/rubinea_bottom.png index 5601c268..8ad59259 100644 Binary files a/src/main/resources/assets/betterend/textures/block/rubinea_bottom.png and b/src/main/resources/assets/betterend/textures/block/rubinea_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/ruscus.png b/src/main/resources/assets/betterend/textures/block/ruscus.png index 68589632..0098eef0 100644 Binary files a/src/main/resources/assets/betterend/textures/block/ruscus.png and b/src/main/resources/assets/betterend/textures/block/ruscus.png differ diff --git a/src/main/resources/assets/betterend/textures/block/rutiscus_path_top.png b/src/main/resources/assets/betterend/textures/block/rutiscus_path_top.png index e01bc130..35a2f2c2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/rutiscus_path_top.png and b/src/main/resources/assets/betterend/textures/block/rutiscus_path_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/rutiscus_side.png b/src/main/resources/assets/betterend/textures/block/rutiscus_side.png index d052be19..ff0195f5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/rutiscus_side.png and b/src/main/resources/assets/betterend/textures/block/rutiscus_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/rutiscus_side_1.png b/src/main/resources/assets/betterend/textures/block/rutiscus_side_1.png index b92237a7..7c7cb921 100644 Binary files a/src/main/resources/assets/betterend/textures/block/rutiscus_side_1.png and b/src/main/resources/assets/betterend/textures/block/rutiscus_side_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/rutiscus_side_2.png b/src/main/resources/assets/betterend/textures/block/rutiscus_side_2.png index b3f35918..c24ccf60 100644 Binary files a/src/main/resources/assets/betterend/textures/block/rutiscus_side_2.png and b/src/main/resources/assets/betterend/textures/block/rutiscus_side_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/rutiscus_top_1.png b/src/main/resources/assets/betterend/textures/block/rutiscus_top_1.png index 17aba4aa..d3204145 100644 Binary files a/src/main/resources/assets/betterend/textures/block/rutiscus_top_1.png and b/src/main/resources/assets/betterend/textures/block/rutiscus_top_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/rutiscus_top_2.png b/src/main/resources/assets/betterend/textures/block/rutiscus_top_2.png index cb14baa0..43d50bce 100644 Binary files a/src/main/resources/assets/betterend/textures/block/rutiscus_top_2.png and b/src/main/resources/assets/betterend/textures/block/rutiscus_top_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/salteago.png b/src/main/resources/assets/betterend/textures/block/salteago.png index dd0df547..25f43f33 100644 Binary files a/src/main/resources/assets/betterend/textures/block/salteago.png and b/src/main/resources/assets/betterend/textures/block/salteago.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sandy_jadestone.png b/src/main/resources/assets/betterend/textures/block/sandy_jadestone.png index f00ff0c2..256ca2f7 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sandy_jadestone.png and b/src/main/resources/assets/betterend/textures/block/sandy_jadestone.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_bricks.png b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_bricks.png index 667f447f..939a6e8d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_bricks.png and b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_bricks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_flower_pot.png b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_flower_pot.png new file mode 100644 index 00000000..9b12e5a2 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_flower_pot.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_front.png b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_front.png index b248b45d..1c3f0779 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_front.png and b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_front_on.png b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_front_on.png index 7e6d7e3c..ce44d104 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_front_on.png and b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_front_on.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_side.png b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_side.png index 1efbd34b..0cbaf1a8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_side.png and b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_top.png b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_top.png index cf5b31c5..1c312e6a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_top.png and b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_furnace_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_lantern_bottom.png b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_lantern_bottom.png index 0807c5bc..98bb0831 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_lantern_bottom.png and b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_lantern_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_lantern_side.png b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_lantern_side.png index ada8266e..53691d81 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_lantern_side.png and b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_lantern_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_lantern_top.png b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_lantern_top.png index f6044f04..1e79a0dd 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_lantern_top.png and b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_lantern_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_polished.png b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_polished.png index 4ab1013d..d69f0992 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_polished.png and b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_polished.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_tiles.png b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_tiles.png index cbfcfa8a..761ca2fb 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sandy_jadestone_tiles.png and b/src/main/resources/assets/betterend/textures/block/sandy_jadestone_tiles.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sangnum_side.png b/src/main/resources/assets/betterend/textures/block/sangnum_side.png index 62bb58df..ee8d4fff 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sangnum_side.png and b/src/main/resources/assets/betterend/textures/block/sangnum_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sangnum_top.png b/src/main/resources/assets/betterend/textures/block/sangnum_top.png index e321cbb1..8382234f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sangnum_top.png and b/src/main/resources/assets/betterend/textures/block/sangnum_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/shadow_berry_leaves.png b/src/main/resources/assets/betterend/textures/block/shadow_berry_leaves.png index 88ac59a9..2be3feca 100644 Binary files a/src/main/resources/assets/betterend/textures/block/shadow_berry_leaves.png and b/src/main/resources/assets/betterend/textures/block/shadow_berry_leaves.png differ diff --git a/src/main/resources/assets/betterend/textures/block/shadow_grass_path_top.png b/src/main/resources/assets/betterend/textures/block/shadow_grass_path_top.png index 18d61cdd..628a98f4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/shadow_grass_path_top.png and b/src/main/resources/assets/betterend/textures/block/shadow_grass_path_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/shadow_grass_side.png b/src/main/resources/assets/betterend/textures/block/shadow_grass_side.png index e4ca5d7f..496d4f99 100644 Binary files a/src/main/resources/assets/betterend/textures/block/shadow_grass_side.png and b/src/main/resources/assets/betterend/textures/block/shadow_grass_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/shadow_grass_top.png b/src/main/resources/assets/betterend/textures/block/shadow_grass_top.png index 2fe86a05..2a2ecf69 100644 Binary files a/src/main/resources/assets/betterend/textures/block/shadow_grass_top.png and b/src/main/resources/assets/betterend/textures/block/shadow_grass_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/shadow_plant.png b/src/main/resources/assets/betterend/textures/block/shadow_plant.png index 40b46460..bd812aac 100644 Binary files a/src/main/resources/assets/betterend/textures/block/shadow_plant.png and b/src/main/resources/assets/betterend/textures/block/shadow_plant.png differ diff --git a/src/main/resources/assets/betterend/textures/block/shadow_plant_potted.png b/src/main/resources/assets/betterend/textures/block/shadow_plant_potted.png new file mode 100644 index 00000000..797bb567 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/shadow_plant_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/silk_moth_nest_connect.png b/src/main/resources/assets/betterend/textures/block/silk_moth_nest_connect.png index b6a5c7ee..df88a38c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/silk_moth_nest_connect.png and b/src/main/resources/assets/betterend/textures/block/silk_moth_nest_connect.png differ diff --git a/src/main/resources/assets/betterend/textures/block/small_amaranita_mushroom.png b/src/main/resources/assets/betterend/textures/block/small_amaranita_mushroom.png index f7ab7e63..51e2a511 100644 Binary files a/src/main/resources/assets/betterend/textures/block/small_amaranita_mushroom.png and b/src/main/resources/assets/betterend/textures/block/small_amaranita_mushroom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/small_jellyshroom_stem.png b/src/main/resources/assets/betterend/textures/block/small_jellyshroom_stem.png index c73056f1..ea93ff32 100644 Binary files a/src/main/resources/assets/betterend/textures/block/small_jellyshroom_stem.png and b/src/main/resources/assets/betterend/textures/block/small_jellyshroom_stem.png differ diff --git a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal.png b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal.png deleted file mode 100644 index e2981961..00000000 Binary files a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal.png and /dev/null differ diff --git a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_bricks.png b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_bricks.png index b6b4336b..f3cb7623 100644 Binary files a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_bricks.png and b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_bricks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_pillar_side.png b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_pillar_side.png index 6edbb4a2..409d2354 100644 Binary files a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_pillar_side.png and b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_pillar_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_pillar_top.png b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_pillar_top.png index 04973162..5ff24fe3 100644 Binary files a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_pillar_top.png and b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_pillar_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_polished.png b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_polished.png index 9b0a4fab..c17d40d8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_polished.png and b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_polished.png differ diff --git a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_shard.png b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_shard.png index aa1a21fe..f410d09e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_shard.png and b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_shard.png differ diff --git a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_side.png b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_side.png index e2981961..9828de1a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_side.png and b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_tiles.png b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_tiles.png index ad66fdd4..e69f57b1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_tiles.png and b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_tiles.png differ diff --git a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_top.png b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_top.png index ada5b494..420a521f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_top.png and b/src/main/resources/assets/betterend/textures/block/smaragdant_crystal_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock.png index cdecb5f2..9e4c20cc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_bricks.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_bricks.png index 4e7fda6f..d8411976 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_bricks.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_bricks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_bricks_wall_top.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_bricks_wall_top.png index 4f0b359c..c7cdaab2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_bricks_wall_top.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_bricks_wall_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_flower_pot.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_flower_pot.png new file mode 100644 index 00000000..14bec47e Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_flower_pot.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_front.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_front.png index dffaa6b8..54cc0de1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_front.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_front_on.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_front_on.png index 989c5650..f85b5bd3 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_front_on.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_front_on.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_side.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_side.png index c5b2f091..e2471df2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_side.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_top.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_top.png index 5314ff63..904e7782 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_top.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_furnace_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_lantern_side.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_lantern_side.png index 7912965c..e2af6b78 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_lantern_side.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_lantern_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_pillar_side.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_pillar_side.png index e6712047..26b4c916 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_pillar_side.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_pillar_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_polished.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_polished.png index 4493c2d3..e9056aa0 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_polished.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_polished.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_post_side.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_post_side.png index 75a57a67..140a2fab 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_post_side.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_post_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_post_top.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_post_top.png index aa8192cc..bc81074a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_post_top.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_post_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_tiles.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_tiles.png index 94c6540a..11683331 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_tiles.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_tiles.png differ diff --git a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_top.png b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_top.png index f6d3900a..fc306515 100644 Binary files a/src/main/resources/assets/betterend/textures/block/sulphuric_rock_top.png and b/src/main/resources/assets/betterend/textures/block/sulphuric_rock_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tail_moss.png b/src/main/resources/assets/betterend/textures/block/tail_moss.png index 6c1c583a..be639ec7 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tail_moss.png and b/src/main/resources/assets/betterend/textures/block/tail_moss.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_barrel_top.png b/src/main/resources/assets/betterend/textures/block/tenanea_barrel_top.png index 4813c41d..c498c4f4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_barrel_top.png and b/src/main/resources/assets/betterend/textures/block/tenanea_barrel_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_barrel_top_open.png b/src/main/resources/assets/betterend/textures/block/tenanea_barrel_top_open.png index 7a32a97e..11554ea6 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_barrel_top_open.png and b/src/main/resources/assets/betterend/textures/block/tenanea_barrel_top_open.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_bookshelf.png b/src/main/resources/assets/betterend/textures/block/tenanea_bookshelf.png index 3ca8d449..121a4cdc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_bookshelf.png and b/src/main/resources/assets/betterend/textures/block/tenanea_bookshelf.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_composter_bottom.png b/src/main/resources/assets/betterend/textures/block/tenanea_composter_bottom.png index 2b281191..60e78b3a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_composter_bottom.png and b/src/main/resources/assets/betterend/textures/block/tenanea_composter_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_composter_side.png b/src/main/resources/assets/betterend/textures/block/tenanea_composter_side.png index 84686721..8308504a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_composter_side.png and b/src/main/resources/assets/betterend/textures/block/tenanea_composter_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_composter_top.png b/src/main/resources/assets/betterend/textures/block/tenanea_composter_top.png index aaeb6391..497c16d1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_composter_top.png and b/src/main/resources/assets/betterend/textures/block/tenanea_composter_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_bottom.png b/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_bottom.png index 8031c220..ec5e10dd 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_bottom.png and b/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_front.png b/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_front.png index 5862ae14..a9ddfc87 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_front.png and b/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_side.png b/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_side.png index 751a91bc..3c0065e9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_side.png and b/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_top.png b/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_top.png index 842f74ab..6afe861a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_top.png and b/src/main/resources/assets/betterend/textures/block/tenanea_crafting_table_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_flowers.png b/src/main/resources/assets/betterend/textures/block/tenanea_flowers.png index db355c90..5280ebaa 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_flowers.png and b/src/main/resources/assets/betterend/textures/block/tenanea_flowers.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_flowers_bottom.png b/src/main/resources/assets/betterend/textures/block/tenanea_flowers_bottom.png index 783673aa..76c3e0e6 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_flowers_bottom.png and b/src/main/resources/assets/betterend/textures/block/tenanea_flowers_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_flowers_stem.png b/src/main/resources/assets/betterend/textures/block/tenanea_flowers_stem.png index a6132d47..511d81d2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_flowers_stem.png and b/src/main/resources/assets/betterend/textures/block/tenanea_flowers_stem.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_flowers_stem_bottom.png b/src/main/resources/assets/betterend/textures/block/tenanea_flowers_stem_bottom.png index 3afd63ec..82e3bcb8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_flowers_stem_bottom.png and b/src/main/resources/assets/betterend/textures/block/tenanea_flowers_stem_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_flowers_top.png b/src/main/resources/assets/betterend/textures/block/tenanea_flowers_top.png index 3c5937fd..8845c528 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_flowers_top.png and b/src/main/resources/assets/betterend/textures/block/tenanea_flowers_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_leaves.png b/src/main/resources/assets/betterend/textures/block/tenanea_leaves.png index a4285202..8bb1150d 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_leaves.png and b/src/main/resources/assets/betterend/textures/block/tenanea_leaves.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_log_side.png b/src/main/resources/assets/betterend/textures/block/tenanea_log_side.png index eda9c545..f34dab0b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_log_side.png and b/src/main/resources/assets/betterend/textures/block/tenanea_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_log_top.png b/src/main/resources/assets/betterend/textures/block/tenanea_log_top.png index b0edb7c8..da917216 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_log_top.png and b/src/main/resources/assets/betterend/textures/block/tenanea_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_outer_leaves.png b/src/main/resources/assets/betterend/textures/block/tenanea_outer_leaves.png index 0db71132..8aa75fd6 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_outer_leaves.png and b/src/main/resources/assets/betterend/textures/block/tenanea_outer_leaves.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_planks.png b/src/main/resources/assets/betterend/textures/block/tenanea_planks.png index ef6e8e70..159e3346 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_planks.png and b/src/main/resources/assets/betterend/textures/block/tenanea_planks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_stripped_log_side.png b/src/main/resources/assets/betterend/textures/block/tenanea_stripped_log_side.png index 9ef2c0d0..dbc75bde 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_stripped_log_side.png and b/src/main/resources/assets/betterend/textures/block/tenanea_stripped_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_stripped_log_top.png b/src/main/resources/assets/betterend/textures/block/tenanea_stripped_log_top.png index 43958ea0..80027302 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_stripped_log_top.png and b/src/main/resources/assets/betterend/textures/block/tenanea_stripped_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tenanea_trapdoor.png b/src/main/resources/assets/betterend/textures/block/tenanea_trapdoor.png index 2abfd2fc..dea0f719 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tenanea_trapdoor.png and b/src/main/resources/assets/betterend/textures/block/tenanea_trapdoor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_anvil_back.png b/src/main/resources/assets/betterend/textures/block/terminite_anvil_back.png index ab1960cb..886d4c8b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_anvil_back.png and b/src/main/resources/assets/betterend/textures/block/terminite_anvil_back.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_anvil_front.png b/src/main/resources/assets/betterend/textures/block/terminite_anvil_front.png index 837326c8..80a608cc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_anvil_front.png and b/src/main/resources/assets/betterend/textures/block/terminite_anvil_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_anvil_panel.png b/src/main/resources/assets/betterend/textures/block/terminite_anvil_panel.png index c017633d..46f2e6c8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_anvil_panel.png and b/src/main/resources/assets/betterend/textures/block/terminite_anvil_panel.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_anvil_top_1.png b/src/main/resources/assets/betterend/textures/block/terminite_anvil_top_1.png index b590f604..5a90d0f7 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_anvil_top_1.png and b/src/main/resources/assets/betterend/textures/block/terminite_anvil_top_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_anvil_top_2.png b/src/main/resources/assets/betterend/textures/block/terminite_anvil_top_2.png index cf463857..c4a64326 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_anvil_top_2.png and b/src/main/resources/assets/betterend/textures/block/terminite_anvil_top_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_bars.png b/src/main/resources/assets/betterend/textures/block/terminite_bars.png index e9be368c..7d9623a1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_bars.png and b/src/main/resources/assets/betterend/textures/block/terminite_bars.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_block.png b/src/main/resources/assets/betterend/textures/block/terminite_block.png index 26c25d6c..a0b4d738 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_block.png and b/src/main/resources/assets/betterend/textures/block/terminite_block.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_bulb_vine_lantern_metal.png b/src/main/resources/assets/betterend/textures/block/terminite_bulb_vine_lantern_metal.png index e8177af7..6278cecd 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_bulb_vine_lantern_metal.png and b/src/main/resources/assets/betterend/textures/block/terminite_bulb_vine_lantern_metal.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_chandelier_ceil.png b/src/main/resources/assets/betterend/textures/block/terminite_chandelier_ceil.png index 0578cba3..2c4bc2e1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_chandelier_ceil.png and b/src/main/resources/assets/betterend/textures/block/terminite_chandelier_ceil.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_chandelier_floor.png b/src/main/resources/assets/betterend/textures/block/terminite_chandelier_floor.png index a44c68b6..bdf332fa 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_chandelier_floor.png and b/src/main/resources/assets/betterend/textures/block/terminite_chandelier_floor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_chandelier_wall.png b/src/main/resources/assets/betterend/textures/block/terminite_chandelier_wall.png index 689e5c9e..dd8498f8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_chandelier_wall.png and b/src/main/resources/assets/betterend/textures/block/terminite_chandelier_wall.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_door_bottom.png b/src/main/resources/assets/betterend/textures/block/terminite_door_bottom.png index 3491b811..1ec27441 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_door_bottom.png and b/src/main/resources/assets/betterend/textures/block/terminite_door_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_door_side.png b/src/main/resources/assets/betterend/textures/block/terminite_door_side.png index e7eeefcc..de8623d6 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_door_side.png and b/src/main/resources/assets/betterend/textures/block/terminite_door_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_door_top.png b/src/main/resources/assets/betterend/textures/block/terminite_door_top.png index 66e886cc..1a4f4d70 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_door_top.png and b/src/main/resources/assets/betterend/textures/block/terminite_door_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_tile.png b/src/main/resources/assets/betterend/textures/block/terminite_tile.png index 3b31396d..1464c9ff 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_tile.png and b/src/main/resources/assets/betterend/textures/block/terminite_tile.png differ diff --git a/src/main/resources/assets/betterend/textures/block/terminite_trapdoor.png b/src/main/resources/assets/betterend/textures/block/terminite_trapdoor.png index e904fb28..00364b25 100644 Binary files a/src/main/resources/assets/betterend/textures/block/terminite_trapdoor.png and b/src/main/resources/assets/betterend/textures/block/terminite_trapdoor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_anvil_front.png b/src/main/resources/assets/betterend/textures/block/thallasium_anvil_front.png index 83a1ac99..2f0fffad 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_anvil_front.png and b/src/main/resources/assets/betterend/textures/block/thallasium_anvil_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_anvil_panel.png b/src/main/resources/assets/betterend/textures/block/thallasium_anvil_panel.png index 78d46224..44196c65 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_anvil_panel.png and b/src/main/resources/assets/betterend/textures/block/thallasium_anvil_panel.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_anvil_top_1.png b/src/main/resources/assets/betterend/textures/block/thallasium_anvil_top_1.png index a7189969..92be9637 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_anvil_top_1.png and b/src/main/resources/assets/betterend/textures/block/thallasium_anvil_top_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_anvil_top_2.png b/src/main/resources/assets/betterend/textures/block/thallasium_anvil_top_2.png index 6d41d028..c99a62b0 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_anvil_top_2.png and b/src/main/resources/assets/betterend/textures/block/thallasium_anvil_top_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_bars.png b/src/main/resources/assets/betterend/textures/block/thallasium_bars.png index 465a4a6c..25568e74 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_bars.png and b/src/main/resources/assets/betterend/textures/block/thallasium_bars.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_block.png b/src/main/resources/assets/betterend/textures/block/thallasium_block.png index 50d0d93c..10700012 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_block.png and b/src/main/resources/assets/betterend/textures/block/thallasium_block.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_bulb_vine_lantern_metal.png b/src/main/resources/assets/betterend/textures/block/thallasium_bulb_vine_lantern_metal.png index ca39eac9..7ac65a9e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_bulb_vine_lantern_metal.png and b/src/main/resources/assets/betterend/textures/block/thallasium_bulb_vine_lantern_metal.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_chandelier_ceil.png b/src/main/resources/assets/betterend/textures/block/thallasium_chandelier_ceil.png index 942ba9ce..66aef332 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_chandelier_ceil.png and b/src/main/resources/assets/betterend/textures/block/thallasium_chandelier_ceil.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_chandelier_floor.png b/src/main/resources/assets/betterend/textures/block/thallasium_chandelier_floor.png index 90b9a25b..ef02d30b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_chandelier_floor.png and b/src/main/resources/assets/betterend/textures/block/thallasium_chandelier_floor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_chandelier_wall.png b/src/main/resources/assets/betterend/textures/block/thallasium_chandelier_wall.png index 59cb4f63..95ef5288 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_chandelier_wall.png and b/src/main/resources/assets/betterend/textures/block/thallasium_chandelier_wall.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_door_bottom.png b/src/main/resources/assets/betterend/textures/block/thallasium_door_bottom.png index 23832cdd..d4e4299a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_door_bottom.png and b/src/main/resources/assets/betterend/textures/block/thallasium_door_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_door_side.png b/src/main/resources/assets/betterend/textures/block/thallasium_door_side.png index 597023e8..aa266b4e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_door_side.png and b/src/main/resources/assets/betterend/textures/block/thallasium_door_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_door_top.png b/src/main/resources/assets/betterend/textures/block/thallasium_door_top.png index d0787596..8fa8642a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_door_top.png and b/src/main/resources/assets/betterend/textures/block/thallasium_door_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/thallasium_trapdoor.png b/src/main/resources/assets/betterend/textures/block/thallasium_trapdoor.png index 30b1170e..30d1aeaa 100644 Binary files a/src/main/resources/assets/betterend/textures/block/thallasium_trapdoor.png and b/src/main/resources/assets/betterend/textures/block/thallasium_trapdoor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tube_worm_1.png b/src/main/resources/assets/betterend/textures/block/tube_worm_1.png index 2be52d58..1b993308 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tube_worm_1.png and b/src/main/resources/assets/betterend/textures/block/tube_worm_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tube_worm_2.png b/src/main/resources/assets/betterend/textures/block/tube_worm_2.png index 7b90cd00..7a2331ce 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tube_worm_2.png and b/src/main/resources/assets/betterend/textures/block/tube_worm_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/tube_worm_3.png b/src/main/resources/assets/betterend/textures/block/tube_worm_3.png index 8e97cc6d..fb6084a7 100644 Binary files a/src/main/resources/assets/betterend/textures/block/tube_worm_3.png and b/src/main/resources/assets/betterend/textures/block/tube_worm_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/twisted_moss.png b/src/main/resources/assets/betterend/textures/block/twisted_moss.png index 3f734254..64352afd 100644 Binary files a/src/main/resources/assets/betterend/textures/block/twisted_moss.png and b/src/main/resources/assets/betterend/textures/block/twisted_moss.png differ diff --git a/src/main/resources/assets/betterend/textures/block/twisted_moss_2.png b/src/main/resources/assets/betterend/textures/block/twisted_moss_2.png index befe1545..dfc98752 100644 Binary files a/src/main/resources/assets/betterend/textures/block/twisted_moss_2.png and b/src/main/resources/assets/betterend/textures/block/twisted_moss_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_bottom.png b/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_bottom.png index 53d299c7..f12047a3 100644 Binary files a/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_bottom.png and b/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_end.png b/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_end.png index b9464747..06d1bbad 100644 Binary files a/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_end.png and b/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_end.png differ diff --git a/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_small.png b/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_small.png index 3ef19a06..5337e498 100644 Binary files a/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_small.png and b/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_small.png differ diff --git a/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_sporophyte.png b/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_sporophyte.png index 2fc30812..20b3b409 100644 Binary files a/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_sporophyte.png and b/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_sporophyte.png differ diff --git a/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_sporophyte_e.png b/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_sporophyte_e.png index 703a1e39..d2feb638 100644 Binary files a/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_sporophyte_e.png and b/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_sporophyte_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_up.png b/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_up.png index 7266a4c2..ab04f81a 100644 Binary files a/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_up.png and b/src/main/resources/assets/betterend/textures/block/twisted_umbrella_moss_up.png differ diff --git a/src/main/resources/assets/betterend/textures/block/twisted_vine.png b/src/main/resources/assets/betterend/textures/block/twisted_vine.png index 475ea57d..94035748 100644 Binary files a/src/main/resources/assets/betterend/textures/block/twisted_vine.png and b/src/main/resources/assets/betterend/textures/block/twisted_vine.png differ diff --git a/src/main/resources/assets/betterend/textures/block/twisted_vine_bottom.png b/src/main/resources/assets/betterend/textures/block/twisted_vine_bottom.png index e54ac776..44dfe5ad 100644 Binary files a/src/main/resources/assets/betterend/textures/block/twisted_vine_bottom.png and b/src/main/resources/assets/betterend/textures/block/twisted_vine_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/twisted_vine_roots.png b/src/main/resources/assets/betterend/textures/block/twisted_vine_roots.png index 77d9a9de..a68c549b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/twisted_vine_roots.png and b/src/main/resources/assets/betterend/textures/block/twisted_vine_roots.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith.png b/src/main/resources/assets/betterend/textures/block/umbralith.png new file mode 100644 index 00000000..5ed097f7 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_2.png b/src/main/resources/assets/betterend/textures/block/umbralith_2.png new file mode 100644 index 00000000..a49cc9bb Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_3.png b/src/main/resources/assets/betterend/textures/block/umbralith_3.png new file mode 100644 index 00000000..0434d35e Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_3_e.png b/src/main/resources/assets/betterend/textures/block/umbralith_3_e.png new file mode 100644 index 00000000..bea94a5d Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_3_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_4.png b/src/main/resources/assets/betterend/textures/block/umbralith_4.png new file mode 100644 index 00000000..1b6d9efe Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_4_e.png b/src/main/resources/assets/betterend/textures/block/umbralith_4_e.png new file mode 100644 index 00000000..70c9f9cb Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_4_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_5.png b/src/main/resources/assets/betterend/textures/block/umbralith_5.png new file mode 100644 index 00000000..d2986cfe Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_5.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_5_e.png b/src/main/resources/assets/betterend/textures/block/umbralith_5_e.png new file mode 100644 index 00000000..7f3712a3 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_5_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_6.png b/src/main/resources/assets/betterend/textures/block/umbralith_6.png new file mode 100644 index 00000000..4f7b2189 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_6.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_7.png b/src/main/resources/assets/betterend/textures/block/umbralith_7.png new file mode 100644 index 00000000..89d2b5e6 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_7.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_bricks.png b/src/main/resources/assets/betterend/textures/block/umbralith_bricks.png new file mode 100644 index 00000000..f5af79cb Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_bricks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_flower_pot.png b/src/main/resources/assets/betterend/textures/block/umbralith_flower_pot.png new file mode 100644 index 00000000..23ae2fc1 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_flower_pot.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_furnace_front.png b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_front.png new file mode 100644 index 00000000..20f8cbf2 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_furnace_front_on.png b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_front_on.png new file mode 100644 index 00000000..696f967d Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_front_on.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_furnace_glow.png b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_glow.png new file mode 100644 index 00000000..ad655693 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_furnace_glow.png.mcmeta b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_glow.png.mcmeta new file mode 100644 index 00000000..1c2798b6 --- /dev/null +++ b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_glow.png.mcmeta @@ -0,0 +1,12 @@ +{ + "animation": { + "interpolate": true, + "frametime": 8, + "frames": [ + 0, + 1, + 2, + 3 + ] + } +} diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_furnace_glow_e.png b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_glow_e.png new file mode 100644 index 00000000..ad655693 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_glow_e.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_furnace_glow_e.png.mcmeta b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_glow_e.png.mcmeta new file mode 100644 index 00000000..1c2798b6 --- /dev/null +++ b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_glow_e.png.mcmeta @@ -0,0 +1,12 @@ +{ + "animation": { + "interpolate": true, + "frametime": 8, + "frames": [ + 0, + 1, + 2, + 3 + ] + } +} diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_furnace_side.png b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_side.png new file mode 100644 index 00000000..dc5d4d97 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_furnace_top.png b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_top.png new file mode 100644 index 00000000..45986bf8 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_furnace_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_lantern_bottom.png b/src/main/resources/assets/betterend/textures/block/umbralith_lantern_bottom.png new file mode 100644 index 00000000..41b38062 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_lantern_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_lantern_side.png b/src/main/resources/assets/betterend/textures/block/umbralith_lantern_side.png new file mode 100644 index 00000000..63eeef86 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_lantern_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_lantern_top.png b/src/main/resources/assets/betterend/textures/block/umbralith_lantern_top.png new file mode 100644 index 00000000..3eb6a18c Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_lantern_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_pillar_side.png b/src/main/resources/assets/betterend/textures/block/umbralith_pillar_side.png new file mode 100644 index 00000000..68552023 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_pillar_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_pillar_top.png b/src/main/resources/assets/betterend/textures/block/umbralith_pillar_top.png new file mode 100644 index 00000000..ad283b42 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_pillar_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_polished.png b/src/main/resources/assets/betterend/textures/block/umbralith_polished.png new file mode 100644 index 00000000..c5a256cc Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_polished.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbralith_tiles.png b/src/main/resources/assets/betterend/textures/block/umbralith_tiles.png new file mode 100644 index 00000000..71ff3226 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/umbralith_tiles.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_bookshelf.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_bookshelf.png index 0c0167a2..5b8a40ae 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_bookshelf.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_bookshelf.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_composter_bottom.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_composter_bottom.png index 859d7e13..01065fd5 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_composter_bottom.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_composter_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_composter_side.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_composter_side.png index ce3be5bc..5bd2cdca 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_composter_side.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_composter_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_composter_top.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_composter_top.png index 7ca47be8..4873c7ef 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_composter_top.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_composter_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_crafting_table_front.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_crafting_table_front.png index 56f6e074..860b111c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_crafting_table_front.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_crafting_table_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_crafting_table_side.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_crafting_table_side.png index 8b6dc906..7a1e8ff2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_crafting_table_side.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_crafting_table_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_crafting_table_top.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_crafting_table_top.png index 2b5e02af..851d73ba 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_crafting_table_top.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_crafting_table_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_door_bottom.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_door_bottom.png index 3ca75a7b..eb16485c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_door_bottom.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_door_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_door_side.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_door_side.png index 4962a1e6..d82aa4f1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_door_side.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_door_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_door_top.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_door_top.png index a8e2472f..41fe7a86 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_door_top.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_door_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_log_side.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_log_side.png index 74ab18a6..1052e62b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_log_side.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_log_top.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_log_top.png index 1aed4f68..d2e7a4a2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_log_top.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane.png index 6aed0419..d9ccb39b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_0.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_0.png index 668b3236..6eea05c0 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_0.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_0.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_1.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_1.png index 91caf5c7..a9080d6b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_1.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_1.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_2.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_2.png index 293c6b16..c1e3fcd1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_2.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_2.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_3.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_3.png index da56a9b9..57ad9bd9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_3.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_3.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_4.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_4.png index 3ff72f88..0dacbc6c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_4.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_4.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_5.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_5.png index 001dadc9..292c8b96 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_5.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_5.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_6.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_6.png index f431af32..bc8fe86e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_6.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_6.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_7.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_7.png index 5e3d4f8a..b37365d4 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_7.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_membrane_7.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_planks.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_planks.png index fa89c7e5..da8d7800 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_planks.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_planks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_sapling.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_sapling.png index 5a269b70..b104d279 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_sapling.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_sapling.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_stripped_log_side.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_stripped_log_side.png index c0109808..b677ec04 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_stripped_log_side.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_stripped_log_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_stripped_log_top.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_stripped_log_top.png index 5a9c4c75..6cd36eed 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_stripped_log_top.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_stripped_log_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/umbrella_tree_trapdoor.png b/src/main/resources/assets/betterend/textures/block/umbrella_tree_trapdoor.png index 20c4233c..3a04b5bc 100644 Binary files a/src/main/resources/assets/betterend/textures/block/umbrella_tree_trapdoor.png and b/src/main/resources/assets/betterend/textures/block/umbrella_tree_trapdoor.png differ diff --git a/src/main/resources/assets/betterend/textures/block/vaiolush_fern.png b/src/main/resources/assets/betterend/textures/block/vaiolush_fern.png index 81631cec..f1fe5267 100644 Binary files a/src/main/resources/assets/betterend/textures/block/vaiolush_fern.png and b/src/main/resources/assets/betterend/textures/block/vaiolush_fern.png differ diff --git a/src/main/resources/assets/betterend/textures/block/vaiolush_fern_potted.png b/src/main/resources/assets/betterend/textures/block/vaiolush_fern_potted.png new file mode 100644 index 00000000..2797cacf Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/vaiolush_fern_potted.png differ diff --git a/src/main/resources/assets/betterend/textures/block/violecite.png b/src/main/resources/assets/betterend/textures/block/violecite.png index 7b3f9b76..c36e1d40 100644 Binary files a/src/main/resources/assets/betterend/textures/block/violecite.png and b/src/main/resources/assets/betterend/textures/block/violecite.png differ diff --git a/src/main/resources/assets/betterend/textures/block/violecite_bricks.png b/src/main/resources/assets/betterend/textures/block/violecite_bricks.png index bfee2087..c2bc46b7 100644 Binary files a/src/main/resources/assets/betterend/textures/block/violecite_bricks.png and b/src/main/resources/assets/betterend/textures/block/violecite_bricks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/violecite_flower_pot.png b/src/main/resources/assets/betterend/textures/block/violecite_flower_pot.png new file mode 100644 index 00000000..c8551839 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/violecite_flower_pot.png differ diff --git a/src/main/resources/assets/betterend/textures/block/violecite_furnace_front.png b/src/main/resources/assets/betterend/textures/block/violecite_furnace_front.png index a00b7eb5..0766f1ee 100644 Binary files a/src/main/resources/assets/betterend/textures/block/violecite_furnace_front.png and b/src/main/resources/assets/betterend/textures/block/violecite_furnace_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/violecite_furnace_side.png b/src/main/resources/assets/betterend/textures/block/violecite_furnace_side.png index 311fda8c..11ec02fe 100644 Binary files a/src/main/resources/assets/betterend/textures/block/violecite_furnace_side.png and b/src/main/resources/assets/betterend/textures/block/violecite_furnace_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/violecite_furnace_top.png b/src/main/resources/assets/betterend/textures/block/violecite_furnace_top.png index dffd5b35..1f616a4c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/violecite_furnace_top.png and b/src/main/resources/assets/betterend/textures/block/violecite_furnace_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/violecite_pillar_side.png b/src/main/resources/assets/betterend/textures/block/violecite_pillar_side.png index a7b85016..029a3d95 100644 Binary files a/src/main/resources/assets/betterend/textures/block/violecite_pillar_side.png and b/src/main/resources/assets/betterend/textures/block/violecite_pillar_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/violecite_pillar_top.png b/src/main/resources/assets/betterend/textures/block/violecite_pillar_top.png index e68fb339..81a02a5b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/violecite_pillar_top.png and b/src/main/resources/assets/betterend/textures/block/violecite_pillar_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/violecite_polished.png b/src/main/resources/assets/betterend/textures/block/violecite_polished.png index 38655205..5240a81c 100644 Binary files a/src/main/resources/assets/betterend/textures/block/violecite_polished.png and b/src/main/resources/assets/betterend/textures/block/violecite_polished.png differ diff --git a/src/main/resources/assets/betterend/textures/block/violecite_post_side.png b/src/main/resources/assets/betterend/textures/block/violecite_post_side.png index aa2e5fe7..11701e9e 100644 Binary files a/src/main/resources/assets/betterend/textures/block/violecite_post_side.png and b/src/main/resources/assets/betterend/textures/block/violecite_post_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone.png index 9e756998..8ce9445b 100644 Binary files a/src/main/resources/assets/betterend/textures/block/virid_jadestone.png and b/src/main/resources/assets/betterend/textures/block/virid_jadestone.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone_bricks.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone_bricks.png index ebb6a9ab..55ee89e1 100644 Binary files a/src/main/resources/assets/betterend/textures/block/virid_jadestone_bricks.png and b/src/main/resources/assets/betterend/textures/block/virid_jadestone_bricks.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone_flower_pot.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone_flower_pot.png new file mode 100644 index 00000000..72603752 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/block/virid_jadestone_flower_pot.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_front.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_front.png index d71ecb81..5c578d7f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_front.png and b/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_front.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_front_on.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_front_on.png index 899e1c14..51464edb 100644 Binary files a/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_front_on.png and b/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_front_on.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_side.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_side.png index ecf9569c..1335de36 100644 Binary files a/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_side.png and b/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_top.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_top.png index c81182e2..e6f9670f 100644 Binary files a/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_top.png and b/src/main/resources/assets/betterend/textures/block/virid_jadestone_furnace_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone_lantern_bottom.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone_lantern_bottom.png index 3e78f2dc..fb39e011 100644 Binary files a/src/main/resources/assets/betterend/textures/block/virid_jadestone_lantern_bottom.png and b/src/main/resources/assets/betterend/textures/block/virid_jadestone_lantern_bottom.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone_lantern_side.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone_lantern_side.png index 9e3e91e5..425961d8 100644 Binary files a/src/main/resources/assets/betterend/textures/block/virid_jadestone_lantern_side.png and b/src/main/resources/assets/betterend/textures/block/virid_jadestone_lantern_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone_lantern_top.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone_lantern_top.png index 2ceefd0d..b4ae13d6 100644 Binary files a/src/main/resources/assets/betterend/textures/block/virid_jadestone_lantern_top.png and b/src/main/resources/assets/betterend/textures/block/virid_jadestone_lantern_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone_pillar_side.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone_pillar_side.png index 502ffa0e..df24dd33 100644 Binary files a/src/main/resources/assets/betterend/textures/block/virid_jadestone_pillar_side.png and b/src/main/resources/assets/betterend/textures/block/virid_jadestone_pillar_side.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone_pillar_top.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone_pillar_top.png index 7879b95f..96e85dd2 100644 Binary files a/src/main/resources/assets/betterend/textures/block/virid_jadestone_pillar_top.png and b/src/main/resources/assets/betterend/textures/block/virid_jadestone_pillar_top.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone_polished.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone_polished.png index 38460f73..f810e5f9 100644 Binary files a/src/main/resources/assets/betterend/textures/block/virid_jadestone_polished.png and b/src/main/resources/assets/betterend/textures/block/virid_jadestone_polished.png differ diff --git a/src/main/resources/assets/betterend/textures/block/virid_jadestone_tiles.png b/src/main/resources/assets/betterend/textures/block/virid_jadestone_tiles.png index 4d7db656..f0f0d052 100644 Binary files a/src/main/resources/assets/betterend/textures/block/virid_jadestone_tiles.png and b/src/main/resources/assets/betterend/textures/block/virid_jadestone_tiles.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/chest/dragon_tree_chest.png b/src/main/resources/assets/betterend/textures/entity/chest/dragon_tree_chest.png index d610d601..c3d71599 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/chest/dragon_tree_chest.png and b/src/main/resources/assets/betterend/textures/entity/chest/dragon_tree_chest.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/chest/dragon_tree_chest_right.png b/src/main/resources/assets/betterend/textures/entity/chest/dragon_tree_chest_right.png index 56835c74..95acf304 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/chest/dragon_tree_chest_right.png and b/src/main/resources/assets/betterend/textures/entity/chest/dragon_tree_chest_right.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/chest/lucernia_chest.png b/src/main/resources/assets/betterend/textures/entity/chest/lucernia_chest.png index 5c736a98..6878d49e 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/chest/lucernia_chest.png and b/src/main/resources/assets/betterend/textures/entity/chest/lucernia_chest.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/chest/lucernia_chest_left.png b/src/main/resources/assets/betterend/textures/entity/chest/lucernia_chest_left.png index 2538d299..cfef1815 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/chest/lucernia_chest_left.png and b/src/main/resources/assets/betterend/textures/entity/chest/lucernia_chest_left.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/chest/lucernia_chest_right.png b/src/main/resources/assets/betterend/textures/entity/chest/lucernia_chest_right.png index ae64b382..bbf45721 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/chest/lucernia_chest_right.png and b/src/main/resources/assets/betterend/textures/entity/chest/lucernia_chest_right.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/chest/mossy_glowshroom_chest.png b/src/main/resources/assets/betterend/textures/entity/chest/mossy_glowshroom_chest.png index b4213e59..764269a0 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/chest/mossy_glowshroom_chest.png and b/src/main/resources/assets/betterend/textures/entity/chest/mossy_glowshroom_chest.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/chest/pythadendron_chest.png b/src/main/resources/assets/betterend/textures/entity/chest/pythadendron_chest.png index ea5565fa..d35814cf 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/chest/pythadendron_chest.png and b/src/main/resources/assets/betterend/textures/entity/chest/pythadendron_chest.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/chest/pythadendron_chest_left.png b/src/main/resources/assets/betterend/textures/entity/chest/pythadendron_chest_left.png index ad430ec1..da8fa6fd 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/chest/pythadendron_chest_left.png and b/src/main/resources/assets/betterend/textures/entity/chest/pythadendron_chest_left.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/chest/pythadendron_chest_right.png b/src/main/resources/assets/betterend/textures/entity/chest/pythadendron_chest_right.png index dc8d6fa9..ddbd1e86 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/chest/pythadendron_chest_right.png and b/src/main/resources/assets/betterend/textures/entity/chest/pythadendron_chest_right.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa.png b/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa.png index 5f5dbb93..547a194a 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa.png and b/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa_glow.png b/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa_glow.png index 1ff0bcf7..90ec8895 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa_glow.png and b/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa_sulphur.png b/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa_sulphur.png index 4cf67740..7abb243f 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa_sulphur.png and b/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa_sulphur.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa_sulphur_glow.png b/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa_sulphur_glow.png index d302c5a7..b0196652 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa_sulphur_glow.png and b/src/main/resources/assets/betterend/textures/entity/cubozoa/cubozoa_sulphur_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/dragonfly.png b/src/main/resources/assets/betterend/textures/entity/dragonfly.png index 3c69d09f..7a3cc9a7 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/dragonfly.png and b/src/main/resources/assets/betterend/textures/entity/dragonfly.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/dragonfly_glow.png b/src/main/resources/assets/betterend/textures/entity/dragonfly_glow.png index c781f72c..10ef43ce 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/dragonfly_glow.png and b/src/main/resources/assets/betterend/textures/entity/dragonfly_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/elytra_armored.png b/src/main/resources/assets/betterend/textures/entity/elytra_armored.png index 4fb41886..ce93c8c3 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/elytra_armored.png and b/src/main/resources/assets/betterend/textures/entity/elytra_armored.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/elytra_crystalite.png b/src/main/resources/assets/betterend/textures/entity/elytra_crystalite.png index 6f970955..eda29ead 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/elytra_crystalite.png and b/src/main/resources/assets/betterend/textures/entity/elytra_crystalite.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_0.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_0.png index 9f77504f..aa0c2bc5 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_0.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_0.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_0_glow.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_0_glow.png index c7ac74e0..b0f5b754 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_0_glow.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_0_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_1.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_1.png index 4d73ab13..416975bc 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_1.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_1.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_1_glow.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_1_glow.png index f3c96e46..ded5c13e 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_1_glow.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_1_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_2.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_2.png index f2f2e224..effea377 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_2.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_2.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_2_glow.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_2_glow.png index 1689a3a5..c08d19cc 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_2_glow.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_2_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_3.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_3.png index dc1137da..40d0bf47 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_3.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_3.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_3_glow.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_3_glow.png index 1bc4dfee..b892df0b 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_3_glow.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_3_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_4.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_4.png index 2db3f17e..d98eaa8d 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_4.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_4.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_4_glow.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_4_glow.png index 25fc9931..5b0d068c 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_4_glow.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_4_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_5.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_5.png index 6120cb0a..c9a33250 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_5.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_5.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_5_glow.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_5_glow.png index 03d527ab..bbdad63a 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_5_glow.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_5_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_6.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_6.png index 606fbca6..79c9d0fd 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_6.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_6.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_6_glow.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_6_glow.png index 43118e03..880890bd 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_6_glow.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_6_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_7.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_7.png index 6648a828..987a8e18 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_7.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_7.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_7_glow.png b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_7_glow.png index 1577d4a0..ac00119f 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_7_glow.png and b/src/main/resources/assets/betterend/textures/entity/end_fish/end_fish_7_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_amber.png b/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_amber.png index 2f44e329..035b17e7 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_amber.png and b/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_amber.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_amber_glow.png b/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_amber_glow.png index ab8288de..beb64749 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_amber_glow.png and b/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_amber_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_glow.png b/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_glow.png index 472300de..5560e6d4 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_glow.png and b/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_lake_glow.png b/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_lake_glow.png index 711d1497..56cb43ca 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_lake_glow.png and b/src/main/resources/assets/betterend/textures/entity/end_slime/end_slime_lake_glow.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/eternal_crystal.png b/src/main/resources/assets/betterend/textures/entity/eternal_crystal.png index 9b63ccf3..52c3eaa4 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/eternal_crystal.png and b/src/main/resources/assets/betterend/textures/entity/eternal_crystal.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/shadow_walker.png b/src/main/resources/assets/betterend/textures/entity/shadow_walker.png index 2bd9593d..a43d152a 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/shadow_walker.png and b/src/main/resources/assets/betterend/textures/entity/shadow_walker.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/sign/dragon_tree_sign.png b/src/main/resources/assets/betterend/textures/entity/sign/dragon_tree_sign.png index 20faf88d..a4fd763f 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/sign/dragon_tree_sign.png and b/src/main/resources/assets/betterend/textures/entity/sign/dragon_tree_sign.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/sign/end_lotus_sign.png b/src/main/resources/assets/betterend/textures/entity/sign/end_lotus_sign.png index 2d8d9e6b..bf79c45e 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/sign/end_lotus_sign.png and b/src/main/resources/assets/betterend/textures/entity/sign/end_lotus_sign.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/sign/helix_tree_sign.png b/src/main/resources/assets/betterend/textures/entity/sign/helix_tree_sign.png index 7df69a2e..2f886d23 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/sign/helix_tree_sign.png and b/src/main/resources/assets/betterend/textures/entity/sign/helix_tree_sign.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/sign/jellyshroom_sign.png b/src/main/resources/assets/betterend/textures/entity/sign/jellyshroom_sign.png index f16e9528..2e49e074 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/sign/jellyshroom_sign.png and b/src/main/resources/assets/betterend/textures/entity/sign/jellyshroom_sign.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/sign/lacugrove_sign.png b/src/main/resources/assets/betterend/textures/entity/sign/lacugrove_sign.png index b4164eb6..8ffe4247 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/sign/lacugrove_sign.png and b/src/main/resources/assets/betterend/textures/entity/sign/lacugrove_sign.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/sign/lucernia_sign.png b/src/main/resources/assets/betterend/textures/entity/sign/lucernia_sign.png index 0836dd40..6582238a 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/sign/lucernia_sign.png and b/src/main/resources/assets/betterend/textures/entity/sign/lucernia_sign.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/sign/pythadendron_sign.png b/src/main/resources/assets/betterend/textures/entity/sign/pythadendron_sign.png index c53643d9..3810727f 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/sign/pythadendron_sign.png and b/src/main/resources/assets/betterend/textures/entity/sign/pythadendron_sign.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/sign/tenanea_sign.png b/src/main/resources/assets/betterend/textures/entity/sign/tenanea_sign.png index 7771a007..90534337 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/sign/tenanea_sign.png and b/src/main/resources/assets/betterend/textures/entity/sign/tenanea_sign.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/sign/umbrella_tree_sign.png b/src/main/resources/assets/betterend/textures/entity/sign/umbrella_tree_sign.png index 23e39bb4..22ed069e 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/sign/umbrella_tree_sign.png and b/src/main/resources/assets/betterend/textures/entity/sign/umbrella_tree_sign.png differ diff --git a/src/main/resources/assets/betterend/textures/entity/silk_moth.png b/src/main/resources/assets/betterend/textures/entity/silk_moth.png index c66fb192..fd8d6574 100644 Binary files a/src/main/resources/assets/betterend/textures/entity/silk_moth.png and b/src/main/resources/assets/betterend/textures/entity/silk_moth.png differ diff --git a/src/main/resources/assets/betterend/textures/gui/infusion.png b/src/main/resources/assets/betterend/textures/gui/infusion.png new file mode 100644 index 00000000..30250f32 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/gui/infusion.png differ diff --git a/src/main/resources/assets/betterend/textures/gui/rei_infusion.png b/src/main/resources/assets/betterend/textures/gui/rei_infusion.png index a25798d3..597615ea 100644 Binary files a/src/main/resources/assets/betterend/textures/gui/rei_infusion.png and b/src/main/resources/assets/betterend/textures/gui/rei_infusion.png differ diff --git a/src/main/resources/assets/betterend/textures/gui/smelter_gui.png b/src/main/resources/assets/betterend/textures/gui/smelter_gui.png index 5f070aee..640a1447 100644 Binary files a/src/main/resources/assets/betterend/textures/gui/smelter_gui.png and b/src/main/resources/assets/betterend/textures/gui/smelter_gui.png differ diff --git a/src/main/resources/assets/betterend/textures/heightmaps/mountain_1.png b/src/main/resources/assets/betterend/textures/heightmaps/mountain_1.png index 020f8daa..5d49bbc5 100644 Binary files a/src/main/resources/assets/betterend/textures/heightmaps/mountain_1.png and b/src/main/resources/assets/betterend/textures/heightmaps/mountain_1.png differ diff --git a/src/main/resources/assets/betterend/textures/images/eternal_ritual/portal_frame_full.png b/src/main/resources/assets/betterend/textures/images/eternal_ritual/portal_frame_full.png index 64af920a..a9fbfce1 100644 Binary files a/src/main/resources/assets/betterend/textures/images/eternal_ritual/portal_frame_full.png and b/src/main/resources/assets/betterend/textures/images/eternal_ritual/portal_frame_full.png differ diff --git a/src/main/resources/assets/betterend/textures/images/eternal_ritual/portal_structure.png b/src/main/resources/assets/betterend/textures/images/eternal_ritual/portal_structure.png index 6d460027..b1460785 100644 Binary files a/src/main/resources/assets/betterend/textures/images/eternal_ritual/portal_structure.png and b/src/main/resources/assets/betterend/textures/images/eternal_ritual/portal_structure.png differ diff --git a/src/main/resources/assets/betterend/textures/images/infusion_ritual/infusion_ritual_full.png b/src/main/resources/assets/betterend/textures/images/infusion_ritual/infusion_ritual_full.png index 88e04018..01ddead7 100644 Binary files a/src/main/resources/assets/betterend/textures/images/infusion_ritual/infusion_ritual_full.png and b/src/main/resources/assets/betterend/textures/images/infusion_ritual/infusion_ritual_full.png differ diff --git a/src/main/resources/assets/betterend/textures/images/infusion_ritual/infusion_ritual_start.png b/src/main/resources/assets/betterend/textures/images/infusion_ritual/infusion_ritual_start.png index 2361f777..57f3cc27 100644 Binary files a/src/main/resources/assets/betterend/textures/images/infusion_ritual/infusion_ritual_start.png and b/src/main/resources/assets/betterend/textures/images/infusion_ritual/infusion_ritual_start.png differ diff --git a/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_finished.png b/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_finished.png index 1bfb82df..f754bd2b 100644 Binary files a/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_finished.png and b/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_finished.png differ diff --git a/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_ready.png b/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_ready.png index 42a5459e..efae5a7a 100644 Binary files a/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_ready.png and b/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_ready.png differ diff --git a/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_started.png b/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_started.png index b3f5898f..29a6d007 100644 Binary files a/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_started.png and b/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_started.png differ diff --git a/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_structure.png b/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_structure.png index b06d537f..8cc26ef9 100644 Binary files a/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_structure.png and b/src/main/resources/assets/betterend/textures/images/infusion_ritual/ritual_structure.png differ diff --git a/src/main/resources/assets/betterend/textures/item/aeternium_boots.png b/src/main/resources/assets/betterend/textures/item/aeternium_boots.png index d36b2dc0..402c8126 100644 Binary files a/src/main/resources/assets/betterend/textures/item/aeternium_boots.png and b/src/main/resources/assets/betterend/textures/item/aeternium_boots.png differ diff --git a/src/main/resources/assets/betterend/textures/item/aeternium_chestplate.png b/src/main/resources/assets/betterend/textures/item/aeternium_chestplate.png index b150e1a5..49f0c341 100644 Binary files a/src/main/resources/assets/betterend/textures/item/aeternium_chestplate.png and b/src/main/resources/assets/betterend/textures/item/aeternium_chestplate.png differ diff --git a/src/main/resources/assets/betterend/textures/item/aeternium_forged_plate.png b/src/main/resources/assets/betterend/textures/item/aeternium_forged_plate.png index 3ffd9a9a..9f177f33 100644 Binary files a/src/main/resources/assets/betterend/textures/item/aeternium_forged_plate.png and b/src/main/resources/assets/betterend/textures/item/aeternium_forged_plate.png differ diff --git a/src/main/resources/assets/betterend/textures/item/aeternium_helmet.png b/src/main/resources/assets/betterend/textures/item/aeternium_helmet.png index ba4664fb..3fe27e48 100644 Binary files a/src/main/resources/assets/betterend/textures/item/aeternium_helmet.png and b/src/main/resources/assets/betterend/textures/item/aeternium_helmet.png differ diff --git a/src/main/resources/assets/betterend/textures/item/aeternium_ingot.png b/src/main/resources/assets/betterend/textures/item/aeternium_ingot.png index 031a777a..6622d555 100644 Binary files a/src/main/resources/assets/betterend/textures/item/aeternium_ingot.png and b/src/main/resources/assets/betterend/textures/item/aeternium_ingot.png differ diff --git a/src/main/resources/assets/betterend/textures/item/aeternium_leggings.png b/src/main/resources/assets/betterend/textures/item/aeternium_leggings.png index 69c2a5a5..4ad455a4 100644 Binary files a/src/main/resources/assets/betterend/textures/item/aeternium_leggings.png and b/src/main/resources/assets/betterend/textures/item/aeternium_leggings.png differ diff --git a/src/main/resources/assets/betterend/textures/item/amber_gem.png b/src/main/resources/assets/betterend/textures/item/amber_gem.png index 9843c210..248b9764 100644 Binary files a/src/main/resources/assets/betterend/textures/item/amber_gem.png and b/src/main/resources/assets/betterend/textures/item/amber_gem.png differ diff --git a/src/main/resources/assets/betterend/textures/item/amber_root_raw.png b/src/main/resources/assets/betterend/textures/item/amber_root_raw.png index adae9d37..d78d4562 100644 Binary files a/src/main/resources/assets/betterend/textures/item/amber_root_raw.png and b/src/main/resources/assets/betterend/textures/item/amber_root_raw.png differ diff --git a/src/main/resources/assets/betterend/textures/item/amber_root_seed.png b/src/main/resources/assets/betterend/textures/item/amber_root_seed.png index bf1a7b90..270c111d 100644 Binary files a/src/main/resources/assets/betterend/textures/item/amber_root_seed.png and b/src/main/resources/assets/betterend/textures/item/amber_root_seed.png differ diff --git a/src/main/resources/assets/betterend/textures/item/aurant_polypore.png b/src/main/resources/assets/betterend/textures/item/aurant_polypore.png index bfdde532..84010b1d 100644 Binary files a/src/main/resources/assets/betterend/textures/item/aurant_polypore.png and b/src/main/resources/assets/betterend/textures/item/aurant_polypore.png differ diff --git a/src/main/resources/assets/betterend/textures/item/blossom_berry.png b/src/main/resources/assets/betterend/textures/item/blossom_berry.png index d0a89188..a92c1db0 100644 Binary files a/src/main/resources/assets/betterend/textures/item/blossom_berry.png and b/src/main/resources/assets/betterend/textures/item/blossom_berry.png differ diff --git a/src/main/resources/assets/betterend/textures/item/blossom_berry_jelly.png b/src/main/resources/assets/betterend/textures/item/blossom_berry_jelly.png index d09b7c25..46c128b8 100644 Binary files a/src/main/resources/assets/betterend/textures/item/blossom_berry_jelly.png and b/src/main/resources/assets/betterend/textures/item/blossom_berry_jelly.png differ diff --git a/src/main/resources/assets/betterend/textures/item/blossom_berry_seed.png b/src/main/resources/assets/betterend/textures/item/blossom_berry_seed.png index 6a34f91a..0d9cbf5e 100644 Binary files a/src/main/resources/assets/betterend/textures/item/blossom_berry_seed.png and b/src/main/resources/assets/betterend/textures/item/blossom_berry_seed.png differ diff --git a/src/main/resources/assets/betterend/textures/item/blue_vine_seed.png b/src/main/resources/assets/betterend/textures/item/blue_vine_seed.png index 965fccd1..8749466c 100644 Binary files a/src/main/resources/assets/betterend/textures/item/blue_vine_seed.png and b/src/main/resources/assets/betterend/textures/item/blue_vine_seed.png differ diff --git a/src/main/resources/assets/betterend/textures/item/bolux_mushroom.png b/src/main/resources/assets/betterend/textures/item/bolux_mushroom.png index 350ed56b..a9276264 100644 Binary files a/src/main/resources/assets/betterend/textures/item/bolux_mushroom.png and b/src/main/resources/assets/betterend/textures/item/bolux_mushroom.png differ diff --git a/src/main/resources/assets/betterend/textures/item/bolux_mushroom_cooked.png b/src/main/resources/assets/betterend/textures/item/bolux_mushroom_cooked.png index 4541a243..844e05ab 100644 Binary files a/src/main/resources/assets/betterend/textures/item/bolux_mushroom_cooked.png and b/src/main/resources/assets/betterend/textures/item/bolux_mushroom_cooked.png differ diff --git a/src/main/resources/assets/betterend/textures/item/bucket_cubozoa.png b/src/main/resources/assets/betterend/textures/item/bucket_cubozoa.png index 6b1e88c4..cd510ebb 100644 Binary files a/src/main/resources/assets/betterend/textures/item/bucket_cubozoa.png and b/src/main/resources/assets/betterend/textures/item/bucket_cubozoa.png differ diff --git a/src/main/resources/assets/betterend/textures/item/bucket_end_fish.png b/src/main/resources/assets/betterend/textures/item/bucket_end_fish.png index 9b0678c4..460c451a 100644 Binary files a/src/main/resources/assets/betterend/textures/item/bucket_end_fish.png and b/src/main/resources/assets/betterend/textures/item/bucket_end_fish.png differ diff --git a/src/main/resources/assets/betterend/textures/item/cave_pumpkin_pie.png b/src/main/resources/assets/betterend/textures/item/cave_pumpkin_pie.png index d24ce153..419b2de1 100644 Binary files a/src/main/resources/assets/betterend/textures/item/cave_pumpkin_pie.png and b/src/main/resources/assets/betterend/textures/item/cave_pumpkin_pie.png differ diff --git a/src/main/resources/assets/betterend/textures/item/cave_pumpkin_seed.png b/src/main/resources/assets/betterend/textures/item/cave_pumpkin_seed.png index f49ede5b..e6e2278e 100644 Binary files a/src/main/resources/assets/betterend/textures/item/cave_pumpkin_seed.png and b/src/main/resources/assets/betterend/textures/item/cave_pumpkin_seed.png differ diff --git a/src/main/resources/assets/betterend/textures/item/charnia_cyan.png b/src/main/resources/assets/betterend/textures/item/charnia_cyan.png index 2cccc768..36357963 100644 Binary files a/src/main/resources/assets/betterend/textures/item/charnia_cyan.png and b/src/main/resources/assets/betterend/textures/item/charnia_cyan.png differ diff --git a/src/main/resources/assets/betterend/textures/item/charnia_green.png b/src/main/resources/assets/betterend/textures/item/charnia_green.png index a63ccf28..7e9121b5 100644 Binary files a/src/main/resources/assets/betterend/textures/item/charnia_green.png and b/src/main/resources/assets/betterend/textures/item/charnia_green.png differ diff --git a/src/main/resources/assets/betterend/textures/item/charnia_light_blue.png b/src/main/resources/assets/betterend/textures/item/charnia_light_blue.png index 5e82ab7e..2dde93a9 100644 Binary files a/src/main/resources/assets/betterend/textures/item/charnia_light_blue.png and b/src/main/resources/assets/betterend/textures/item/charnia_light_blue.png differ diff --git a/src/main/resources/assets/betterend/textures/item/charnia_orange.png b/src/main/resources/assets/betterend/textures/item/charnia_orange.png index e95351d3..19da7ad1 100644 Binary files a/src/main/resources/assets/betterend/textures/item/charnia_orange.png and b/src/main/resources/assets/betterend/textures/item/charnia_orange.png differ diff --git a/src/main/resources/assets/betterend/textures/item/charnia_purple.png b/src/main/resources/assets/betterend/textures/item/charnia_purple.png index f46cacbd..40538bf3 100644 Binary files a/src/main/resources/assets/betterend/textures/item/charnia_purple.png and b/src/main/resources/assets/betterend/textures/item/charnia_purple.png differ diff --git a/src/main/resources/assets/betterend/textures/item/charnia_red.png b/src/main/resources/assets/betterend/textures/item/charnia_red.png index 69378b84..bf5cddfa 100644 Binary files a/src/main/resources/assets/betterend/textures/item/charnia_red.png and b/src/main/resources/assets/betterend/textures/item/charnia_red.png differ diff --git a/src/main/resources/assets/betterend/textures/item/chorus_mushroom_cooked.png b/src/main/resources/assets/betterend/textures/item/chorus_mushroom_cooked.png index ebed2b9b..dd74d8c9 100644 Binary files a/src/main/resources/assets/betterend/textures/item/chorus_mushroom_cooked.png and b/src/main/resources/assets/betterend/textures/item/chorus_mushroom_cooked.png differ diff --git a/src/main/resources/assets/betterend/textures/item/chorus_mushroom_raw.png b/src/main/resources/assets/betterend/textures/item/chorus_mushroom_raw.png index a40c514a..171777e0 100644 Binary files a/src/main/resources/assets/betterend/textures/item/chorus_mushroom_raw.png and b/src/main/resources/assets/betterend/textures/item/chorus_mushroom_raw.png differ diff --git a/src/main/resources/assets/betterend/textures/item/chorus_mushroom_seed.png b/src/main/resources/assets/betterend/textures/item/chorus_mushroom_seed.png index 996f396e..31c20cc7 100644 Binary files a/src/main/resources/assets/betterend/textures/item/chorus_mushroom_seed.png and b/src/main/resources/assets/betterend/textures/item/chorus_mushroom_seed.png differ diff --git a/src/main/resources/assets/betterend/textures/item/crystalite_boots.png b/src/main/resources/assets/betterend/textures/item/crystalite_boots.png index f8f05112..f5c8a6df 100644 Binary files a/src/main/resources/assets/betterend/textures/item/crystalite_boots.png and b/src/main/resources/assets/betterend/textures/item/crystalite_boots.png differ diff --git a/src/main/resources/assets/betterend/textures/item/crystalite_chestplate.png b/src/main/resources/assets/betterend/textures/item/crystalite_chestplate.png index a23e12b1..98a04754 100644 Binary files a/src/main/resources/assets/betterend/textures/item/crystalite_chestplate.png and b/src/main/resources/assets/betterend/textures/item/crystalite_chestplate.png differ diff --git a/src/main/resources/assets/betterend/textures/item/crystalite_helmet.png b/src/main/resources/assets/betterend/textures/item/crystalite_helmet.png index 0bf64398..4ec7bad8 100644 Binary files a/src/main/resources/assets/betterend/textures/item/crystalite_helmet.png and b/src/main/resources/assets/betterend/textures/item/crystalite_helmet.png differ diff --git a/src/main/resources/assets/betterend/textures/item/crystalite_leggings.png b/src/main/resources/assets/betterend/textures/item/crystalite_leggings.png index b9fa7e3c..a54ad9c5 100644 Binary files a/src/main/resources/assets/betterend/textures/item/crystalite_leggings.png and b/src/main/resources/assets/betterend/textures/item/crystalite_leggings.png differ diff --git a/src/main/resources/assets/betterend/textures/item/crystalline_sulphur.png b/src/main/resources/assets/betterend/textures/item/crystalline_sulphur.png index cd352249..20e5c4b4 100644 Binary files a/src/main/resources/assets/betterend/textures/item/crystalline_sulphur.png and b/src/main/resources/assets/betterend/textures/item/crystalline_sulphur.png differ diff --git a/src/main/resources/assets/betterend/textures/item/elytra_armored.png b/src/main/resources/assets/betterend/textures/item/elytra_armored.png index f8dfb88b..93a62632 100644 Binary files a/src/main/resources/assets/betterend/textures/item/elytra_armored.png and b/src/main/resources/assets/betterend/textures/item/elytra_armored.png differ diff --git a/src/main/resources/assets/betterend/textures/item/elytra_armored_broken.png b/src/main/resources/assets/betterend/textures/item/elytra_armored_broken.png index fe2de9a2..009f6aa7 100644 Binary files a/src/main/resources/assets/betterend/textures/item/elytra_armored_broken.png and b/src/main/resources/assets/betterend/textures/item/elytra_armored_broken.png differ diff --git a/src/main/resources/assets/betterend/textures/item/elytra_crystalite.png b/src/main/resources/assets/betterend/textures/item/elytra_crystalite.png index 01f80018..2cc34970 100644 Binary files a/src/main/resources/assets/betterend/textures/item/elytra_crystalite.png and b/src/main/resources/assets/betterend/textures/item/elytra_crystalite.png differ diff --git a/src/main/resources/assets/betterend/textures/item/elytra_crystalite_broken.png b/src/main/resources/assets/betterend/textures/item/elytra_crystalite_broken.png index d568e329..b41df949 100644 Binary files a/src/main/resources/assets/betterend/textures/item/elytra_crystalite_broken.png and b/src/main/resources/assets/betterend/textures/item/elytra_crystalite_broken.png differ diff --git a/src/main/resources/assets/betterend/textures/item/end_fish_cooked.png b/src/main/resources/assets/betterend/textures/item/end_fish_cooked.png index 32cebbd8..2e8012ff 100644 Binary files a/src/main/resources/assets/betterend/textures/item/end_fish_cooked.png and b/src/main/resources/assets/betterend/textures/item/end_fish_cooked.png differ diff --git a/src/main/resources/assets/betterend/textures/item/end_lily_seed.png b/src/main/resources/assets/betterend/textures/item/end_lily_seed.png index eb6ec615..347e1919 100644 Binary files a/src/main/resources/assets/betterend/textures/item/end_lily_seed.png and b/src/main/resources/assets/betterend/textures/item/end_lily_seed.png differ diff --git a/src/main/resources/assets/betterend/textures/item/end_lotus_seed.png b/src/main/resources/assets/betterend/textures/item/end_lotus_seed.png index 351633ab..64dc7dc8 100644 Binary files a/src/main/resources/assets/betterend/textures/item/end_lotus_seed.png and b/src/main/resources/assets/betterend/textures/item/end_lotus_seed.png differ diff --git a/src/main/resources/assets/betterend/textures/item/end_lotus_sign.png b/src/main/resources/assets/betterend/textures/item/end_lotus_sign.png index 6ff9f25e..a5d42722 100644 Binary files a/src/main/resources/assets/betterend/textures/item/end_lotus_sign.png and b/src/main/resources/assets/betterend/textures/item/end_lotus_sign.png differ diff --git a/src/main/resources/assets/betterend/textures/item/end_stone_stalactite.png b/src/main/resources/assets/betterend/textures/item/end_stone_stalactite.png index 9372b7cf..8efa74e7 100644 Binary files a/src/main/resources/assets/betterend/textures/item/end_stone_stalactite.png and b/src/main/resources/assets/betterend/textures/item/end_stone_stalactite.png differ diff --git a/src/main/resources/assets/betterend/textures/item/end_stone_stalactite_cavemoss.png b/src/main/resources/assets/betterend/textures/item/end_stone_stalactite_cavemoss.png index 478e770d..bfb6042f 100644 Binary files a/src/main/resources/assets/betterend/textures/item/end_stone_stalactite_cavemoss.png and b/src/main/resources/assets/betterend/textures/item/end_stone_stalactite_cavemoss.png differ diff --git a/src/main/resources/assets/betterend/textures/item/ender_shard.png b/src/main/resources/assets/betterend/textures/item/ender_shard.png index 29b0e054..0f9400c2 100644 Binary files a/src/main/resources/assets/betterend/textures/item/ender_shard.png and b/src/main/resources/assets/betterend/textures/item/ender_shard.png differ diff --git a/src/main/resources/assets/betterend/textures/item/filalux_wings.png b/src/main/resources/assets/betterend/textures/item/filalux_wings.png index e76070b4..6b0ee2a4 100644 Binary files a/src/main/resources/assets/betterend/textures/item/filalux_wings.png and b/src/main/resources/assets/betterend/textures/item/filalux_wings.png differ diff --git a/src/main/resources/assets/betterend/textures/item/flammalix.png b/src/main/resources/assets/betterend/textures/item/flammalix.png new file mode 100644 index 00000000..80de2d85 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/item/flammalix.png differ diff --git a/src/main/resources/assets/betterend/textures/item/gelatine.png b/src/main/resources/assets/betterend/textures/item/gelatine.png index 75cd82f4..82dc9b9b 100644 Binary files a/src/main/resources/assets/betterend/textures/item/gelatine.png and b/src/main/resources/assets/betterend/textures/item/gelatine.png differ diff --git a/src/main/resources/assets/betterend/textures/item/glowing_bulb.png b/src/main/resources/assets/betterend/textures/item/glowing_bulb.png index 743aa420..3e2f2d26 100644 Binary files a/src/main/resources/assets/betterend/textures/item/glowing_bulb.png and b/src/main/resources/assets/betterend/textures/item/glowing_bulb.png differ diff --git a/src/main/resources/assets/betterend/textures/item/guidebook.png b/src/main/resources/assets/betterend/textures/item/guidebook.png index a1693fd2..be3017a1 100644 Binary files a/src/main/resources/assets/betterend/textures/item/guidebook.png and b/src/main/resources/assets/betterend/textures/item/guidebook.png differ diff --git a/src/main/resources/assets/betterend/textures/item/helix_tree_door.png b/src/main/resources/assets/betterend/textures/item/helix_tree_door.png index c73b180c..52a00f33 100644 Binary files a/src/main/resources/assets/betterend/textures/item/helix_tree_door.png and b/src/main/resources/assets/betterend/textures/item/helix_tree_door.png differ diff --git a/src/main/resources/assets/betterend/textures/item/helix_tree_sign.png b/src/main/resources/assets/betterend/textures/item/helix_tree_sign.png index db835722..740cacb6 100644 Binary files a/src/main/resources/assets/betterend/textures/item/helix_tree_sign.png and b/src/main/resources/assets/betterend/textures/item/helix_tree_sign.png differ diff --git a/src/main/resources/assets/betterend/textures/item/hydralux_petal.png b/src/main/resources/assets/betterend/textures/item/hydralux_petal.png index 2d27cea2..a9530d29 100644 Binary files a/src/main/resources/assets/betterend/textures/item/hydralux_petal.png and b/src/main/resources/assets/betterend/textures/item/hydralux_petal.png differ diff --git a/src/main/resources/assets/betterend/textures/item/hydralux_spore.png b/src/main/resources/assets/betterend/textures/item/hydralux_spore.png index 4979bb54..5041dcf0 100644 Binary files a/src/main/resources/assets/betterend/textures/item/hydralux_spore.png and b/src/main/resources/assets/betterend/textures/item/hydralux_spore.png differ diff --git a/src/main/resources/assets/betterend/textures/item/iron_hammer.png b/src/main/resources/assets/betterend/textures/item/iron_hammer.png index 118a9d1a..3dee3871 100644 Binary files a/src/main/resources/assets/betterend/textures/item/iron_hammer.png and b/src/main/resources/assets/betterend/textures/item/iron_hammer.png differ diff --git a/src/main/resources/assets/betterend/textures/item/jungle_fern.png b/src/main/resources/assets/betterend/textures/item/jungle_fern.png index 862e19e1..bbe48955 100644 Binary files a/src/main/resources/assets/betterend/textures/item/jungle_fern.png and b/src/main/resources/assets/betterend/textures/item/jungle_fern.png differ diff --git a/src/main/resources/assets/betterend/textures/item/lanceleaf_seed.png b/src/main/resources/assets/betterend/textures/item/lanceleaf_seed.png index 330ed0fc..2eb3390f 100644 Binary files a/src/main/resources/assets/betterend/textures/item/lanceleaf_seed.png and b/src/main/resources/assets/betterend/textures/item/lanceleaf_seed.png differ diff --git a/src/main/resources/assets/betterend/textures/item/leather_stripe.png b/src/main/resources/assets/betterend/textures/item/leather_stripe.png index ac46074d..0cf28fdc 100644 Binary files a/src/main/resources/assets/betterend/textures/item/leather_stripe.png and b/src/main/resources/assets/betterend/textures/item/leather_stripe.png differ diff --git a/src/main/resources/assets/betterend/textures/item/lucernia_door.png b/src/main/resources/assets/betterend/textures/item/lucernia_door.png index 5b172d76..24611236 100644 Binary files a/src/main/resources/assets/betterend/textures/item/lucernia_door.png and b/src/main/resources/assets/betterend/textures/item/lucernia_door.png differ diff --git a/src/main/resources/assets/betterend/textures/item/lucernia_sign.png b/src/main/resources/assets/betterend/textures/item/lucernia_sign.png index 5cb550d8..28c1ee26 100644 Binary files a/src/main/resources/assets/betterend/textures/item/lucernia_sign.png and b/src/main/resources/assets/betterend/textures/item/lucernia_sign.png differ diff --git a/src/main/resources/assets/betterend/textures/item/lumecorn_rod.png b/src/main/resources/assets/betterend/textures/item/lumecorn_rod.png index 5b1d1226..54b8650b 100644 Binary files a/src/main/resources/assets/betterend/textures/item/lumecorn_rod.png and b/src/main/resources/assets/betterend/textures/item/lumecorn_rod.png differ diff --git a/src/main/resources/assets/betterend/textures/item/murkweed.png b/src/main/resources/assets/betterend/textures/item/murkweed.png index a5843440..39279a5b 100644 Binary files a/src/main/resources/assets/betterend/textures/item/murkweed.png and b/src/main/resources/assets/betterend/textures/item/murkweed.png differ diff --git a/src/main/resources/assets/betterend/textures/item/music_disc_endseeker.png b/src/main/resources/assets/betterend/textures/item/music_disc_endseeker.png index 8c4ab480..2875300f 100644 Binary files a/src/main/resources/assets/betterend/textures/item/music_disc_endseeker.png and b/src/main/resources/assets/betterend/textures/item/music_disc_endseeker.png differ diff --git a/src/main/resources/assets/betterend/textures/item/music_disc_eo_dracona.png b/src/main/resources/assets/betterend/textures/item/music_disc_eo_dracona.png index a4a91c3f..fd72ed07 100644 Binary files a/src/main/resources/assets/betterend/textures/item/music_disc_eo_dracona.png and b/src/main/resources/assets/betterend/textures/item/music_disc_eo_dracona.png differ diff --git a/src/main/resources/assets/betterend/textures/item/music_disc_grasping_at_stars.png b/src/main/resources/assets/betterend/textures/item/music_disc_grasping_at_stars.png index 7d607c5b..083c42d5 100644 Binary files a/src/main/resources/assets/betterend/textures/item/music_disc_grasping_at_stars.png and b/src/main/resources/assets/betterend/textures/item/music_disc_grasping_at_stars.png differ diff --git a/src/main/resources/assets/betterend/textures/item/music_disc_strange_and_alien.png b/src/main/resources/assets/betterend/textures/item/music_disc_strange_and_alien.png index a6c84ad4..cc6bdd7f 100644 Binary files a/src/main/resources/assets/betterend/textures/item/music_disc_strange_and_alien.png and b/src/main/resources/assets/betterend/textures/item/music_disc_strange_and_alien.png differ diff --git a/src/main/resources/assets/betterend/textures/item/netherite_hammer.png b/src/main/resources/assets/betterend/textures/item/netherite_hammer.png index b3dd3071..4c54ece9 100644 Binary files a/src/main/resources/assets/betterend/textures/item/netherite_hammer.png and b/src/main/resources/assets/betterend/textures/item/netherite_hammer.png differ diff --git a/src/main/resources/assets/betterend/textures/item/pond_anemone.png b/src/main/resources/assets/betterend/textures/item/pond_anemone.png index 32414526..6b9dd9f8 100644 Binary files a/src/main/resources/assets/betterend/textures/item/pond_anemone.png and b/src/main/resources/assets/betterend/textures/item/pond_anemone.png differ diff --git a/src/main/resources/assets/betterend/textures/item/purple_polypore.png b/src/main/resources/assets/betterend/textures/item/purple_polypore.png index 9a47237c..44ac7d39 100644 Binary files a/src/main/resources/assets/betterend/textures/item/purple_polypore.png and b/src/main/resources/assets/betterend/textures/item/purple_polypore.png differ diff --git a/src/main/resources/assets/betterend/textures/item/raw_amber.png b/src/main/resources/assets/betterend/textures/item/raw_amber.png index 76295d42..18872298 100644 Binary files a/src/main/resources/assets/betterend/textures/item/raw_amber.png and b/src/main/resources/assets/betterend/textures/item/raw_amber.png differ diff --git a/src/main/resources/assets/betterend/textures/item/shadow_berry.png b/src/main/resources/assets/betterend/textures/item/shadow_berry.png index c9ce4614..f23af1bf 100644 Binary files a/src/main/resources/assets/betterend/textures/item/shadow_berry.png and b/src/main/resources/assets/betterend/textures/item/shadow_berry.png differ diff --git a/src/main/resources/assets/betterend/textures/item/shadow_berry_cooked.png b/src/main/resources/assets/betterend/textures/item/shadow_berry_cooked.png index 9b0c8389..7771c320 100644 Binary files a/src/main/resources/assets/betterend/textures/item/shadow_berry_cooked.png and b/src/main/resources/assets/betterend/textures/item/shadow_berry_cooked.png differ diff --git a/src/main/resources/assets/betterend/textures/item/shadow_berry_jelly.png b/src/main/resources/assets/betterend/textures/item/shadow_berry_jelly.png index 6c12b368..43ad04d5 100644 Binary files a/src/main/resources/assets/betterend/textures/item/shadow_berry_jelly.png and b/src/main/resources/assets/betterend/textures/item/shadow_berry_jelly.png differ diff --git a/src/main/resources/assets/betterend/textures/item/shadow_berry_seeds.png b/src/main/resources/assets/betterend/textures/item/shadow_berry_seeds.png index 20afce5b..04bb4dd0 100644 Binary files a/src/main/resources/assets/betterend/textures/item/shadow_berry_seeds.png and b/src/main/resources/assets/betterend/textures/item/shadow_berry_seeds.png differ diff --git a/src/main/resources/assets/betterend/textures/item/silk_fiber.png b/src/main/resources/assets/betterend/textures/item/silk_fiber.png index e8e0dfee..c4d6fccd 100644 Binary files a/src/main/resources/assets/betterend/textures/item/silk_fiber.png and b/src/main/resources/assets/betterend/textures/item/silk_fiber.png differ diff --git a/src/main/resources/assets/betterend/textures/item/silk_moth_matrix.png b/src/main/resources/assets/betterend/textures/item/silk_moth_matrix.png index c87a1436..69c6f367 100644 Binary files a/src/main/resources/assets/betterend/textures/item/silk_moth_matrix.png and b/src/main/resources/assets/betterend/textures/item/silk_moth_matrix.png differ diff --git a/src/main/resources/assets/betterend/textures/item/small_amaranita_mushroom.png b/src/main/resources/assets/betterend/textures/item/small_amaranita_mushroom.png index d4e8c69d..008b1a70 100644 Binary files a/src/main/resources/assets/betterend/textures/item/small_amaranita_mushroom.png and b/src/main/resources/assets/betterend/textures/item/small_amaranita_mushroom.png differ diff --git a/src/main/resources/assets/betterend/textures/item/small_jellyshroom.png b/src/main/resources/assets/betterend/textures/item/small_jellyshroom.png index 4a149bf9..e294a664 100644 Binary files a/src/main/resources/assets/betterend/textures/item/small_jellyshroom.png and b/src/main/resources/assets/betterend/textures/item/small_jellyshroom.png differ diff --git a/src/main/resources/assets/betterend/textures/item/sweet_berry_jelly.png b/src/main/resources/assets/betterend/textures/item/sweet_berry_jelly.png index 4e2ff978..2d5a0050 100644 Binary files a/src/main/resources/assets/betterend/textures/item/sweet_berry_jelly.png and b/src/main/resources/assets/betterend/textures/item/sweet_berry_jelly.png differ diff --git a/src/main/resources/assets/betterend/textures/item/tenanea_door.png b/src/main/resources/assets/betterend/textures/item/tenanea_door.png index dded079f..1f27e1ac 100644 Binary files a/src/main/resources/assets/betterend/textures/item/tenanea_door.png and b/src/main/resources/assets/betterend/textures/item/tenanea_door.png differ diff --git a/src/main/resources/assets/betterend/textures/item/tenanea_flowers.png b/src/main/resources/assets/betterend/textures/item/tenanea_flowers.png index 8a968bb6..5a74f541 100644 Binary files a/src/main/resources/assets/betterend/textures/item/tenanea_flowers.png and b/src/main/resources/assets/betterend/textures/item/tenanea_flowers.png differ diff --git a/src/main/resources/assets/betterend/textures/item/terminite_axe_head.png b/src/main/resources/assets/betterend/textures/item/terminite_axe_head.png index 5f65902a..0499e1de 100644 Binary files a/src/main/resources/assets/betterend/textures/item/terminite_axe_head.png and b/src/main/resources/assets/betterend/textures/item/terminite_axe_head.png differ diff --git a/src/main/resources/assets/betterend/textures/item/terminite_boots.png b/src/main/resources/assets/betterend/textures/item/terminite_boots.png index bfc2254a..560dab34 100644 Binary files a/src/main/resources/assets/betterend/textures/item/terminite_boots.png and b/src/main/resources/assets/betterend/textures/item/terminite_boots.png differ diff --git a/src/main/resources/assets/betterend/textures/item/terminite_chestplate.png b/src/main/resources/assets/betterend/textures/item/terminite_chestplate.png index 90f9efd8..d10d2862 100644 Binary files a/src/main/resources/assets/betterend/textures/item/terminite_chestplate.png and b/src/main/resources/assets/betterend/textures/item/terminite_chestplate.png differ diff --git a/src/main/resources/assets/betterend/textures/item/terminite_door.png b/src/main/resources/assets/betterend/textures/item/terminite_door.png index c5a64524..8fb90b07 100644 Binary files a/src/main/resources/assets/betterend/textures/item/terminite_door.png and b/src/main/resources/assets/betterend/textures/item/terminite_door.png differ diff --git a/src/main/resources/assets/betterend/textures/item/terminite_forged_plate.png b/src/main/resources/assets/betterend/textures/item/terminite_forged_plate.png index 5b203bbe..1e538400 100644 Binary files a/src/main/resources/assets/betterend/textures/item/terminite_forged_plate.png and b/src/main/resources/assets/betterend/textures/item/terminite_forged_plate.png differ diff --git a/src/main/resources/assets/betterend/textures/item/terminite_helmet.png b/src/main/resources/assets/betterend/textures/item/terminite_helmet.png index 3bc9fa08..8aaa6390 100644 Binary files a/src/main/resources/assets/betterend/textures/item/terminite_helmet.png and b/src/main/resources/assets/betterend/textures/item/terminite_helmet.png differ diff --git a/src/main/resources/assets/betterend/textures/item/terminite_hoe.png b/src/main/resources/assets/betterend/textures/item/terminite_hoe.png index 778f244e..c457aa21 100644 Binary files a/src/main/resources/assets/betterend/textures/item/terminite_hoe.png and b/src/main/resources/assets/betterend/textures/item/terminite_hoe.png differ diff --git a/src/main/resources/assets/betterend/textures/item/terminite_ingot.png b/src/main/resources/assets/betterend/textures/item/terminite_ingot.png index 4c0bcfdc..78d8306b 100644 Binary files a/src/main/resources/assets/betterend/textures/item/terminite_ingot.png and b/src/main/resources/assets/betterend/textures/item/terminite_ingot.png differ diff --git a/src/main/resources/assets/betterend/textures/item/terminite_leggings.png b/src/main/resources/assets/betterend/textures/item/terminite_leggings.png index 18503e47..4bf290a1 100644 Binary files a/src/main/resources/assets/betterend/textures/item/terminite_leggings.png and b/src/main/resources/assets/betterend/textures/item/terminite_leggings.png differ diff --git a/src/main/resources/assets/betterend/textures/item/terminite_pickaxe.png b/src/main/resources/assets/betterend/textures/item/terminite_pickaxe.png index 42a0bbed..72977c3d 100644 Binary files a/src/main/resources/assets/betterend/textures/item/terminite_pickaxe.png and b/src/main/resources/assets/betterend/textures/item/terminite_pickaxe.png differ diff --git a/src/main/resources/assets/betterend/textures/item/terminite_sword.png b/src/main/resources/assets/betterend/textures/item/terminite_sword.png index ac4a40df..c8fb1703 100644 Binary files a/src/main/resources/assets/betterend/textures/item/terminite_sword.png and b/src/main/resources/assets/betterend/textures/item/terminite_sword.png differ diff --git a/src/main/resources/assets/betterend/textures/item/terminite_sword_handle.png b/src/main/resources/assets/betterend/textures/item/terminite_sword_handle.png index c4e35d66..cf968a25 100644 Binary files a/src/main/resources/assets/betterend/textures/item/terminite_sword_handle.png and b/src/main/resources/assets/betterend/textures/item/terminite_sword_handle.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thallasium_axe.png b/src/main/resources/assets/betterend/textures/item/thallasium_axe.png index 9ede4dce..b40443f0 100644 Binary files a/src/main/resources/assets/betterend/textures/item/thallasium_axe.png and b/src/main/resources/assets/betterend/textures/item/thallasium_axe.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thallasium_chandelier.png b/src/main/resources/assets/betterend/textures/item/thallasium_chandelier.png index 9f89bee0..6b515979 100644 Binary files a/src/main/resources/assets/betterend/textures/item/thallasium_chandelier.png and b/src/main/resources/assets/betterend/textures/item/thallasium_chandelier.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thallasium_chestplate.png b/src/main/resources/assets/betterend/textures/item/thallasium_chestplate.png index 562bf4bd..54718c4a 100644 Binary files a/src/main/resources/assets/betterend/textures/item/thallasium_chestplate.png and b/src/main/resources/assets/betterend/textures/item/thallasium_chestplate.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thallasium_door.png b/src/main/resources/assets/betterend/textures/item/thallasium_door.png index a0f3d6ae..d8af2a49 100644 Binary files a/src/main/resources/assets/betterend/textures/item/thallasium_door.png and b/src/main/resources/assets/betterend/textures/item/thallasium_door.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thallasium_forged_plate.png b/src/main/resources/assets/betterend/textures/item/thallasium_forged_plate.png index 2be7008f..077a1067 100644 Binary files a/src/main/resources/assets/betterend/textures/item/thallasium_forged_plate.png and b/src/main/resources/assets/betterend/textures/item/thallasium_forged_plate.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thallasium_hoe.png b/src/main/resources/assets/betterend/textures/item/thallasium_hoe.png index d32687f0..11eeffb9 100644 Binary files a/src/main/resources/assets/betterend/textures/item/thallasium_hoe.png and b/src/main/resources/assets/betterend/textures/item/thallasium_hoe.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thallasium_ingot.png b/src/main/resources/assets/betterend/textures/item/thallasium_ingot.png index 95c0dcea..cf2599d3 100644 Binary files a/src/main/resources/assets/betterend/textures/item/thallasium_ingot.png and b/src/main/resources/assets/betterend/textures/item/thallasium_ingot.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thallasium_pickaxe.png b/src/main/resources/assets/betterend/textures/item/thallasium_pickaxe.png index c02927e7..d8eeca65 100644 Binary files a/src/main/resources/assets/betterend/textures/item/thallasium_pickaxe.png and b/src/main/resources/assets/betterend/textures/item/thallasium_pickaxe.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thallasium_pickaxe_head.png b/src/main/resources/assets/betterend/textures/item/thallasium_pickaxe_head.png index dcee9d06..64c1a7c6 100644 Binary files a/src/main/resources/assets/betterend/textures/item/thallasium_pickaxe_head.png and b/src/main/resources/assets/betterend/textures/item/thallasium_pickaxe_head.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thallasium_raw.png b/src/main/resources/assets/betterend/textures/item/thallasium_raw.png new file mode 100644 index 00000000..a03e9fad Binary files /dev/null and b/src/main/resources/assets/betterend/textures/item/thallasium_raw.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thallasium_shovel.png b/src/main/resources/assets/betterend/textures/item/thallasium_shovel.png index cc09eb41..16deffff 100644 Binary files a/src/main/resources/assets/betterend/textures/item/thallasium_shovel.png and b/src/main/resources/assets/betterend/textures/item/thallasium_shovel.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thallasium_sword.png b/src/main/resources/assets/betterend/textures/item/thallasium_sword.png index 9a13f796..4e216176 100644 Binary files a/src/main/resources/assets/betterend/textures/item/thallasium_sword.png and b/src/main/resources/assets/betterend/textures/item/thallasium_sword.png differ diff --git a/src/main/resources/assets/betterend/textures/item/thermal fungus.png b/src/main/resources/assets/betterend/textures/item/thermal fungus.png index 201d44e8..bf1056d1 100644 Binary files a/src/main/resources/assets/betterend/textures/item/thermal fungus.png and b/src/main/resources/assets/betterend/textures/item/thermal fungus.png differ diff --git a/src/main/resources/assets/betterend/textures/item/tube_worm.png b/src/main/resources/assets/betterend/textures/item/tube_worm.png index e0ba37bc..6159c290 100644 Binary files a/src/main/resources/assets/betterend/textures/item/tube_worm.png and b/src/main/resources/assets/betterend/textures/item/tube_worm.png differ diff --git a/src/main/resources/assets/betterend/textures/item/twisted_umbrella_moss_large.png b/src/main/resources/assets/betterend/textures/item/twisted_umbrella_moss_large.png index 7bcb1773..c250f97f 100644 Binary files a/src/main/resources/assets/betterend/textures/item/twisted_umbrella_moss_large.png and b/src/main/resources/assets/betterend/textures/item/twisted_umbrella_moss_large.png differ diff --git a/src/main/resources/assets/betterend/textures/item/twisted_umbrella_moss_small.png b/src/main/resources/assets/betterend/textures/item/twisted_umbrella_moss_small.png index 67383d2d..36c8cb23 100644 Binary files a/src/main/resources/assets/betterend/textures/item/twisted_umbrella_moss_small.png and b/src/main/resources/assets/betterend/textures/item/twisted_umbrella_moss_small.png differ diff --git a/src/main/resources/assets/betterend/textures/item/umbrella_cluster_juice.png b/src/main/resources/assets/betterend/textures/item/umbrella_cluster_juice.png index 0a0287e8..ca84f426 100644 Binary files a/src/main/resources/assets/betterend/textures/item/umbrella_cluster_juice.png and b/src/main/resources/assets/betterend/textures/item/umbrella_cluster_juice.png differ diff --git a/src/main/resources/assets/betterend/textures/item/umbrella_tree_door.png b/src/main/resources/assets/betterend/textures/item/umbrella_tree_door.png index 3d877603..f1a9991c 100644 Binary files a/src/main/resources/assets/betterend/textures/item/umbrella_tree_door.png and b/src/main/resources/assets/betterend/textures/item/umbrella_tree_door.png differ diff --git a/src/main/resources/assets/betterend/textures/minimap/entities/cubozoa.png b/src/main/resources/assets/betterend/textures/minimap/entities/cubozoa.png index ac048eec..3a44e5d3 100644 Binary files a/src/main/resources/assets/betterend/textures/minimap/entities/cubozoa.png and b/src/main/resources/assets/betterend/textures/minimap/entities/cubozoa.png differ diff --git a/src/main/resources/assets/betterend/textures/minimap/entities/dragonfly.png b/src/main/resources/assets/betterend/textures/minimap/entities/dragonfly.png index f3a11e2c..38bc39ea 100644 Binary files a/src/main/resources/assets/betterend/textures/minimap/entities/dragonfly.png and b/src/main/resources/assets/betterend/textures/minimap/entities/dragonfly.png differ diff --git a/src/main/resources/assets/betterend/textures/minimap/entities/silk_moth.png b/src/main/resources/assets/betterend/textures/minimap/entities/silk_moth.png index fb1a6fb9..ad0e9901 100644 Binary files a/src/main/resources/assets/betterend/textures/minimap/entities/silk_moth.png and b/src/main/resources/assets/betterend/textures/minimap/entities/silk_moth.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/black_spore_0.png b/src/main/resources/assets/betterend/textures/particle/black_spore_0.png index 082b3b48..02eaee9e 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/black_spore_0.png and b/src/main/resources/assets/betterend/textures/particle/black_spore_0.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/black_spore_1.png b/src/main/resources/assets/betterend/textures/particle/black_spore_1.png index aba5d1a7..d3c98306 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/black_spore_1.png and b/src/main/resources/assets/betterend/textures/particle/black_spore_1.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/black_spore_2.png b/src/main/resources/assets/betterend/textures/particle/black_spore_2.png index 28b28a3a..a0402bf7 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/black_spore_2.png and b/src/main/resources/assets/betterend/textures/particle/black_spore_2.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/black_spore_3.png b/src/main/resources/assets/betterend/textures/particle/black_spore_3.png index d8aae095..5251be4e 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/black_spore_3.png and b/src/main/resources/assets/betterend/textures/particle/black_spore_3.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/black_spore_4.png b/src/main/resources/assets/betterend/textures/particle/black_spore_4.png index 2f42081e..bc5533ce 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/black_spore_4.png and b/src/main/resources/assets/betterend/textures/particle/black_spore_4.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/black_spore_5.png b/src/main/resources/assets/betterend/textures/particle/black_spore_5.png index 322baa2f..00d7ea61 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/black_spore_5.png and b/src/main/resources/assets/betterend/textures/particle/black_spore_5.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/jungle_spore_0.png b/src/main/resources/assets/betterend/textures/particle/jungle_spore_0.png index 5360abcc..d911a8e3 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/jungle_spore_0.png and b/src/main/resources/assets/betterend/textures/particle/jungle_spore_0.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_1.png b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_1.png index 1bba4714..eefe522e 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_1.png and b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_1.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_2.png b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_2.png index 24c8cac1..7b380f5e 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_2.png and b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_2.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_3.png b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_3.png index bbcc0ea7..e28ab943 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_3.png and b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_3.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_4.png b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_4.png index dcd27226..30fabf74 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_4.png and b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_4.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_5.png b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_5.png index 4e2c8f6a..b50f6dee 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_5.png and b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_5.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_6.png b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_6.png index 4da3d9f4..4086c0dd 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_6.png and b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_6.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_7.png b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_7.png index 5dbe73a5..bbf170de 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_7.png and b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_7.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_8.png b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_8.png index a0906550..e7530ac3 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_8.png and b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_8.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_9.png b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_9.png index 86e14dd1..3ca20b49 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_9.png and b/src/main/resources/assets/betterend/textures/particle/smaragdant_particle_9.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/snowflake_0.png b/src/main/resources/assets/betterend/textures/particle/snowflake_0.png index fcdabe94..3727e7ae 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/snowflake_0.png and b/src/main/resources/assets/betterend/textures/particle/snowflake_0.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/snowflake_1.png b/src/main/resources/assets/betterend/textures/particle/snowflake_1.png index da249eb9..489df309 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/snowflake_1.png and b/src/main/resources/assets/betterend/textures/particle/snowflake_1.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/snowflake_2.png b/src/main/resources/assets/betterend/textures/particle/snowflake_2.png index f0d26b8e..043cc55d 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/snowflake_2.png and b/src/main/resources/assets/betterend/textures/particle/snowflake_2.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/snowflake_3.png b/src/main/resources/assets/betterend/textures/particle/snowflake_3.png index 53487c10..d8e231f5 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/snowflake_3.png and b/src/main/resources/assets/betterend/textures/particle/snowflake_3.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/snowflake_4.png b/src/main/resources/assets/betterend/textures/particle/snowflake_4.png index bc5b3637..e55cf76b 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/snowflake_4.png and b/src/main/resources/assets/betterend/textures/particle/snowflake_4.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/snowflake_5.png b/src/main/resources/assets/betterend/textures/particle/snowflake_5.png index d2e86d47..454a1117 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/snowflake_5.png and b/src/main/resources/assets/betterend/textures/particle/snowflake_5.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/snowflake_6.png b/src/main/resources/assets/betterend/textures/particle/snowflake_6.png index da249eb9..489df309 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/snowflake_6.png and b/src/main/resources/assets/betterend/textures/particle/snowflake_6.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/tenanea_petal_0.png b/src/main/resources/assets/betterend/textures/particle/tenanea_petal_0.png index 253203cb..b2c1fdce 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/tenanea_petal_0.png and b/src/main/resources/assets/betterend/textures/particle/tenanea_petal_0.png differ diff --git a/src/main/resources/assets/betterend/textures/particle/tenanea_petal_1.png b/src/main/resources/assets/betterend/textures/particle/tenanea_petal_1.png index 31fa92f3..b56fca7c 100644 Binary files a/src/main/resources/assets/betterend/textures/particle/tenanea_petal_1.png and b/src/main/resources/assets/betterend/textures/particle/tenanea_petal_1.png differ diff --git a/src/main/resources/assets/betterend/textures/sky/fog.png b/src/main/resources/assets/betterend/textures/sky/fog.png index 4c6cfd0c..54583ffd 100644 Binary files a/src/main/resources/assets/betterend/textures/sky/fog.png and b/src/main/resources/assets/betterend/textures/sky/fog.png differ diff --git a/src/main/resources/assets/betterend/textures/sky/nebula_1.png b/src/main/resources/assets/betterend/textures/sky/nebula_1.png index 19f8cb1c..3cbd9c12 100644 Binary files a/src/main/resources/assets/betterend/textures/sky/nebula_1.png and b/src/main/resources/assets/betterend/textures/sky/nebula_1.png differ diff --git a/src/main/resources/assets/betterend/textures/sky/nebula_2.png b/src/main/resources/assets/betterend/textures/sky/nebula_2.png index 07a08ef8..bb21f563 100644 Binary files a/src/main/resources/assets/betterend/textures/sky/nebula_2.png and b/src/main/resources/assets/betterend/textures/sky/nebula_2.png differ diff --git a/src/main/resources/assets/betterend/textures/sky/nebula_3.png b/src/main/resources/assets/betterend/textures/sky/nebula_3.png index 8f79123b..8d0779c8 100644 Binary files a/src/main/resources/assets/betterend/textures/sky/nebula_3.png and b/src/main/resources/assets/betterend/textures/sky/nebula_3.png differ diff --git a/src/main/resources/assets/betterend/textures/sky/stars.png b/src/main/resources/assets/betterend/textures/sky/stars.png index 642cc0e3..dfe50cb8 100644 Binary files a/src/main/resources/assets/betterend/textures/sky/stars.png and b/src/main/resources/assets/betterend/textures/sky/stars.png differ diff --git a/src/main/resources/assets/bewitchment/textures/block/purpur_witch_altar.png b/src/main/resources/assets/bewitchment/textures/block/purpur_witch_altar.png index c7f1cacc..eb431bca 100644 Binary files a/src/main/resources/assets/bewitchment/textures/block/purpur_witch_altar.png and b/src/main/resources/assets/bewitchment/textures/block/purpur_witch_altar.png differ diff --git a/src/main/resources/assets/bewitchment/textures/block/purpur_witch_altar_end.png b/src/main/resources/assets/bewitchment/textures/block/purpur_witch_altar_end.png index b13aa044..d1e9151e 100644 Binary files a/src/main/resources/assets/bewitchment/textures/block/purpur_witch_altar_end.png and b/src/main/resources/assets/bewitchment/textures/block/purpur_witch_altar_end.png differ diff --git a/src/main/resources/assets/blockus/textures/block/chiseled_purpur.png b/src/main/resources/assets/blockus/textures/block/chiseled_purpur.png index 44217c51..17007010 100644 Binary files a/src/main/resources/assets/blockus/textures/block/chiseled_purpur.png and b/src/main/resources/assets/blockus/textures/block/chiseled_purpur.png differ diff --git a/src/main/resources/assets/blockus/textures/block/purpur_bricks.png b/src/main/resources/assets/blockus/textures/block/purpur_bricks.png index 2a6b681b..89ad8e15 100644 Binary files a/src/main/resources/assets/blockus/textures/block/purpur_bricks.png and b/src/main/resources/assets/blockus/textures/block/purpur_bricks.png differ diff --git a/src/main/resources/assets/blockus/textures/block/purpur_lines.png b/src/main/resources/assets/blockus/textures/block/purpur_lines.png index 8525a8a8..2c43e75e 100644 Binary files a/src/main/resources/assets/blockus/textures/block/purpur_lines.png and b/src/main/resources/assets/blockus/textures/block/purpur_lines.png differ diff --git a/src/main/resources/assets/blockus/textures/block/purpur_little_bricks.png b/src/main/resources/assets/blockus/textures/block/purpur_little_bricks.png index 29640aad..e7cab518 100644 Binary files a/src/main/resources/assets/blockus/textures/block/purpur_little_bricks.png and b/src/main/resources/assets/blockus/textures/block/purpur_little_bricks.png differ diff --git a/src/main/resources/assets/blockus/textures/block/purpur_squares.png b/src/main/resources/assets/blockus/textures/block/purpur_squares.png index 11cba257..3aac01f2 100644 Binary files a/src/main/resources/assets/blockus/textures/block/purpur_squares.png and b/src/main/resources/assets/blockus/textures/block/purpur_squares.png differ diff --git a/src/main/resources/assets/blockus/textures/block/smooth_purpur.png b/src/main/resources/assets/blockus/textures/block/smooth_purpur.png index a6e571b3..3baca3eb 100644 Binary files a/src/main/resources/assets/blockus/textures/block/smooth_purpur.png and b/src/main/resources/assets/blockus/textures/block/smooth_purpur.png differ diff --git a/src/main/resources/assets/byg/textures/block/purpur_stone.png b/src/main/resources/assets/byg/textures/block/purpur_stone.png index 31306e84..61e671dc 100644 Binary files a/src/main/resources/assets/byg/textures/block/purpur_stone.png and b/src/main/resources/assets/byg/textures/block/purpur_stone.png differ diff --git a/src/main/resources/assets/colored_lights/light_colors.json b/src/main/resources/assets/colored_lights/light_colors.json new file mode 100644 index 00000000..27a890de --- /dev/null +++ b/src/main/resources/assets/colored_lights/light_colors.json @@ -0,0 +1,91 @@ +{ + "replace": false, + "colors": { + "betterend:smaragdant_crystal": "#17cfbd", + "betterend:smaragdant_crystal_shard": "#17cfbd", + "betterend:smaragdant_crystal_shard": "#17cfbd", + "betterend:smaragdant_crystal_bricks": "#17cfbd", + "betterend:smaragdant_crystal_bricks_slab": "#17cfbd", + "betterend:smaragdant_crystal_bricks_stairs": "#17cfbd", + "betterend:smaragdant_crystal_bricks_wall": "#17cfbd", + "betterend:smaragdant_crystal_pedestal": "#17cfbd", + "betterend:smaragdant_crystal_pillar": "#17cfbd", + "betterend:smaragdant_crystal_polished": "#17cfbd", + "betterend:smaragdant_crystal_slab": "#17cfbd", + "betterend:smaragdant_crystal_stairs": "#17cfbd", + "betterend:smaragdant_crystal_tiles": "#17cfbd", + "betterend:smaragdant_crystal_wall": "#17cfbd", + "betterend:aurora_crystal": "#f74da1", + "betterend:mossy_glowshroom_fur": "#8be6ff", + "betterend:mossy_glowshroom_hymenophore": "#8be6ff", + "betterend:umbrella_tree_cluster": "#c054f9", + "betterend:umbrella_tree_cluster": "#c054f9", + "betterend:umbrella_moss": "#ff943e", + "betterend:umbrella_moss_tall": "#ff943e", + "betterend:creeping_moss": "#0de4fc", + "betterend:twisted_umbrella_moss": "#e045d0", + "betterend:twisted_umbrella_moss_tall": "#e045d0", + "betterend:glowing_pillar_luminophor": "#ffd96c", + "betterend:glowing_pillar_leaves": "#ffd96c", + "betterend:bulb_moss": "#ffd96c", + "betterend:blue_vine_lantern": "#a6effb", + "betterend:blue_vine_fur": "#a6effb", + "betterend:purple_polypore": "#c53aec", + "betterend:aurant_polypore": "#a2d9ff", + "betterend:end_lily": "#c27dff", + "betterend:dense_vine": "#f47ffc", + "betterend:pond_anemone": "#f1f0da", + "betterend:amaranita_lantern": "#baecd9", + "betterend:amaranita_fur": "#baecd9", + + "betterend:neon_cactus": "#86f0e7", + "betterend:neon_cactus_block": "#86f0e7", + "betterend:neon_cactus_stairs": "#86f0e7", + "betterend:neon_cactus_slab": "#86f0e7", + + "betterend:iron_bulb_lantern_orange": "#ff963c", + "betterend:iron_bulb_lantern_magenta": "#d25aff", + "betterend:iron_bulb_lantern_light_blue": "#78b5ff", + "betterend:iron_bulb_lantern_yellow": "#ffff39", + "betterend:iron_bulb_lantern_lime": "#9fff1f", + "betterend:iron_bulb_lantern_pink": "#ff86ae", + "betterend:iron_bulb_lantern_cyan": "#7fd4ff", + "betterend:iron_bulb_lantern_purple": "#b65aff", + "betterend:iron_bulb_lantern_blue": "#496dff", + "betterend:iron_bulb_lantern_brown": "#ffbe80", + "betterend:iron_bulb_lantern_green": "#cdff66", + "betterend:iron_bulb_lantern_red": "#ff5555", + + "betterend:thallasium_bulb_lantern_orange": "#ff963c", + "betterend:thallasium_bulb_lantern_magenta": "#d25aff", + "betterend:thallasium_bulb_lantern_light_blue": "#78b5ff", + "betterend:thallasium_bulb_lantern_yellow": "#ffff39", + "betterend:thallasium_bulb_lantern_lime": "#9fff1f", + "betterend:thallasium_bulb_lantern_pink": "#ff86ae", + "betterend:thallasium_bulb_lantern_cyan": "#7fd4ff", + "betterend:thallasium_bulb_lantern_purple": "#b65aff", + "betterend:thallasium_bulb_lantern_blue": "#496dff", + "betterend:thallasium_bulb_lantern_brown": "#ffbe80", + "betterend:thallasium_bulb_lantern_green": "#cdff66", + "betterend:thallasium_bulb_lantern_red": "#ff5555", + + "betterend:terminite_bulb_lantern_orange": "#ff963c", + "betterend:terminite_bulb_lantern_magenta": "#d25aff", + "betterend:terminite_bulb_lantern_light_blue": "#78b5ff", + "betterend:terminite_bulb_lantern_yellow": "#ffff39", + "betterend:terminite_bulb_lantern_lime": "#9fff1f", + "betterend:terminite_bulb_lantern_pink": "#ff86ae", + "betterend:terminite_bulb_lantern_cyan": "#7fd4ff", + "betterend:terminite_bulb_lantern_purple": "#b65aff", + "betterend:terminite_bulb_lantern_blue": "#496dff", + "betterend:terminite_bulb_lantern_brown": "#ffbe80", + "betterend:terminite_bulb_lantern_green": "#cdff66", + "betterend:terminite_bulb_lantern_red": "#ff5555", + + "betterend:thallasium_chandelier": "#e0fceb", + "betterend:terminite_chandelier": "#e0fceb", + "betterend:iron_chandelier": "#e0fceb", + "betterend:gold_chandelier": "#e0fceb", + "betterend:lumecorn": "#e0fceb" + } +} diff --git a/src/main/resources/assets/emi/recipe/defaults/betterend.json b/src/main/resources/assets/emi/recipe/defaults/betterend.json new file mode 100644 index 00000000..b8f4cd5a --- /dev/null +++ b/src/main/resources/assets/emi/recipe/defaults/betterend.json @@ -0,0 +1,354 @@ +{ + "recipes": [ + "betterend:umbralith_bricks_slab", + "betterend:helix_tree_stripped_log", + "betterend:umbralith_furnace", + "betterend:lacugrove_stairs", + "betterend:dragon_bone_block", + "betterend:flavolite_wall", + "betterend:dragon_tree_stripped_log", + "betterend:violecite_polished", + "betterend:sulphuric_rock_stairs", + "betterend:tenanea_stripped_bark", + "betterend:smaragdant_crystal_bricks_slab", + "betterend:tenanea_slab", + "betterend:dragon_tree_slab", + "betterend:helix_tree_bookshelf", + "betterend:umbrella_tree_fence", + "betterend:thallasium_hoe", + "emi:bclib/terminite_sword_blade/anvil/item.betterend.terminite_hammer", + "betterend:flavolite_bricks_wall", + "betterend:thallasium_stairs", + "betterend:flavolite_tiles", + "betterend:azure_jadestone_furnace", + "betterend:helix_tree_stairs", + "betterend:umbrella_tree_barrel", + "betterend:lotus_block", + "betterend:mossy_glowshroom_planks", + "betterend:hydralux_petal_block_magenta", + "betterend:golden_hammer", + "betterend:violecite_bricks", + "betterend:dragon_tree_fence", + "betterend:purpur_pedestal", + "betterend:flavolite_pillar", + "betterend:violecite_bricks_wall", + "betterend:hydralux_petal_block_green", + "betterend:terminite_pickaxe", + "betterend:terminite_chestplate", + "betterend:tenanea_stairs", + "betterend:flavolite_bricks_slab", + "betterend:terminite_slab", + "betterend:crystalite_helmet", + "betterend:umbralith_bricks_stairs", + "betterend:azure_jadestone_slab", + "betterend:helix_tree_slab", + "betterend:helix_tree_gate", + "betterend:lacugrove_stripped_bark", + "betterend:umbrella_tree_slab", + "betterend:silk_moth_hive", + "betterend:thallasium_hammer", + "betterend:smaragdant_crystal_bricks_wall", + "betterend:pythadendron_chest", + "betterend:hydralux_petal_block_brown", + "betterend:violecite_bricks_stairs", + "betterend:thallasium_chain", + "betterend:smaragdant_crystal_polished", + "betterend:terminite_anvil_updrade", + "betterend:pythadendron_fence", + "betterend:virid_jadestone_tiles", + "betterend:terminite_bars", + "betterend:endstone_flower_pot", + "betterend:helix_tree_composter", + "emi:bclib/thallasium_sword_blade/anvil/item.betterend.iron_hammer", + "betterend:flavolite_polished", + "betterend:amber_gem", + "betterend:end_lotus_stripped_log", + "betterend:sulphuric_rock_wall", + "betterend:smaragdant_crystal_wall", + "betterend:aeternium_pickaxe", + "betterend:thallasium_sword_handle", + "betterend:pythadendron_bookshelf", + "betterend:amber_block", + "betterend:netherite_hammer", + "betterend:lucernia_planks", + "betterend:thallasium_slab", + "betterend:tenanea_planks", + "betterend:mossy_glowshroom_stripped_bark", + "betterend:end_lotus_stripped_bark", + "betterend:dragon_tree_stripped_bark", + "betterend:umbralith_pillar", + "betterend:jellyshroom_barrel", + "betterend:terminite_ingot_thallasium", + "betterend:jellyshroom_slab", + "betterend:thallasium_axe", + "betterend:tenanea_barrel", + "betterend:crystalite_boots", + "betterend:virid_jadestone_pillar", + "betterend:mossy_glowshroom_stairs", + "betterend:eternal_crystal", + "betterend:hydralux_petal_block_orange", + "betterend:thallasium_shovel", + "betterend:sulphuric_rock_bricks_slab", + "betterend:jellyshroom_gate", + "betterend:thallasium_chestplate", + "betterend:cave_pumpkin_pie", + "betterend:sulphuric_rock_bricks", + "betterend:umbrella_tree_stripped_bark", + "betterend:lacugrove_stripped_log", + "betterend:dragon_tree_planks", + "betterend:dragon_tree_barrel", + "betterend:hydralux_petal_block_purple", + "betterend:terminite_stairs", + "betterend:sandy_jadestone_tiles", + "betterend:aeternium_shovel", + "betterend:tenanea_fence", + "betterend:azure_jadestone_pedestal", + "betterend:lacugrove_chest", + "betterend:dragon_bone_slab", + "betterend:azure_jadestone_polished", + "betterend:bolux_mushroom_smelting", + "betterend:umbrella_tree_composter", + "betterend:end_lotus_bookshelf", + "betterend:dragon_tree_chest", + "betterend:terminite_sword", + "betterend:violecite_slab", + "betterend:sandy_jadestone_furnace", + "betterend:smaragdant_crystal_pillar", + "betterend:dragon_tree_stairs", + "betterend:smaragdant_crystal_stairs", + "betterend:ancient_emerald_ice", + "betterend:lacugrove_barrel", + "emi:bclib/aeternium_hammer_head/anvil/item.betterend.iron_hammer", + "betterend:sulphuric_rock_pedestal", + "betterend:lucernia_gate", + "betterend:jellyshroom_stripped_log", + "betterend:leather_to_stripes", + "betterend:sandy_jadestone_bricks_wall", + "betterend:virid_jadestone_flower_pot", + "betterend:aeternium_helmet", + "betterend:helix_tree_stripped_bark", + "betterend:azure_jadestone_bricks", + "betterend:lacugrove_fence", + "betterend:azure_jadestone_bricks_stairs", + "betterend:hydralux_petal_block_light_gray", + "betterend:flavolite_stairs", + "emi:bclib/aeternium_axe_head/anvil/item.betterend.aeternium_hammer", + "betterend:aeternium_hammer", + "betterend:sandy_jadestone_bricks", + "betterend:virid_jadestone_wall", + "betterend:mossy_glowshroom_chest", + "betterend:pythadendron_composter", + "betterend:aurora_block", + "betterend:hydralux_petal_block_pink", + "betterend:thallasium_helmet", + "betterend:hydralux_petal_block_cyan", + "betterend:sulphuric_rock_slab", + "betterend:sandy_jadestone_polished", + "betterend:dragon_tree_bookshelf", + "betterend:end_lotus_chest", + "betterend:lucernia_bookshelf", + "betterend:sandy_jadestone_pedestal", + "betterend:violecite_tiles", + "betterend:aeternium_chestplate", + "betterend:diamond_hammer", + "betterend:aeternium_axe", + "betterend:lucernia_slab", + "betterend:virid_jadestone_polished", + "betterend:umbralith_slab", + "betterend:mossy_glowshroom_stripped_log", + "betterend:end_lotus_slab", + "betterend:terminite_tile", + "betterend:thallasium_boots", + "betterend:sulphuric_rock_tiles", + "betterend:aeternium_sword", + "betterend:umbralith_bricks_wall", + "betterend:terminite_shovel", + "betterend:end_berry_smelting", + "betterend:lucernia_fence", + "betterend:hydralux_petal_block_lime", + "betterend:aeternium_sword_handle", + "betterend:dragon_tree_gate", + "betterend:crystalite_leggings", + "betterend:aeternium_hoe", + "betterend:neon_cactus_block", + "betterend:lacugrove_planks", + "betterend:umbralith_tiles", + "betterend:violecite_bricks_slab", + "betterend:tenanea_bookshelf", + "betterend:end_lotus_stairs", + "betterend:hydralux_petal_block_black", + "betterend:smaragdant_crystal_tiles", + "betterend:virid_jadestone_bricks", + "emi:bclib/thallasium_shovel_head/anvil/item.betterend.iron_hammer", + "betterend:end_lotus_composter", + "betterend:ender_perl_to_block", + "betterend:sandy_jadestone_wall", + "betterend:flavolite_furnace", + "betterend:neon_cactus_block_stairs", + "betterend:sandy_jadestone_pillar", + "betterend:thallasium_pickaxe", + "betterend:violecite_stairs", + "betterend:mossy_glowshroom_bark", + "betterend:terminite_chain", + "betterend:azure_jadestone_bricks_slab", + "betterend:andesite_pedestal", + "betterend:smaragdant_crystal_bricks_stairs", + "betterend:jellyshroom_fence", + "betterend:terminite_block", + "betterend:hydralux_petal_block_red", + "emi:bclib/terminite_axe_head/anvil/item.betterend.terminite_hammer", + "betterend:lacugrove_slab", + "betterend:crystalite_elytra", + "betterend:pythadendron_gate", + "betterend:virid_jadestone_slab", + "betterend:enchanted_membrane", + "betterend:missing_tile", + "betterend:hydralux_petal_block_white", + "betterend:runed_flavolite", + "emi:bclib/thallasium_forged_plate/anvil/item.betterend.iron_hammer", + "betterend:pythadendron_bark", + "betterend:terminite_axe", + "betterend:chorus_mushroom_smelting", + "betterend:diorite_pedestal", + "betterend:dragon_tree_composter", + "emi:bclib/thallasium_pickaxe_head/anvil/item.betterend.iron_hammer", + "betterend:umbrella_tree_stripped_log", + "betterend:umbrella_tree_stairs", + "emi:bclib/aeternium_hoe_head/anvil/item.betterend.aeternium_hammer", + "emi:bclib/terminite_shovel_head/anvil/item.betterend.terminite_hammer", + "betterend:sulphuric_rock_bricks_stairs", + "betterend:pythadendron_stairs", + "betterend:pythadendron_slab", + "betterend:thallasium_sword", + "betterend:lacugrove_bookshelf", + "betterend:terminite_leggings", + "betterend:sandy_jadestone_flower_pot", + "betterend:terminite_hoe", + "emi:bclib/ender_shard_to_dust/anvil/item.betterend.iron_hammer", + "betterend:leather_wrapped_stick", + "betterend:end_lotus_fence", + "betterend:mossy_glowshroom_fence", + "betterend:violecite_pedestal", + "betterend:end_lotus_gate", + "betterend:aeternium_boots", + "betterend:end_lotus_planks", + "emi:bclib/thallasium_axe_head/anvil/item.betterend.iron_hammer", + "betterend:sulphuric_rock_lantern", + "emi:bclib/terminite_pickaxe_head/anvil/item.betterend.terminite_hammer", + "betterend:virid_jadestone_stairs", + "betterend:neon_cactus_block_slab", + "betterend:helix_tree_fence", + "betterend:crystalite_chestplate", + "betterend:lucernia_stripped_log", + "betterend:mossy_glowshroom_gate", + "betterend:umbrella_tree_chest", + "betterend:mossy_glowshroom_composter", + "betterend:violecite_pillar", + "betterend:pythadendron_stripped_log", + "betterend:smaragdant_crystal_bricks", + "betterend:lucernia_composter", + "betterend:azure_jadestone_pillar", + "betterend:lacugrove_composter", + "betterend:flavolite_slab", + "betterend:pythadendron_stripped_bark", + "betterend:lucernia_stairs", + "betterend:helix_tree_barrel", + "betterend:sandy_jadestone_bricks_slab", + "betterend:infusion_pedestal", + "betterend:virid_jadestone_bricks_wall", + "betterend:mossy_glowshroom_bookshelf", + "betterend:end_lotus_barrel", + "emi:bclib/terminite_hoe_head/anvil/item.betterend.terminite_hammer", + "betterend:umbrella_tree_bookshelf", + "betterend:flavolite_bricks", + "betterend:aeternium_block", + "betterend:enchanted_petal", + "emi:bclib/aeternium_sword_blade/anvil/item.betterend.aeternium_hammer", + "betterend:flavolite_bricks_stairs", + "betterend:armored_elytra", + "betterend:tenanea_chest", + "betterend:jellyshroom_stripped_bark", + "betterend:aeternium_leggings", + "betterend:pythadendron_barrel", + "betterend:azure_jadestone_stairs", + "betterend:charcoal_block", + "betterend:terminite_anvil", + "betterend:umbralith_flower_pot", + "betterend:lacugrove_gate", + "betterend:umbralith_wall", + "betterend:granite_pedestal", + "betterend:azure_jadestone_flower_pot", + "betterend:lucernia_chest", + "emi:bclib/terminite_forged_plate/anvil/item.betterend.terminite_hammer", + "betterend:virid_jadestone_pedestal", + "betterend:helix_tree_chest", + "betterend:umbrella_tree_planks", + "betterend:thallasium_block", + "betterend:terminite_helmet", + "betterend:flavolite_flower_pot", + "betterend:sandy_jadestone_stairs", + "betterend:tenanea_stripped_log", + "betterend:petal_block", + "betterend:mossy_glowshroom_log", + "betterend:smaragdant_crystal_pedestal", + "betterend:violecite_button", + "betterend:mossy_glowshroom_slab", + "betterend:sulphuric_rock_pillar", + "betterend:terminite_boots", + "betterend:jellyshroom_stairs", + "betterend:virid_jadestone_bricks_stairs", + "betterend:dragon_bone_stairs", + "betterend:hydralux_petal_block_gray", + "betterend:sulphuric_rock_bricks_wall", + "betterend:iron_hammer", + "betterend:mossy_glowshroom_barrel", + "betterend:violecite_flower_pot", + "emi:bclib/aeternium_pickaxe_head/anvil/item.betterend.aeternium_hammer", + "betterend:terminite_sword_handle", + "betterend:umbralith_pedestal", + "betterend:thallasium_tile", + "betterend:jellyshroom_bookshelf", + "betterend:virid_jadestone_furnace", + "betterend:umbralith_stairs", + "betterend:sandy_jadestone_bricks_stairs", + "betterend:tenanea_composter", + "betterend:umbralith_bricks", + "betterend:quartz_pedestal", + "betterend:jellyshroom_planks", + "betterend:pythadendron_log", + "betterend:thallasium_bars", + "betterend:sulphuric_rock_furnace", + "betterend:azure_jadestone_tiles", + "betterend:pythadendron_planks", + "emi:bclib/thallasium_hoe_head/anvil/item.betterend.iron_hammer", + "betterend:virid_jadestone_bricks_slab", + "betterend:hydralux_petal_block_yellow", + "betterend:sulphuric_rock_polished", + "betterend:helix_tree_planks", + "betterend:hydralux_petal_block_blue", + "betterend:smaragdant_crystal_slab", + "betterend:azure_jadestone_wall", + "betterend:hydralux_petal_block_light_blue", + "betterend:thallasium_anvil", + "betterend:sandy_jadestone_slab", + "betterend:violecite_furnace", + "betterend:flavolite_pedestal", + "betterend:tenanea_gate", + "emi:bclib/aeternium_shovel_head/anvil/item.betterend.aeternium_hammer", + "betterend:thallasium_leggings", + "emi:bclib/aeternium_forged_plate/anvil/item.betterend.aeternium_hammer", + "betterend:violecite_wall", + "betterend:sweet_berry_jelly", + "betterend:jellyshroom_chest", + "betterend:dense_emerald_ice", + "betterend:lucernia_barrel", + "betterend:umbralith_polished", + "betterend:lucernia_stripped_bark", + "betterend:azure_jadestone_bricks_wall", + "betterend:filalux_lantern", + "betterend:aeternium_ingot", + "betterend:sulphuric_rock_flower_pot", + "betterend:umbrella_tree_gate", + "betterend:jellyshroom_composter" + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/0.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/0.png index 1b08edf3..e35e0e30 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/0.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/0.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/1.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/1.png index 87d5d00d..f8b1f0fb 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/1.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/1.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/10.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/10.png index 135782d0..fffc947a 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/10.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/10.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/11.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/11.png index f757688d..ef365d77 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/11.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/11.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/12.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/12.png index 8903c2dd..a447bf70 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/12.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/12.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/13.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/13.png index 6439f421..ff96ff52 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/13.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/13.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/14.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/14.png index 6ebfa407..f2f65591 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/14.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/14.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/15.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/15.png index dc7d4bc3..59f292b8 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/15.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/15.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/16.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/16.png index f3abcfc0..7442be04 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/16.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/16.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/2.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/2.png index 972d93e4..c735c575 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/2.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/2.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/3.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/3.png index 7087d639..c2e95e6f 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/3.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/3.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/4.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/4.png index 5ecf596c..50ccf0a4 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/4.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/4.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/5.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/5.png index a596289d..e7f21a15 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/5.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/5.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/6.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/6.png index ef8eb740..3705b251 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/6.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/6.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/7.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/7.png index 59ebd87b..c97104f4 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/7.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/7.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/8.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/8.png index 2c6a6ab9..ec938419 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/8.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/8.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/9.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/9.png index f4b2e314..d4eca12d 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/9.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/00_cave_moss/9.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/0.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/0.png index 66489430..b3db56d3 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/0.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/0.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/1.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/1.png index afad59e1..0605e3a3 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/1.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/1.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/10.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/10.png index 17f87ab2..41926be9 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/10.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/10.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/11.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/11.png index ff076b69..802efb30 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/11.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/11.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/12.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/12.png index 66afd0b7..0b69d778 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/12.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/12.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/13.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/13.png index 4bc3438d..fa76fce5 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/13.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/13.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/14.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/14.png index d07298d1..d9170d41 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/14.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/14.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/15.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/15.png index bb838314..39e9fab4 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/15.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/15.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/16.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/16.png index 3a2e30bd..4bab73b4 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/16.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/16.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/2.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/2.png index 1e27b8bd..1c43f1bc 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/2.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/2.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/3.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/3.png index b3e34e3e..3608f6d0 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/3.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/3.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/4.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/4.png index c342d455..83b283eb 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/4.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/4.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/5.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/5.png index fee7f640..522ada94 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/5.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/5.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/6.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/6.png index a6642af1..aba464e8 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/6.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/6.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/7.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/7.png index f06882d1..9b312c36 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/7.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/7.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/8.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/8.png index 1f7a4c21..94f2c43e 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/8.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/8.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/9.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/9.png index fa92f732..824b7ebc 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/9.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/01_end_mycelium/9.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/0.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/0.png index cf819bb8..465d5358 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/0.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/0.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/1.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/1.png index bc01affc..801faafd 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/1.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/1.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/10.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/10.png index effc7384..fd8e7d17 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/10.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/10.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/11.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/11.png index 30af3a9d..c22ce00f 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/11.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/11.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/12.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/12.png index 0b74ea00..c2710df1 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/12.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/12.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/13.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/13.png index bb1198e4..30f6aba6 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/13.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/13.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/14.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/14.png index eab2989c..a0f03d2c 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/14.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/14.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/15.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/15.png index e888cb2d..738c9da9 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/15.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/15.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/16.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/16.png index d621f44d..9bfc4986 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/16.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/16.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/2.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/2.png index fe25e341..8fdcc355 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/2.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/2.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/3.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/3.png index 5eef4cad..748a1aad 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/3.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/3.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/4.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/4.png index b1d24587..4ea91ed7 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/4.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/4.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/5.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/5.png index dd439534..1d19f8e0 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/5.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/5.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/6.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/6.png index aff99fbb..044a5ba4 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/6.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/6.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/7.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/7.png index decc1df6..0c455d64 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/7.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/7.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/8.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/8.png index 3539ffee..9bd4e667 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/8.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/8.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/9.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/9.png index 19456c06..85a9d7a2 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/9.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/02_shadow_grass/9.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/0.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/0.png index 0e8a30b8..e8e22abf 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/0.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/0.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/1.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/1.png index a279ef34..ca0324af 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/1.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/1.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/10.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/10.png index 8f213540..cbedd02c 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/10.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/10.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/11.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/11.png index 3e2f8e4f..9e411cbd 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/11.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/11.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/12.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/12.png index 7ac8e31f..137f7005 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/12.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/12.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/13.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/13.png index 7e146564..aa0e6724 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/13.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/13.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/14.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/14.png index db2cbf58..0247631c 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/14.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/14.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/15.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/15.png index a9c0943b..766f65e7 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/15.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/15.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/16.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/16.png index 03fb198b..ca7445f0 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/16.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/16.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/2.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/2.png index c298da04..8fd26cfd 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/2.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/2.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/3.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/3.png index b3aab034..34a8f1b2 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/3.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/3.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/4.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/4.png index 3d319553..c69de7e8 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/4.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/4.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/5.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/5.png index 8a49840f..7edf53a1 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/5.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/5.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/6.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/6.png index a338a2e9..a3a54f27 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/6.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/6.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/7.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/7.png index faf95c26..4fc10095 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/7.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/7.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/8.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/8.png index 80bc0611..7a864223 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/8.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/8.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/9.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/9.png index 87bb5c50..892730d8 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/9.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/03_pink_moss/9.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/0.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/0.png index 057d32f9..c7ce97eb 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/0.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/0.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/1.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/1.png index 9594e510..ad5ae8b6 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/1.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/1.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/10.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/10.png index 732e8e8a..d8f0cb1f 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/10.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/10.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/11.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/11.png index ddc6c4e9..15338b50 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/11.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/11.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/12.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/12.png index 7373cf41..bb282269 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/12.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/12.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/13.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/13.png index 65761543..ba7f8862 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/13.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/13.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/14.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/14.png index 4d49254f..bab62dfa 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/14.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/14.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/15.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/15.png index dba78f68..ae07790e 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/15.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/15.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/16.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/16.png index 112d9b5c..f0dbcdb4 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/16.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/16.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/2.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/2.png index 9279002d..9c685e7b 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/2.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/2.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/3.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/3.png index f50499f0..e12468a9 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/3.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/3.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/4.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/4.png index 9f8bed30..e811f505 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/4.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/4.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/5.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/5.png index a4365c8a..14426459 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/5.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/5.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/6.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/6.png index 9ebf8e71..b5d78b6a 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/6.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/6.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/7.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/7.png index cc2d5b7a..dd9ef897 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/7.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/7.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/8.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/8.png index af2b1b2f..59c827c4 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/8.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/8.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/9.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/9.png index fa238e33..1261fea2 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/9.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/04_crystal_moss/9.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/0.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/0.png index 8e3d4cf1..f4627524 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/0.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/0.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/1.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/1.png index 83823914..ab7e5acb 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/1.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/1.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/10.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/10.png index f623c7bd..35bfd8fc 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/10.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/10.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/11.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/11.png index bef6508c..46f56d24 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/11.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/11.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/12.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/12.png index 6e9b01bb..e5e7653b 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/12.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/12.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/13.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/13.png index 82fc46bb..a726a29d 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/13.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/13.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/14.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/14.png index 42c137e2..bb715e9b 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/14.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/14.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/15.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/15.png index b9dcf33b..7dfc8b2c 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/15.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/15.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/16.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/16.png index c0393d14..4e650050 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/16.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/16.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/2.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/2.png index f392e546..25d449ab 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/2.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/2.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/3.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/3.png index c9ba7fc2..afc94eb6 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/3.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/3.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/4.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/4.png index ea9eec42..45d760c7 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/4.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/4.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/5.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/5.png index e310bbba..9a87e827 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/5.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/5.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/6.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/6.png index 489a5a54..a8c1df6c 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/6.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/6.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/7.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/7.png index 9bc9721c..2cb304e3 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/7.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/7.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/8.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/8.png index 49794325..f905aade 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/8.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/8.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/9.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/9.png index 434b7583..afe52a24 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/9.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/05_chorus_nylium/9.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/0.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/0.png index 2a25ff4e..a03ee9fa 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/0.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/0.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/1.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/1.png index b2a070a8..690e721b 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/1.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/1.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/10.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/10.png index f0ae41cd..77f674d8 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/10.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/10.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/11.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/11.png index bd38bc7a..4521db24 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/11.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/11.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/12.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/12.png index 09de79e7..7b98c48e 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/12.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/12.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/13.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/13.png index 1d506846..f1112101 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/13.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/13.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/14.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/14.png index 032f429d..bf3d3ecf 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/14.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/14.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/15.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/15.png index a31f1211..dbbdf295 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/15.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/15.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/16.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/16.png index 574f4558..e766d0d1 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/16.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/16.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/2.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/2.png index 7d5bcb39..caf58486 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/2.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/2.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/3.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/3.png index 19214a1b..d4c8417d 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/3.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/3.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/4.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/4.png index cde72ff0..ed389ea9 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/4.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/4.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/5.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/5.png index 28aa99ee..9b30d8cc 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/5.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/5.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/6.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/6.png index 9d190d75..d552e74d 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/6.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/6.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/7.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/7.png index 19041ceb..bed058cb 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/7.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/7.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/8.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/8.png index 9fbfc238..a9286d3d 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/8.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/8.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/9.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/9.png index 14fdd580..3788424e 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/9.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/06_end_moss/9.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/0.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/0.png index 8db7ca1f..1c7a1419 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/0.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/0.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/1.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/1.png index 54eeb8c0..3a1ad64f 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/1.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/1.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/10.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/10.png index a3218431..200ad38a 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/10.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/10.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/11.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/11.png index b3a93ac7..71e680e4 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/11.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/11.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/12.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/12.png index 1b2d4715..9eb57038 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/12.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/12.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/13.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/13.png index 3998baf8..afeac637 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/13.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/13.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/14.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/14.png index 21a2a1d9..a3cd5fb3 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/14.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/14.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/15.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/15.png index 1aa8e0be..31a7e901 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/15.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/15.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/16.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/16.png index 51651b61..556d1171 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/16.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/16.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/2.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/2.png index fd9ca0bb..f5cf4f71 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/2.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/2.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/3.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/3.png index a62a37e5..101b9e62 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/3.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/3.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/4.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/4.png index 236fc41e..cc6315e6 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/4.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/4.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/5.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/5.png index 78df1b23..54aec74c 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/5.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/5.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/6.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/6.png index 13177059..a1722234 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/6.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/6.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/7.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/7.png index 0828a363..fa6c59fa 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/7.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/7.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/8.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/8.png index 84c01406..f746c58b 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/8.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/8.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/9.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/9.png index 36a53fdb..a48f14f7 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/9.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/07_jungle_moss/9.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/0.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/0.png index 825c5a61..64a79612 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/0.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/0.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/1.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/1.png index ffcddb8b..f668523a 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/1.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/1.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/10.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/10.png index 95ae3e9b..0bf9f4aa 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/10.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/10.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/11.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/11.png index 61a75bc8..7df0bdd2 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/11.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/11.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/12.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/12.png index d6a962bf..cd6ab240 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/12.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/12.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/13.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/13.png index bf7e550d..db816de0 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/13.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/13.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/14.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/14.png index 17ddf5d3..575e0622 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/14.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/14.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/15.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/15.png index bae0ee46..fdca200b 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/15.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/15.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/16.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/16.png index cc1dfd7d..bb054f68 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/16.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/16.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/2.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/2.png index 15620fc3..02657aaa 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/2.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/2.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/3.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/3.png index becaaa5b..c2427c79 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/3.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/3.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/4.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/4.png index abe4f264..b939f32b 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/4.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/4.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/5.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/5.png index f556156b..7f737726 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/5.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/5.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/6.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/6.png index 987fbde5..74395dd6 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/6.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/6.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/7.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/7.png index be6227d8..67f93834 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/7.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/7.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/8.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/8.png index 8f0a7609..a020e139 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/8.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/8.png differ diff --git a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/9.png b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/9.png index e8b707d4..d3c12ed6 100644 Binary files a/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/9.png and b/src/main/resources/assets/minecraft/optifine/ctm/_overlays/08_amber_moss/9.png differ diff --git a/src/main/resources/assets/minecraft/textures/block/andesite_pillar.png b/src/main/resources/assets/minecraft/textures/block/andesite_pillar.png index c6af95fc..8d71ded8 100644 Binary files a/src/main/resources/assets/minecraft/textures/block/andesite_pillar.png and b/src/main/resources/assets/minecraft/textures/block/andesite_pillar.png differ diff --git a/src/main/resources/assets/minecraft/textures/block/diorite_pillar.png b/src/main/resources/assets/minecraft/textures/block/diorite_pillar.png index 3da66679..bed31af4 100644 Binary files a/src/main/resources/assets/minecraft/textures/block/diorite_pillar.png and b/src/main/resources/assets/minecraft/textures/block/diorite_pillar.png differ diff --git a/src/main/resources/assets/minecraft/textures/block/granite_pillar.png b/src/main/resources/assets/minecraft/textures/block/granite_pillar.png index 2e1e0541..c3fbfdda 100644 Binary files a/src/main/resources/assets/minecraft/textures/block/granite_pillar.png and b/src/main/resources/assets/minecraft/textures/block/granite_pillar.png differ diff --git a/src/main/resources/assets/minecraft/textures/block/purpur_block.png b/src/main/resources/assets/minecraft/textures/block/purpur_block.png index 361c099a..4b12900a 100644 Binary files a/src/main/resources/assets/minecraft/textures/block/purpur_block.png and b/src/main/resources/assets/minecraft/textures/block/purpur_block.png differ diff --git a/src/main/resources/assets/minecraft/textures/block/purpur_pillar.png b/src/main/resources/assets/minecraft/textures/block/purpur_pillar.png index 6047dc55..4113a913 100644 Binary files a/src/main/resources/assets/minecraft/textures/block/purpur_pillar.png and b/src/main/resources/assets/minecraft/textures/block/purpur_pillar.png differ diff --git a/src/main/resources/assets/minecraft/textures/block/purpur_pillar_top.png b/src/main/resources/assets/minecraft/textures/block/purpur_pillar_top.png index df441003..a2a4e774 100644 Binary files a/src/main/resources/assets/minecraft/textures/block/purpur_pillar_top.png and b/src/main/resources/assets/minecraft/textures/block/purpur_pillar_top.png differ diff --git a/src/main/resources/assets/minecraft/textures/entity/shulker/shulker.png b/src/main/resources/assets/minecraft/textures/entity/shulker/shulker.png index 9c2b811c..49d633c9 100644 Binary files a/src/main/resources/assets/minecraft/textures/entity/shulker/shulker.png and b/src/main/resources/assets/minecraft/textures/entity/shulker/shulker.png differ diff --git a/src/main/resources/assets/minecraft/textures/models/armor/aeternium_layer_1.png b/src/main/resources/assets/minecraft/textures/models/armor/aeternium_layer_1.png index f6051cad..69da1276 100644 Binary files a/src/main/resources/assets/minecraft/textures/models/armor/aeternium_layer_1.png and b/src/main/resources/assets/minecraft/textures/models/armor/aeternium_layer_1.png differ diff --git a/src/main/resources/assets/minecraft/textures/models/armor/aeternium_layer_2.png b/src/main/resources/assets/minecraft/textures/models/armor/aeternium_layer_2.png index cc99c6b5..ee2caadf 100644 Binary files a/src/main/resources/assets/minecraft/textures/models/armor/aeternium_layer_2.png and b/src/main/resources/assets/minecraft/textures/models/armor/aeternium_layer_2.png differ diff --git a/src/main/resources/assets/minecraft/textures/models/armor/crystalite_layer_1.png b/src/main/resources/assets/minecraft/textures/models/armor/crystalite_layer_1.png index 5019c1ce..324011ce 100644 Binary files a/src/main/resources/assets/minecraft/textures/models/armor/crystalite_layer_1.png and b/src/main/resources/assets/minecraft/textures/models/armor/crystalite_layer_1.png differ diff --git a/src/main/resources/assets/minecraft/textures/models/armor/crystalite_layer_2.png b/src/main/resources/assets/minecraft/textures/models/armor/crystalite_layer_2.png index 26bda1e9..effa931f 100644 Binary files a/src/main/resources/assets/minecraft/textures/models/armor/crystalite_layer_2.png and b/src/main/resources/assets/minecraft/textures/models/armor/crystalite_layer_2.png differ diff --git a/src/main/resources/assets/minecraft/textures/models/armor/crystalite_overlay_layer_1.png b/src/main/resources/assets/minecraft/textures/models/armor/crystalite_overlay_layer_1.png index 42b159fe..0f954570 100644 Binary files a/src/main/resources/assets/minecraft/textures/models/armor/crystalite_overlay_layer_1.png and b/src/main/resources/assets/minecraft/textures/models/armor/crystalite_overlay_layer_1.png differ diff --git a/src/main/resources/assets/minecraft/textures/models/armor/crystalite_overlay_layer_2.png b/src/main/resources/assets/minecraft/textures/models/armor/crystalite_overlay_layer_2.png index 692a470d..6654b4fc 100644 Binary files a/src/main/resources/assets/minecraft/textures/models/armor/crystalite_overlay_layer_2.png and b/src/main/resources/assets/minecraft/textures/models/armor/crystalite_overlay_layer_2.png differ diff --git a/src/main/resources/assets/minecraft/textures/models/armor/terminite_layer_1.png b/src/main/resources/assets/minecraft/textures/models/armor/terminite_layer_1.png index b2ba4409..85623658 100644 Binary files a/src/main/resources/assets/minecraft/textures/models/armor/terminite_layer_1.png and b/src/main/resources/assets/minecraft/textures/models/armor/terminite_layer_1.png differ diff --git a/src/main/resources/assets/minecraft/textures/models/armor/terminite_layer_2.png b/src/main/resources/assets/minecraft/textures/models/armor/terminite_layer_2.png index c4711e2d..b609bf78 100644 Binary files a/src/main/resources/assets/minecraft/textures/models/armor/terminite_layer_2.png and b/src/main/resources/assets/minecraft/textures/models/armor/terminite_layer_2.png differ diff --git a/src/main/resources/assets/minecraft/textures/models/armor/thallasium_layer_1.png b/src/main/resources/assets/minecraft/textures/models/armor/thallasium_layer_1.png index 228612cf..7517e1fb 100644 Binary files a/src/main/resources/assets/minecraft/textures/models/armor/thallasium_layer_1.png and b/src/main/resources/assets/minecraft/textures/models/armor/thallasium_layer_1.png differ diff --git a/src/main/resources/assets/minecraft/textures/models/armor/thallasium_layer_2.png b/src/main/resources/assets/minecraft/textures/models/armor/thallasium_layer_2.png index 9d1f79b1..75f6cbaf 100644 Binary files a/src/main/resources/assets/minecraft/textures/models/armor/thallasium_layer_2.png and b/src/main/resources/assets/minecraft/textures/models/armor/thallasium_layer_2.png differ diff --git a/src/main/resources/betterend.accesswidener b/src/main/resources/betterend.accesswidener new file mode 100644 index 00000000..1c8e98af --- /dev/null +++ b/src/main/resources/betterend.accesswidener @@ -0,0 +1,4 @@ +accessWidener v1 named + +# Classes +accessible class net/minecraft/world/level/levelgen/SurfaceRules$SurfaceRule diff --git a/src/main/resources/betterend.mixins.client.json b/src/main/resources/betterend.mixins.client.json index 084bbab4..6551baa3 100644 --- a/src/main/resources/betterend.mixins.client.json +++ b/src/main/resources/betterend.mixins.client.json @@ -1,26 +1,21 @@ { - "required": true, - "minVersion": "0.8", - "package": "ru.betterend.mixin.client", - "compatibilityLevel": "JAVA_8", - "client": [ - "AbstractSoundInstanceAccessor", - "ClientPlayNetworkHandlerMixin", - "HumanoidMobRendererMixin", - "ArmorStandRendererMixin", - "ClientRecipeBookMixin", - "MinecraftClientMixin", - "PlayerRendererMixin", - "WorldRendererMixin", - "MusicTrackerMixin", - "AnvilScreenMixin", - "BiomeColorsMixin", - "ModelLoaderMixin", - "LocalPlayerMixin", - "CapeLayerMixin", - "ItemStackMixin" - ], - "injectors": { - "defaultRequire": 1 - } + "required": true, + "minVersion": "0.8", + "package": "org.betterx.betterend.mixin.client", + "compatibilityLevel": "JAVA_16", + "client": [ + "AbstractSoundInstanceAccessor", + "ArmorStandRendererMixin", + "BiomeColorsMixin", + "CapeLayerMixin", + "HumanoidMobRendererMixin", + "ItemStackMixin", + "MinecraftClientMixin", + "ModelLoaderMixin", + "MusicTrackerMixin", + "PlayerRendererMixin" + ], + "injectors": { + "defaultRequire": 1 + } } diff --git a/src/main/resources/betterend.mixins.common.json b/src/main/resources/betterend.mixins.common.json index e4d533ea..33ede3c7 100644 --- a/src/main/resources/betterend.mixins.common.json +++ b/src/main/resources/betterend.mixins.common.json @@ -1,31 +1,29 @@ { "required": true, "minVersion": "0.8", - "package": "ru.betterend.mixin.common", - "compatibilityLevel": "JAVA_8", + "package": "org.betterx.betterend.mixin.common", + "compatibilityLevel": "JAVA_16", "mixins": [ - "BiomeGenerationSettingsAccessor", - "NoiseBasedChunkGeneratorMixin", - "ChunkBiomeContainerMixin", - "WeightedBiomePickerMixin", + "LevelMixin", + "NoiseBasedChunkGeneratorAccessor", + "NoiseGeneratorSettingsMixin", + "NoiseInterpolatorAccessor", "ChorusPlantFeatureMixin", "PlayerAdvancementsMixin", "ChorusFlowerBlockMixin", - "ComposterBlockAccessor", "ChorusPlantBlockMixin", "EndPodiumFeatureMixin", - "PotionBrewingAccessor", - "MinecraftServerMixin", "EndDragonFightMixin", + "MappedRegistryMixin", + "WorldGenRegionMixin", "BlockBehaviourMixin", - "DimensionTypeMixin", + "NoiseChunkAccessor", "CraftingMenuMixin", "LivingEntityMixin", "ServerPlayerMixin", - "SpikeFeatureMixin", + "SpikeFeatureMixin", "ServerLevelMixin", - "PlayerListMixin", - "AnvilMenuMixin", + "NoiseChunkMixin", "EnderManMixin", "EndSpikeMixin", "MonsterMixin", diff --git a/src/main/resources/betterend.mixins.shadow.json b/src/main/resources/betterend.mixins.shadow.json new file mode 100644 index 00000000..08955be4 --- /dev/null +++ b/src/main/resources/betterend.mixins.shadow.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "shadow.fabric.mixin.client.rendering", + "compatibilityLevel": "JAVA_16", + "client": [ + "MixinArmorFeatureRenderer", + "MixinItem" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/main/resources/data/betterend/loot_tables/chests/chorus_forest.json b/src/main/resources/data/betterend/loot_tables/chests/chorus_forest.json new file mode 100644 index 00000000..c135faf3 --- /dev/null +++ b/src/main/resources/data/betterend/loot_tables/chests/chorus_forest.json @@ -0,0 +1,4 @@ +{ + "type": "minecraft:chest", + "pools": [] +} diff --git a/src/main/resources/data/betterend/loot_tables/chests/common.json b/src/main/resources/data/betterend/loot_tables/chests/common.json new file mode 100644 index 00000000..c135faf3 --- /dev/null +++ b/src/main/resources/data/betterend/loot_tables/chests/common.json @@ -0,0 +1,4 @@ +{ + "type": "minecraft:chest", + "pools": [] +} diff --git a/src/main/resources/data/betterend/loot_tables/chests/foggy_mushroomland.json b/src/main/resources/data/betterend/loot_tables/chests/foggy_mushroomland.json new file mode 100644 index 00000000..c135faf3 --- /dev/null +++ b/src/main/resources/data/betterend/loot_tables/chests/foggy_mushroomland.json @@ -0,0 +1,4 @@ +{ + "type": "minecraft:chest", + "pools": [] +} diff --git a/src/main/resources/data/betterend/loot_tables/chests/lantern_woods.json b/src/main/resources/data/betterend/loot_tables/chests/lantern_woods.json new file mode 100644 index 00000000..c135faf3 --- /dev/null +++ b/src/main/resources/data/betterend/loot_tables/chests/lantern_woods.json @@ -0,0 +1,4 @@ +{ + "type": "minecraft:chest", + "pools": [] +} diff --git a/src/main/resources/data/betterend/loot_tables/chests/shadow_forest.json b/src/main/resources/data/betterend/loot_tables/chests/shadow_forest.json new file mode 100644 index 00000000..c135faf3 --- /dev/null +++ b/src/main/resources/data/betterend/loot_tables/chests/shadow_forest.json @@ -0,0 +1,4 @@ +{ + "type": "minecraft:chest", + "pools": [] +} diff --git a/src/main/resources/data/betterend/loot_tables/chests/umbrella_jungle.json b/src/main/resources/data/betterend/loot_tables/chests/umbrella_jungle.json new file mode 100644 index 00000000..c135faf3 --- /dev/null +++ b/src/main/resources/data/betterend/loot_tables/chests/umbrella_jungle.json @@ -0,0 +1,4 @@ +{ + "type": "minecraft:chest", + "pools": [] +} diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/categories/biomes.json b/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/categories/biomes.json new file mode 100644 index 00000000..26fc50b9 --- /dev/null +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/categories/biomes.json @@ -0,0 +1,5 @@ +{ + "name": "Biome", + "description": "Bald verfügabr...", + "icon": "betterend:end_mycelium" +} \ No newline at end of file diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/categories/crafting.json b/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/categories/crafting.json new file mode 100644 index 00000000..1b0b44fb --- /dev/null +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/categories/crafting.json @@ -0,0 +1,6 @@ +{ + "name": "Crafting", + "description": "Bald verfügabr...", + "icon": "betterend:iron_hammer", + "sortnum": 2 +} \ No newline at end of file diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/categories/end_veil.json b/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/categories/end_veil.json new file mode 100644 index 00000000..fc2d51d3 --- /dev/null +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/categories/end_veil.json @@ -0,0 +1,6 @@ +{ + "name": "Endschleier", + "description": "Schaue den Enderman ohne Furcht tief in die Augen.", + "icon": "betterend:textures/mob_effect/end_veil.png", + "sortnum": 3 +} \ No newline at end of file diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/categories/rituals.json b/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/categories/rituals.json new file mode 100644 index 00000000..308b16fc --- /dev/null +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/categories/rituals.json @@ -0,0 +1,6 @@ +{ + "name": "Rituale", + "description": "Mystische Künste aus dem End. Diese in der Oberwelt lang vergessenen Rituale eröffnen Dir neue Wege und Möglichkeiten.", + "icon": "betterend:infusion_pedestal", + "sortnum": 1 +} \ No newline at end of file diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/entries/rituals/eternal_ritual.json b/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/entries/rituals/eternal_ritual.json new file mode 100644 index 00000000..c093f043 --- /dev/null +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/entries/rituals/eternal_ritual.json @@ -0,0 +1,44 @@ +{ + "name": "Rituale der Ewigkeit", + "icon": "betterend:eternal_pedestal", + "read_by_default": true, + "category": "betterend:rituals", + "pages": [ + { + "type": "text", + "text": "\"Ein steiniger Weg zurück in die Oberwelt.\"$(br2)Auf Deinen Reisen durch das End wirst du gelegentlich alte Ruinen finden.$(br2)Alte Mythen erzählen von einem (vielleicht schon) zerstörten Rahme aus $(bold)Flavolitrune$(), der von sechs Sockeln umringt ist." + }, + { + "type": "image", + "text": "", + "border": false, + "images": [ + "betterend:textures/images/eternal_ritual/portal_structure.png" + ] + }, + { + "type": "text", + "text": "Es sind die letzte überbleibsel eines majestätischen Protals, dass einst eine Pforte zwischen der Oberwelt und dem End bildete.$(br2)Um das Protal wieder zum leben zu erwecken, musst Du zuerst die Teile des Rahmens finden und vervollständigen." + }, + { + "type": "image", + "text": "Platziere dann 6 $(bold)Ewige Kristalle$() auf den Sockeln.", + "border": false, + "images": [ + "betterend:textures/images/eternal_ritual/portal_frame_full.png" + ] + }, + { + "type": "image", + "text": "Sobald der letzte Kirstall paltziert wurde,", + "border": false, + "images": [ + "betterend:textures/images/eternal_ritual/ritual_finished.png" + ] + }, + { + "type": "text", + "text": "wird das Portal aus seinem Schlummer erwachen und die Welten verbinden. Die $(bold)Flavolitrune$() (um den Rahmen zu reparieren) und die $(bold)Ewige Kristalle$() können durch ein $(l:rituals/infusion_ritual)Infusionsritual$(/l) erschaffen werden." + } + ] +} diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/entries/rituals/infusion_ritual.json b/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/entries/rituals/infusion_ritual.json new file mode 100644 index 00000000..df3583ed --- /dev/null +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/de_de/entries/rituals/infusion_ritual.json @@ -0,0 +1,64 @@ +{ + "name": "Elementarritual", + "icon": "betterend:infusion_pedestal", + "read_by_default": true, + "category": "betterend:rituals", + "pages": [ + { + "type": "text", + "text": "Hauche deinen Gegenständen die Macht der Elemente ein." + }, + { + "type": "crafting", + "title": "Der Ritualplatz", + "text": "Zuerst musst Du einen $(bold)Elementarsockel$() sowie 8 weitere Sockel eines $(bold)beliebigen$() Typs herstellen.", + "recipe": "betterend:infusion_pedestal" + }, + { + "type": "image", + "text": "Stelle den Elementarsockel umringt von den restlichen Sockeln (Abb. 2) auf.", + "border": true, + "images": [ + "betterend:textures/images/infusion_ritual/infusion_ritual_start.png", + "betterend:textures/images/infusion_ritual/infusion_ritual_full.png" + ] + }, + { + "type": "image", + "title": "Verschmelzen", + "text": "Damit ist der Ritualplatz fertig, und kann verwendet werden.", + "border": false, + "images": [ + "betterend:textures/images/infusion_ritual/ritual_structure.png" + ] + }, + { + "type": "image", + "text": "Setzte den Hauptwirkstoff umringt von den Katalysatoren", + "border": false, + "images": [ + "betterend:textures/images/infusion_ritual/ritual_ready.png" + ] + }, + { + "type": "text", + "text": "auf den $(bold)Elementarsockel$().$(br2)Alle möglichen Rezepte findest du zum Beispiel mit $(l:https://www.curseforge.com/minecraft/mc-mods/roughly-enough-items)REI$(/l).$(br2)Um den Prozess zu starten, plaziere den Hauptwirkstoff zuletzt oder klicke den $(bold)Elementarsockel$() mit der rechten Moustaste an." + }, + { + "type": "image", + "text": "Die Sockel verschmelzen nun die Zutaten. ", + "border": false, + "images": [ + "betterend:textures/images/infusion_ritual/ritual_started.png" + ] + }, + { + "type": "image", + "text": "Nach einer kurzen Zeit sind die Katalysatoren verbraucht und das Ritual ist beendet.", + "border": false, + "images": [ + "betterend:textures/images/infusion_ritual/ritual_finished.png" + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/en_us/entries/rituals/eternal_ritual.json b/src/main/resources/data/betterend/patchouli_books/guidebook/en_us/entries/rituals/eternal_ritual.json index dc587602..596563f9 100644 --- a/src/main/resources/data/betterend/patchouli_books/guidebook/en_us/entries/rituals/eternal_ritual.json +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/en_us/entries/rituals/eternal_ritual.json @@ -2,7 +2,7 @@ "name": "Eternal Ritual", "icon": "betterend:eternal_pedestal", "read_by_default": true, - "category": "rituals", + "category": "betterend:rituals", "pages": [ { "type": "text", diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/en_us/entries/rituals/infusion_ritual.json b/src/main/resources/data/betterend/patchouli_books/guidebook/en_us/entries/rituals/infusion_ritual.json index a588ebf8..da553170 100644 --- a/src/main/resources/data/betterend/patchouli_books/guidebook/en_us/entries/rituals/infusion_ritual.json +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/en_us/entries/rituals/infusion_ritual.json @@ -2,7 +2,7 @@ "name": "Infusion Ritual", "icon": "betterend:infusion_pedestal", "read_by_default": true, - "category": "rituals", + "category": "betterend:rituals", "pages": [ { "type": "text", diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/categories/biomes.json b/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/categories/biomes.json new file mode 100644 index 00000000..d0d81f6c --- /dev/null +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/categories/biomes.json @@ -0,0 +1,5 @@ +{ + "name": "Biomas", + "description": "En progreso...", + "icon": "betterend:end_mycelium" +} \ No newline at end of file diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/categories/crafting.json b/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/categories/crafting.json new file mode 100644 index 00000000..6faeb86e --- /dev/null +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/categories/crafting.json @@ -0,0 +1,6 @@ +{ + "name": "Crafteo", + "description": "", + "icon": "betterend:iron_hammer", + "sortnum": 2 +} \ No newline at end of file diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/categories/end_veil.json b/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/categories/end_veil.json new file mode 100644 index 00000000..0632316e --- /dev/null +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/categories/end_veil.json @@ -0,0 +1,6 @@ +{ + "name": "Velo del End", + "description": "Mira sin temor a los ojos de los Enderman.", + "icon": "betterend:textures/mob_effect/end_veil.png", + "sortnum": 3 +} \ No newline at end of file diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/categories/rituals.json b/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/categories/rituals.json new file mode 100644 index 00000000..9e5cbe82 --- /dev/null +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/categories/rituals.json @@ -0,0 +1,6 @@ +{ + "name": "Rituales", + "description": "El místico arte del End, ritales secretos que abren nuevos caminos y oportunidades.", + "icon": "betterend:infusion_pedestal", + "sortnum": 1 +} \ No newline at end of file diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/entries/rituals/eternal_ritual.json b/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/entries/rituals/eternal_ritual.json new file mode 100644 index 00000000..ce0d520e --- /dev/null +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/entries/rituals/eternal_ritual.json @@ -0,0 +1,44 @@ +{ + "name": "Ritual Eterno", + "icon": "betterend:eternal_pedestal", + "read_by_default": true, + "category": "rituals", + "pages": [ + { + "type": "text", + "text": "\"Una manera no tan simple de volver al Overworld.\"$(br2)Mientras viajas por el mundo del End, puedes encontrar ruinas antiguas." + }, + { + "type": "image", + "text": "Hay un marco destruido (o no) de $(bold)Flavolita de Runa$() y 6 pedestales alrededor suya.", + "border": false, + "images": [ + "betterend:textures/images/eternal_ritual/portal_structure.png" + ] + }, + { + "type": "text", + "text": "Estos son los restos de portales majestuosos que en algún momento enlazaban los mundos del End y del Overworld.$(br2)Para activar el portal necesitas reconstruir el marco (si está roto)." + }, + { + "type": "image", + "text": "Y colocar 6 $(bold)Cristales Eternos$() en los pedestales.", + "border": false, + "images": [ + "betterend:textures/images/eternal_ritual/portal_frame_full.png" + ] + }, + { + "type": "image", + "text": "Después de que hayas colocado el último cristal, el portal será activado.", + "border": false, + "images": [ + "betterend:textures/images/eternal_ritual/ritual_finished.png" + ] + }, + { + "type": "text", + "text": "$(bold)Flavolita de Runa$() (para reconstruir el marco) y $(bold)Cristales Eternos$() pueden ser obtenidos por $(l:rituals/infusion_ritual)Ritual de Infusión$(/l)." + } + ] +} diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/entries/rituals/infusion_ritual.json b/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/entries/rituals/infusion_ritual.json new file mode 100644 index 00000000..5a6cde5c --- /dev/null +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/es_es/entries/rituals/infusion_ritual.json @@ -0,0 +1,64 @@ +{ + "name": "Ritual de Infusión", + "icon": "betterend:infusion_pedestal", + "read_by_default": true, + "category": "rituals", + "pages": [ + { + "type": "text", + "text": "Infunde objetos con el poder de los elementos." + }, + { + "type": "crafting", + "title": "Preparar la estructura", + "text": "Primero, deberás craftear $(bold)Pedestal de Infusión$() y 8 pedestales de $(bold)cualquier$() otro tipo.", + "recipe": "betterend:infusion_pedestal" + }, + { + "type": "image", + "text": "Luego debes de colocar el Pedestal de Infusión en el centro y los otros pedestales alrededor.", + "border": true, + "images": [ + "betterend:textures/images/infusion_ritual/infusion_ritual_start.png", + "betterend:textures/images/infusion_ritual/infusion_ritual_full.png" + ] + }, + { + "type": "image", + "title": "Infusión", + "text": "Cuando la estructura para el ritual esté lista puedes empezar la infusión.", + "border": false, + "images": [ + "betterend:textures/images/infusion_ritual/ritual_structure.png" + ] + }, + { + "type": "image", + "text": "Coloca el ingrediente principal en el $(bold)Pedestal de Infusión$() y cataliza los otros.", + "border": false, + "images": [ + "betterend:textures/images/infusion_ritual/ritual_ready.png" + ] + }, + { + "type": "text", + "text": "Puedes mirar recetas en el $(l:https://www.curseforge.com/minecraft/mc-mods/roughly-enough-items)REI$(/l).$(br2)Para empezar la Infusión coloca el ingrediente principal al final o dale clic derecho al $(bold)Pedestal de Infusión$()." + }, + { + "type": "image", + "text": "Entonces debes de esperar hasta que el ritual termine.", + "border": false, + "images": [ + "betterend:textures/images/infusion_ritual/ritual_started.png" + ] + }, + { + "type": "image", + "text": "Y obtén el resultado.", + "border": false, + "images": [ + "betterend:textures/images/infusion_ritual/ritual_finished.png" + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/ko_kr/categories/biomes.json b/src/main/resources/data/betterend/patchouli_books/guidebook/ko_kr/categories/biomes.json index 40e3c944..892bf62b 100644 --- a/src/main/resources/data/betterend/patchouli_books/guidebook/ko_kr/categories/biomes.json +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/ko_kr/categories/biomes.json @@ -1,5 +1,5 @@ { - "name": "생물 군계", + "name": "생물군계", "description": "작업 중...", "icon": "betterend:end_mycelium" -} \ No newline at end of file +} diff --git a/src/main/resources/data/betterend/patchouli_books/guidebook/ko_kr/categories/end_veil.json b/src/main/resources/data/betterend/patchouli_books/guidebook/ko_kr/categories/end_veil.json index 81cd0798..51ecc404 100644 --- a/src/main/resources/data/betterend/patchouli_books/guidebook/ko_kr/categories/end_veil.json +++ b/src/main/resources/data/betterend/patchouli_books/guidebook/ko_kr/categories/end_veil.json @@ -1,6 +1,6 @@ { "name": "엔드 베일", - "description": "엔더맨의 눈을 봐도 공격하지 않습니다.", + "description": "엔더맨의 눈을 봐도 공격당하지 않습니다.", "icon": "betterend:textures/mob_effect/end_veil.png", "sortnum": 3 -} \ No newline at end of file +} diff --git a/src/main/resources/data/betterend/structures/biome/umbrella_jungle/house_1.nbt b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/house_1.nbt new file mode 100644 index 00000000..da0d98d1 Binary files /dev/null and b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/house_1.nbt differ diff --git a/src/main/resources/data/betterend/structures/biome/umbrella_jungle/house_2.nbt b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/house_2.nbt new file mode 100644 index 00000000..cbcad4f5 Binary files /dev/null and b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/house_2.nbt differ diff --git a/src/main/resources/data/betterend/structures/biome/umbrella_jungle/jellyshroom_cluster.nbt b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/jellyshroom_cluster.nbt new file mode 100644 index 00000000..c20d8cf4 Binary files /dev/null and b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/jellyshroom_cluster.nbt differ diff --git a/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_1.nbt b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_1.nbt new file mode 100644 index 00000000..cba96af8 Binary files /dev/null and b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_1.nbt differ diff --git a/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_2.nbt b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_2.nbt new file mode 100644 index 00000000..3082767d Binary files /dev/null and b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_2.nbt differ diff --git a/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_3.nbt b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_3.nbt new file mode 100644 index 00000000..8528b77a Binary files /dev/null and b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_3.nbt differ diff --git a/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_4.nbt b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_4.nbt new file mode 100644 index 00000000..af5967d1 Binary files /dev/null and b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_4.nbt differ diff --git a/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_5.nbt b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_5.nbt new file mode 100644 index 00000000..7f22a0b3 Binary files /dev/null and b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_5.nbt differ diff --git a/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_6.nbt b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_6.nbt new file mode 100644 index 00000000..23202848 Binary files /dev/null and b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/ruins_6.nbt differ diff --git a/src/main/resources/data/betterend/structures/biome/umbrella_jungle/structures.json b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/structures.json new file mode 100644 index 00000000..cd3fe4ec --- /dev/null +++ b/src/main/resources/data/betterend/structures/biome/umbrella_jungle/structures.json @@ -0,0 +1,13 @@ +{ + "structures": [ + { "nbt": "jellyshroom_cluster", "offsetY": -1, "terrainMerge": "surface" }, + { "nbt": "house_1", "offsetY": -1, "terrainMerge": "surface" }, + { "nbt": "house_2", "offsetY": 0, "terrainMerge": "surface" }, + { "nbt": "ruins_1", "offsetY": -1, "terrainMerge": "none" }, + { "nbt": "ruins_2", "offsetY": -1, "terrainMerge": "none" }, + { "nbt": "ruins_3", "offsetY": -1, "terrainMerge": "none" }, + { "nbt": "ruins_4", "offsetY": -1, "terrainMerge": "none" }, + { "nbt": "ruins_5", "offsetY": -1, "terrainMerge": "none" }, + { "nbt": "ruins_6", "offsetY": -1, "terrainMerge": "none" } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/c/tags/blocks/bookshelves.json b/src/main/resources/data/c/tags/blocks/bookshelves.json deleted file mode 100644 index 98dee3c8..00000000 --- a/src/main/resources/data/c/tags/blocks/bookshelves.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": "false", - "values": [ - "minecraft:bookshelf" - ] -} \ No newline at end of file diff --git a/src/main/resources/data/fabric/tags/items/hammers.json b/src/main/resources/data/fabric/tags/items/hammers.json deleted file mode 100644 index 847bbc95..00000000 --- a/src/main/resources/data/fabric/tags/items/hammers.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "replace": false, - "values": [ - "betterend:iron_hammer", - "betterend:golden_hammer", - "betterend:diamond_hammer", - "betterend:netherite_hammer", - "betterend:terminite_hammer", - "betterend:aeternium_hammer" - ] -} \ No newline at end of file diff --git a/src/main/resources/data/trinkets/entities/betterend.json b/src/main/resources/data/trinkets/entities/betterend.json new file mode 100644 index 00000000..1a728950 --- /dev/null +++ b/src/main/resources/data/trinkets/entities/betterend.json @@ -0,0 +1,8 @@ +{ + "entities": [ + "player" + ], + "slots": [ + "chest/cape" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/trinkets/tags/items/chest/cape.json b/src/main/resources/data/trinkets/tags/items/chest/cape.json new file mode 100644 index 00000000..a0607002 --- /dev/null +++ b/src/main/resources/data/trinkets/tags/items/chest/cape.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "betterend:elytra_crystalite", + "betterend:elytra_armored" + ] +} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index b880fc77..414e0a1d 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,56 +1,72 @@ { - "schemaVersion": 1, - "id": "betterend", - "version": "${version}", - - "name": "Better End", - "description": "More content for The End dimension, including new biomes, plants, mobs, mechanics, terrain generation and more.\nMade by:\n- paulevs (code & art)\n- Bulldog83 (code & art)\n- Edos (building)\n- Yuki (art)\n- Seaward (art)\n- Firel (music)\n", - "authors": [ - "paulevs (code & art)", - "Bulldog83 (code & art)", - "Edos (building)", - "Yuki (art)", - "Seaward (art)", - "Firel (music)" - ], - "contact": { - "homepage": "https://www.curseforge.com/minecraft/mc-mods/betterend", - "issues": "https://github.com/paulevsGitch/BetterEnd/issues", - "sources": "https://github.com/paulevsGitch/BetterEnd" - }, - - "license": "MIT", - "icon": "assets/betterend/icon.png", - - "environment": "*", - "entrypoints": { - "main": [ - "ru.betterend.BetterEnd" - ], - "client": [ - "ru.betterend.client.BetterEndClient" - ], - "rei_plugins": [ - "ru.betterend.integration.rei.REIPlugin" - ], - "rei_containers": [ - "ru.betterend.integration.rei.REIContainer" - ] - }, - "mixins": [ - "betterend.mixins.common.json", - "betterend.mixins.client.json" - ], - - "depends": { - "fabricloader": ">=0.11.0", - "fabric": ">=0.32.0", - "minecraft": ">=1.16.4", - "bclib": ">=0.1.38" - }, - "suggests": { - "byg": ">=1.1.3", - "blockus": ">=2.0.2", - "nourish": ">=1.2.0" - } + "schemaVersion": 1, + "id": "betterend", + "version": "${version}", + "name": "Better End", + "description": "More content for The End dimension, including new biomes, plants, mobs, mechanics, terrain generation and more.\nMade by:\n- paulevs (code & art)\n- Bulldog83 (code & art)\n- Edos (building)\n- Yuki (art)\n- Seaward (art)\n- Firel (music)\n", + "authors": [ + "Quiqueck (code)", + "paulevs (code & art)", + "Bulldog83 (code & art)", + "Edos (building)", + "Yuki (art)", + "Seaward (art)", + "Firel (music)" + ], + "contact": { + "homepage": "https://www.curseforge.com/minecraft/mc-mods/betterend", + "issues": "https://github.com/quiqueck/BetterEnd/issues", + "sources": "https://github.com/quiqueck/BetterEnd" + }, + "license": "MIT (CC BY-NC-SA 4.0 for some Assets)", + "icon": "assets/betterend/icon.png", + "environment": "*", + "entrypoints": { + "main": [ + "org.betterx.betterend.BetterEnd" + ], + "client": [ + "org.betterx.betterend.client.BetterEndClient" + ], + "rei_client": [ + "org.betterx.betterend.integration.rei.REIPlugin" + ], + "jei_mod_plugin": [ + "org.betterx.betterend.integration.jei.JEIPlugin" + ], + "emi": [ + "org.betterx.betterend.integration.emi.EMIPlugin" + ] + }, + "accessWidener": "betterend.accesswidener", + "mixins": [ + "betterend.mixins.common.json", + "betterend.mixins.client.json", + "betterend.mixins.shadow.json" + ], + "depends": { + "fabricloader": ">=0.14.6", + "fabric": ">=0.56.0", + "minecraft": [ + "1.19", + "1.19.1", + "1.19.2" + ], + "bclib": "2.0.x" + }, + "breaks": { + "bclib": "<2.0.20" + }, + "suggests": { + "byg": ">=2.0.0", + "blockus": ">=2.0.2", + "nourish": ">=1.2.0", + "colored_lights": ">=1.0.3", + "trinkets": ">=3.4.0" + }, + "custom": { + "bclib": { + "updater_icon": "icon_updater.png" + } + } }