Compare commits

..

No commits in common. "hotfix/bclib_2.0.x" and "1.16.5" have entirely different histories.

2236 changed files with 40684 additions and 57151 deletions

View file

@ -1,84 +0,0 @@
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

View file

@ -1,18 +0,0 @@
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

View file

@ -1 +0,0 @@
blank_issues_enabled: true

7
.gitignore vendored
View file

@ -27,10 +27,5 @@ bin/
# fabric
run/
run-client/
run-server/
output/
*.getBlock("log")
Convert.class
ModelPart.class
libs/
*.log

View file

@ -1,161 +0,0 @@
class ModelPart {
static java.util.ArrayList<ModelPart> 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);
}
}

View file

@ -19,7 +19,3 @@ 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.

View file

@ -1,9 +0,0 @@
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

View file

@ -1,19 +1,17 @@
[![](https://jitpack.io/v/quiqueck/BetterEnd.svg)](https://jitpack.io/#quiqueck/BetterEnd)
[![](https://jitpack.io/v/paulevsGitch/BetterEnd.svg)](https://jitpack.io/#paulevsGitch/BetterEnd)
# Better End
Better End Mod for Fabric, MC 1.19
Better End Mod for Fabric, MC 1.16.4
Importing:
* Clone repo
* Edit gradle.properties if necessary
* Run command line in folder: gradlew genSources idea (or eclipse)
* Run command line in folder: gradlew genSources eclipse (or Another-IDE-Name)
* 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

View file

@ -5,75 +5,75 @@ buildscript {
}
plugins {
id 'fabric-loom' version "${loom_version}"
id 'idea'
id 'eclipse'
id 'fabric-loom' version '0.7-SNAPSHOT'
id 'maven-publish'
}
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
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.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 loom.officialMojangMappings()
mappings minecraft.officialMojangMappings()
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_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}"
useApi "vazkii.patchouli:Patchouli:1.16.4-${project.patchouli_version}"
useApi "com.github.paulevsGitch:BCLib:${project.bclib_version}"
useOptional "me.shedaniel:RoughlyEnoughItems:${project.rei_version}"
useOptional "me.shedaniel:RoughlyEnoughItems-api:${project.rei_version}"
//useOptional "grondag:canvas-mc116:${project.canvas_version}"
}
modCompileOnly "me.shedaniel:RoughlyEnoughItems-fabric:${project.rei_version}"
modCompileOnly "me.shedaniel:RoughlyEnoughItems-api-fabric:${project.rei_version}"
// 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 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"
}
}
}
//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}"
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"
}
}
}
processResources {
println "Version: ${project.version}"
inputs.property "version", project.version
filesMatching("fabric.mod.json") {
duplicatesStrategy = 'WARN'
from(sourceSets.main.resources.srcDirs) {
include "fabric.mod.json"
expand "version": project.version
}
}
@ -83,7 +83,6 @@ processResources {
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
it.options.release = 17
}
javadoc {
@ -103,16 +102,8 @@ task sourcesJar(type: Jar, dependsOn: classes) {
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.ASSETS"
}
artifacts {
@ -132,11 +123,11 @@ task release(dependsOn: [remapJar, sourcesJar, javadocJar]) {
doLast {
def github = GitHub.connectUsingOAuth(env.GITHUB_TOKEN as String)
def repository = github.getRepository("quiqueck/BetterEnd")
def repository = github.getRepository("paulevsGitch/BetterEnd")
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.body("A changelog can be found at https://github.com/paulevsGitch/BetterEnd/commits")
releaseBuilder.commitish("master")
def ghRelease = releaseBuilder.create()
@ -147,21 +138,21 @@ task release(dependsOn: [remapJar, sourcesJar, javadocJar]) {
}
// 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()
// }
//}

View file

@ -1,22 +1,21 @@
# 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
# check these on https://fabricmc.net/use
minecraft_version=1.16.5
yarn_mappings=6
loader_version=0.11.3
# Mod Properties
mod_version=2.0.12
maven_group=org.betterx.betterend
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=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
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

Binary file not shown.

View file

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

259
gradlew vendored
View file

@ -1,7 +1,7 @@
#!/bin/sh
#!/usr/bin/env sh
#
# Copyright © 2015-2021 the original authors.
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -17,113 +17,78 @@
#
##############################################################################
#
# 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/.
#
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
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
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
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
APP_BASE_NAME=`basename "$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 ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
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
@ -132,7 +97,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
@ -140,95 +105,79 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
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
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
# 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.
# 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" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
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
# 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" ;;
esac
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.
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
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' ' '
)" '"$@"'
# 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"
exec "$JAVACMD" "$@"

22
gradlew.bat vendored
View file

@ -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 execute
if "%ERRORLEVEL%" == "0" goto init
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 execute
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@ -64,14 +64,28 @@ 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 %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell

View file

@ -1,6 +0,0 @@
# 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

View file

@ -1,16 +1,7 @@
{
"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
}
"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 }
}
}

View file

@ -1,6 +1,5 @@
pluginManagement {
repositories {
jcenter()
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
@ -8,39 +7,3 @@ 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'
}

View file

@ -1,91 +0,0 @@
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);
}
}

View file

@ -1,37 +0,0 @@
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
);
}
}

View file

@ -1,38 +0,0 @@
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();
}
}

View file

@ -1,27 +0,0 @@
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());
}
}

View file

@ -1,30 +0,0 @@
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());
}
}

View file

@ -1,15 +0,0 @@
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));
}
}

View file

@ -1,22 +0,0 @@
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;
}
}

View file

@ -1,89 +0,0 @@
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<ItemStack> 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);
}
}

View file

@ -1,134 +0,0 @@
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<ItemStack> 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)
};
}
}

View file

@ -1,24 +0,0 @@
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<BlockProperties.TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> stateManager) {
stateManager.add(SHAPE);
}
@Override
protected boolean isTerrain(BlockState state) {
return state.getBlock() == EndBlocks.END_MOSS || state.getBlock() == EndBlocks.END_MYCELIUM;
}
}

View file

@ -1,59 +0,0 @@
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<Block, BlockState> stateManager) {
stateManager.add(NATURAL);
}
}

View file

@ -1,81 +0,0 @@
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);
}
}

View file

@ -1,54 +0,0 @@
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<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
return Lists.newArrayList(new ItemStack(this));
}
}

View file

@ -1,108 +0,0 @@
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<Block, BlockState> 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));
}
}
}

View file

@ -1,54 +0,0 @@
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;
}
}

View file

@ -1,49 +0,0 @@
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<ItemStack> 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);
}
}

View file

@ -1,87 +0,0 @@
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<String, String> textures = Maps.newHashMap();
textures.put("%glow%", getGlowTexture());
textures.put("%metal%", getMetalTexture(resourceLocation));
Optional<String> 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";
}
}

View file

@ -1,40 +0,0 @@
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";
}
}

View file

@ -1,49 +0,0 @@
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)
);
}
}
}

View file

@ -1,72 +0,0 @@
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<Block, BlockState> 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<ItemStack> 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);
}
}

View file

@ -1,81 +0,0 @@
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;
}
}

View file

@ -1,120 +0,0 @@
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<Direction, VoxelShape> 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<String> 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<ResourceLocation, UnbakedModel> 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));
}
}

View file

@ -1,19 +0,0 @@
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;
}
}

View file

@ -1,17 +0,0 @@
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;
}
}

View file

@ -1,17 +0,0 @@
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;
}
}

View file

@ -1,122 +0,0 @@
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<Block, BlockState> 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;
}
}

View file

@ -1,39 +0,0 @@
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<ItemStack> 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();
}
}
}

View file

@ -1,28 +0,0 @@
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<DragonTreeFeature, NoneFeatureConfiguration> {
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;
}
}

View file

@ -1,102 +0,0 @@
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<ItemStack> 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());
}
}

View file

@ -1,131 +0,0 @@
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<HydraluxShape> HYDRALUX_SHAPE = EnumProperty.create("shape", HydraluxShape.class);
public static final EnumProperty<PedestalState> PEDESTAL_STATE = EnumProperty.create("state", PedestalState.class);
public static final EnumProperty<CactusBottom> 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;
}
}
}

View file

@ -1,125 +0,0 @@
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<TripleShape> 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<Block, BlockState> 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<ItemStack> 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;
}
}

View file

@ -1,53 +0,0 @@
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);
}
}

View file

@ -1,60 +0,0 @@
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<ItemStack> 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);
}
}

View file

@ -1,82 +0,0 @@
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<Direction> HORIZONTAL_FACING = BlockStateProperties.HORIZONTAL_FACING;
public static final EnumProperty<TripleShape> 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<Block, BlockState> 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);
}
}

View file

@ -1,138 +0,0 @@
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);
}
}

View file

@ -1,112 +0,0 @@
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<Direction> FACING = BlockStateProperties.FACING;
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public static final BooleanProperty LEAF = BooleanProperty.create("leaf");
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
private static final Map<Axis, VoxelShape> 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<Block, BlockState> 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));
}
}

View file

@ -1,32 +0,0 @@
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<String, String> createTexturesMap() {
ResourceLocation blockId = Registry.BLOCK.getKey(parent);
String name = blockId.getPath();
Map<String, String> 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;
}
}

View file

@ -1,228 +0,0 @@
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<Block, BlockState> 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<Entity> 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<DimensionType> 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);
}
}

View file

@ -1,188 +0,0 @@
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<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
List<ItemStack> 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<Block, BlockState> 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 <T extends BlockEntity> BlockEntityTicker<T> getTicker(
Level level,
BlockState blockState,
BlockEntityType<T> blockEntityType
) {
return level.isClientSide() ? null : createTickerHelper(
blockEntityType,
EndBlockEntities.END_STONE_SMELTER,
EndStoneSmelterBlockEntity::tick
);
}
}

View file

@ -1,30 +0,0 @@
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;
}
}

View file

@ -1,52 +0,0 @@
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<ItemStack> 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<TagKey<Block>> blockTags, List<TagKey<Item>> itemTags) {
blockTags.add(CommonBlockTags.END_STONES);
}
}

View file

@ -1,145 +0,0 @@
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<ItemStack> 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<ItemStack> 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<Block, BlockState> 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;
}
}

View file

@ -1,11 +0,0 @@
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));
}
}

View file

@ -1,17 +0,0 @@
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));
}
}

View file

@ -1,52 +0,0 @@
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<Direction, VoxelShape> 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));
}
}

View file

@ -1,62 +0,0 @@
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<ItemStack> 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);
}
}

View file

@ -1,44 +0,0 @@
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);
}
}

View file

@ -1,460 +0,0 @@
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<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(PLANT_ID, SOIL_ID, POT_LIGHT);
}
@Override
public List<ItemStack> getDrops(BlockState state, Builder builder) {
List<ItemStack> 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<String, Integer> reservedPlantsIDs = Maps.newHashMap();
Map<String, Integer> 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<String, Integer> 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<String> pattern = PatternsHelper.createJson(Patterns.BLOCK_FLOWER_POT, blockId);
return ModelsHelper.fromPattern(pattern);
}
@Override
@Environment(EnvType.CLIENT)
public UnbakedModel getModelVariant(
ResourceLocation stateId,
BlockState blockState,
Map<ResourceLocation, UnbakedModel> 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<String, String> textures = Maps.newHashMap();
textures.put("%modid%", loc.getNamespace());
textures.put("%texture%", loc.getPath());
Optional<String> 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<String, String> 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<String> 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<String, String> textures = Maps.newHashMap();
textures.put("%modid%", loc.getNamespace());
textures.put("%texture%", loc.getPath());
Optional<String> 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<String> 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));
}
}

View file

@ -1,17 +0,0 @@
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));
}
}

View file

@ -1,61 +0,0 @@
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<Block, BlockState> stateManager) {
stateManager.add(NATURAL);
}
}

View file

@ -1,37 +0,0 @@
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<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> 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);
}
}

View file

@ -1,82 +0,0 @@
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);
}
}

View file

@ -1,84 +0,0 @@
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<Block, BlockState> 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<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
return BaseLeavesBlock.getLeaveDrops(this, EndBlocks.HELIX_TREE_SAPLING, builder, 16, 32);
}
}

View file

@ -1,28 +0,0 @@
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<HelixTreeFeature, NoneFeatureConfiguration> {
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;
}
}

View file

@ -1,96 +0,0 @@
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<HydraluxShape> SHAPE = EndBlockProperties.HYDRALUX_SHAPE;
public HydraluxBlock() {
super(baseUnderwaterPlantSettings()
.lightLevel((state) -> state.getValue(SHAPE).hasGlow() ? 15 : 0)
);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> 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<ItemStack> 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();
}
}

View file

@ -1,35 +0,0 @@
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) {
}
}

View file

@ -1,43 +0,0 @@
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<String> pattern = Patterns.createJson(Patterns.BLOCK_PETAL_COLORED, path, path);
return ModelsHelper.fromPattern(pattern);
}
}

View file

@ -1,75 +0,0 @@
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);
}
}

View file

@ -1,161 +0,0 @@
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<Block, BlockState> 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 <T extends BlockEntity> BlockEntityTicker<T> getTicker(
Level level,
BlockState blockState,
BlockEntityType<T> blockEntityType
) {
return BlockEntityHydrothermalVent::tick;
}
}

View file

@ -1,103 +0,0 @@
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 <T extends BlockEntity> BlockEntityTicker<T> getTicker(
Level level,
BlockState blockState,
BlockEntityType<T> 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);
}
}

View file

@ -1,107 +0,0 @@
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<Block, BlockState> stateManager) {
stateManager.add(COLOR);
}
@Override
public BCLRenderLayer getRenderLayer() {
return BCLRenderLayer.TRANSLUCENT;
}
@Override
@SuppressWarnings("deprecation")
public List<ItemStack> 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<String> 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;
};
}
}

View file

@ -1,29 +0,0 @@
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<LacugroveFeature, NoneFeatureConfiguration> {
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;
}
}

View file

@ -1,76 +0,0 @@
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<PentaShape> SHAPE = BlockProperties.PENTA_SHAPE;
public static final IntegerProperty ROTATION = BlockProperties.ROTATION;
public LanceleafBlock() {
super();
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> 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<ItemStack> 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));
}
}

View file

@ -1,61 +0,0 @@
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);
}
}

View file

@ -1,70 +0,0 @@
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<TripleShape> 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<Block, BlockState> 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;
}
}

View file

@ -1,28 +0,0 @@
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<LucerniaFeature, NoneFeatureConfiguration> {
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;
}
}

View file

@ -1,117 +0,0 @@
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<EndBlockProperties.LumecornShape> 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<Block, BlockState> 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<ItemStack> 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);
}
}

View file

@ -1,39 +0,0 @@
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<NoneFeatureConfiguration>) (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);
}
}

View file

@ -1,141 +0,0 @@
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<Tuple<BlockPos, Integer>> queue = Lists.newLinkedList();
queue.add(new Tuple<>(pos, 0));
int i = 0;
while (!queue.isEmpty()) {
Tuple<BlockPos, Integer> 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))
));
}
}

View file

@ -1,130 +0,0 @@
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);
}
}

View file

@ -1,13 +0,0 @@
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));
}
}

View file

@ -1,69 +0,0 @@
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<ItemStack> 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;
}
}
}

View file

@ -1,47 +0,0 @@
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<Block, BlockState> builder) {
builder.add(TRANSITION);
}
@Override
public void addTags(List<TagKey<Block>> blockTags, List<TagKey<Item>> itemTags) {
blockTags.add(MineableTags.AXE);
}
}

View file

@ -1,29 +0,0 @@
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<MossyGlowshroomFeature, NoneFeatureConfiguration> {
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;
}
}

View file

@ -1,68 +0,0 @@
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<ItemStack> 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;
}
}
}

View file

@ -1,50 +0,0 @@
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;
}
}

View file

@ -1,59 +0,0 @@
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<ItemStack> 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;
}
}

View file

@ -1,13 +0,0 @@
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));
}
}

View file

@ -1,438 +0,0 @@
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<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
public static final EnumProperty<CactusBottom> CACTUS_BOTTOM = EndBlockProperties.CACTUS_BOTTOM;
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public static final DirectionProperty FACING = BlockStateProperties.FACING;
private static final EnumMap<Direction, VoxelShape> BIG_SHAPES_OPEN = Maps.newEnumMap(Direction.class);
private static final EnumMap<Direction, VoxelShape> MEDIUM_SHAPES_OPEN = Maps.newEnumMap(Direction.class);
private static final EnumMap<Direction, VoxelShape> SMALL_SHAPES_OPEN = Maps.newEnumMap(Direction.class);
private static final EnumMap<Axis, VoxelShape> BIG_SHAPES = Maps.newEnumMap(Axis.class);
private static final EnumMap<Axis, VoxelShape> MEDIUM_SHAPES = Maps.newEnumMap(Axis.class);
private static final EnumMap<Axis, VoxelShape> 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<Block, BlockState> 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<MutableBlockPos> 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<MutableBlockPos> 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";
}
}

View file

@ -1,78 +0,0 @@
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<ResourceLocation, UnbakedModel> modelCache
) {
return this.getBlockModel(stateId, blockState);
}
}

View file

@ -1,34 +0,0 @@
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<String, String> createTexturesMap() {
ResourceLocation blockId = Registry.BLOCK.getKey(parent);
String name = blockId.getPath().replace("_block", "");
return new HashMap<String, String>() {
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);
}
};
}
}

View file

@ -1,51 +0,0 @@
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;
}
}

View file

@ -1,28 +0,0 @@
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<PythadendronTreeFeature, NoneFeatureConfiguration> {
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;
}
}

Some files were not shown because too many files have changed in this diff Show more