Compare commits
27 Commits
1.15.2-For
...
1.16.5-For
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78c7b53595 | ||
|
|
3a04099fc2 | ||
|
|
d6038dd072 | ||
|
|
4ebb7f2d35 | ||
|
|
14a8600552 | ||
|
|
b3ffb7e4d6 | ||
|
|
fc7f2be15c | ||
|
|
b7bdd438e4 | ||
|
|
65c9596a14 | ||
|
|
25b8896a25 | ||
|
|
f1f811219e | ||
|
|
57dc83f1af | ||
|
|
180c2bf230 | ||
|
|
ff89aa7a13 | ||
|
|
25cea8633c | ||
|
|
eeabc1922e | ||
|
|
d7e16d603f | ||
|
|
b1a08ab500 | ||
|
|
fae9e9dfa9 | ||
|
|
512cd786f7 | ||
|
|
b96a17fdb9 | ||
|
|
3d78ecce22 | ||
|
|
6219e9353d | ||
|
|
e3eb222d93 | ||
|
|
8f82fefbb7 | ||
|
|
8a303a1a29 | ||
|
|
49d4f8aa31 |
@@ -1,26 +1,20 @@
|
||||
plugins {
|
||||
kotlin("jvm").version("1.3.61")
|
||||
id("net.minecraftforge.gradle").version("3.0.194")
|
||||
kotlin("jvm").version("1.4.20")
|
||||
id("net.minecraftforge.gradle").version("4.1.12")
|
||||
id("org.spongepowered.mixin").version("0.7-SNAPSHOT")
|
||||
}
|
||||
apply(plugin = "org.spongepowered.mixin")
|
||||
|
||||
repositories {
|
||||
maven("http://files.minecraftforge.net/maven")
|
||||
maven("https://files.minecraftforge.net/maven")
|
||||
maven("https://repo.spongepowered.org/maven")
|
||||
maven("https://minecraft.curseforge.com/api/maven")
|
||||
maven("https://maven.shedaniel.me/")
|
||||
maven("https://www.cursemaven.com")
|
||||
maven("https://thedarkcolour.github.io/KotlinForForge/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"minecraft"("net.minecraftforge:forge:${properties["mcVersion"]}-${properties["forgeVersion"]}")
|
||||
|
||||
"api"(fg.deobf("curse.maven:clothconfig-348521:2938583"))
|
||||
|
||||
"implementation"(fg.deobf("curse.maven:biomesoplenty-220318:2988999"))
|
||||
"implementation"("kottle:Kottle:${properties["kottleVersion"]}")
|
||||
// "implementation"("org.spongepowered:mixin:0.8-SNAPSHOT")
|
||||
"implementation"("thedarkcolour:kotlinforforge:1.7.0")
|
||||
"api"(fg.deobf("curse.maven:clothconfig-348521:3311352"))
|
||||
}
|
||||
|
||||
configurations["annotationProcessor"].extendsFrom(configurations["implementation"])
|
||||
@@ -51,7 +45,6 @@ kotlin {
|
||||
target.compilations.configureEach {
|
||||
kotlinOptions.jvmTarget = "1.8"
|
||||
kotlinOptions.freeCompilerArgs += listOf("-Xno-param-assertions", "-Xno-call-assertions")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@ org.gradle.daemon=false
|
||||
group = com.github.octarine-noise
|
||||
jarName = BetterFoliage-Forge
|
||||
|
||||
version = 2.6.1
|
||||
version = 2.6.5
|
||||
|
||||
mcVersion = 1.15.2
|
||||
forgeVersion = 31.2.44
|
||||
mappingsChannel = snapshot
|
||||
mappingsVersion = 20200514-1.15.1
|
||||
mcVersion = 1.16.5
|
||||
forgeVersion = 36.1.17
|
||||
mappingsChannel = official
|
||||
mappingsVersion = 1.16.5
|
||||
|
||||
kottleVersion = 1.4.0
|
||||
#kottleVersion = 1.4.0
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
53
gradlew
vendored
53
gradlew
vendored
@@ -1,5 +1,21 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# 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.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
|
||||
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=""
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
@@ -66,6 +82,7 @@ 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
|
||||
@@ -109,10 +126,11 @@ if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
@@ -138,19 +156,19 @@ if $cygwin ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
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" ;;
|
||||
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
|
||||
|
||||
@@ -159,14 +177,9 @@ save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# 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"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
43
gradlew.bat
vendored
43
gradlew.bat
vendored
@@ -1,3 +1,19 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -35,7 +54,7 @@ goto fail
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
@@ -45,28 +64,14 @@ echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
maven("http://files.minecraftforge.net/maven")
|
||||
maven("https://files.minecraftforge.net/maven")
|
||||
maven("https://repo.spongepowered.org/maven")
|
||||
gradlePluginPortal()
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
*/
|
||||
@Mixin(Block.class)
|
||||
public class MixinBlock {
|
||||
private static final String shouldSideBeRendered = "Lnet/minecraft/block/Block;shouldSideBeRendered(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Z";
|
||||
private static final String shouldSideBeRendered = "Lnet/minecraft/block/Block;shouldRenderFace(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Z";
|
||||
private static final String getVoxelShape = "Lnet/minecraft/block/BlockState;func_215702_a(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Lnet/minecraft/util/math/shapes/VoxelShape;";
|
||||
private static final String getFaceOcclusionShape = "Lnet/minecraft/block/BlockState;getFaceOcclusionShape(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;)Lnet/minecraft/util/math/shapes/VoxelShape;";
|
||||
private static final String isOpaqueCube = "Lnet/minecraft/block/Block;isOpaqueCube(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)Z";
|
||||
|
||||
@@ -8,7 +8,7 @@ import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.ILightReader;
|
||||
import net.minecraft.world.IBlockDisplayReader;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -19,12 +19,12 @@ import java.util.Random;
|
||||
@Mixin(BlockModelRenderer.class)
|
||||
public class MixinBlockModelRenderer {
|
||||
|
||||
private static final String renderModel = "Lnet/minecraft/client/renderer/BlockModelRenderer;renderModel(Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||
private static final String renderModelFlat = "Lnet/minecraft/client/renderer/BlockModelRenderer;renderModelFlat(Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||
private static final String renderModelSmooth = "Lnet/minecraft/client/renderer/BlockModelRenderer;renderModelSmooth(Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||
private static final String renderModel = "Lnet/minecraft/client/renderer/BlockModelRenderer;renderModel(Lnet/minecraft/world/IBlockDisplayReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||
private static final String renderModelFlat = "Lnet/minecraft/client/renderer/BlockModelRenderer;renderModelFlat(Lnet/minecraft/world/IBlockDisplayReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||
private static final String renderModelSmooth = "Lnet/minecraft/client/renderer/BlockModelRenderer;renderModelSmooth(Lnet/minecraft/world/IBlockDisplayReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||
|
||||
@Redirect(method = renderModel, at = @At(value = "INVOKE", target = renderModelSmooth), remap = false)
|
||||
public boolean onRenderModelSmooth(BlockModelRenderer renderer, ILightReader world, IBakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, IVertexBuilder buffer, boolean checkSides, Random random, long rand, int combinedOverlay, IModelData modelData) {
|
||||
public boolean onRenderModelSmooth(BlockModelRenderer renderer, IBlockDisplayReader world, IBakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, IVertexBuilder buffer, boolean checkSides, Random random, long rand, int combinedOverlay, IModelData modelData) {
|
||||
if (model instanceof SpecialRenderModel)
|
||||
return RenderCtxVanilla.render(renderer, world, (SpecialRenderModel) model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData, true);
|
||||
else
|
||||
@@ -32,10 +32,10 @@ public class MixinBlockModelRenderer {
|
||||
}
|
||||
|
||||
@Redirect(method = renderModel, at = @At(value = "INVOKE", target = renderModelFlat), remap = false)
|
||||
public boolean onRenderModelFlat(BlockModelRenderer renderer, ILightReader world, IBakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, IVertexBuilder buffer, boolean checkSides, Random random, long rand, int combinedOverlay, IModelData modelData) {
|
||||
public boolean onRenderModelFlat(BlockModelRenderer renderer, IBlockDisplayReader world, IBakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, IVertexBuilder buffer, boolean checkSides, Random random, long rand, int combinedOverlay, IModelData modelData) {
|
||||
if (model instanceof SpecialRenderModel)
|
||||
return RenderCtxVanilla.render(renderer, world, (SpecialRenderModel) model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData, false);
|
||||
else
|
||||
return renderer.renderModelSmooth(world, model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData);
|
||||
return renderer.renderModelFlat(world, model, state, pos, matrixStack, buffer, checkSides, random, rand, combinedOverlay, modelData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package mods.betterfoliage.mixin;
|
||||
|
||||
import mods.betterfoliage.Hooks;
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import org.spongepowered.asm.mixin.Debug;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Coerce;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
/**
|
||||
@@ -14,14 +17,15 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
*
|
||||
* Needed to avoid excessive darkening of Round Logs at the corners, now that they are not full blocks.
|
||||
*/
|
||||
@Mixin(BlockState.class)
|
||||
@Mixin(AbstractBlock.AbstractBlockState.class)
|
||||
@SuppressWarnings({"deprecation"})
|
||||
public class MixinBlockState {
|
||||
private static final String callFrom = "Lnet/minecraft/block/BlockState;getAmbientOcclusionLightValue(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)F";
|
||||
private static final String callTo = "Lnet/minecraft/block/Block;getAmbientOcclusionLightValue(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)F";
|
||||
private static final String callFrom = "Lnet/minecraft/block/AbstractBlock$AbstractBlockState;getShadeBrightness(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)F";
|
||||
// why is the INVOKEVIRTUAL target class Block in the bytecode, not AbstractBlock?
|
||||
private static final String callTo = "Lnet/minecraft/block/Block;getShadeBrightness(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)F";
|
||||
|
||||
@Redirect(method = callFrom, at = @At(value = "INVOKE", target = callTo))
|
||||
float getAmbientOcclusionValue(Block block, BlockState state, IBlockReader reader, BlockPos pos) {
|
||||
return Hooks.getAmbientOcclusionLightValueOverride(block.getAmbientOcclusionLightValue(state, reader, pos), state);
|
||||
return Hooks.getAmbientOcclusionLightValueOverride(block.getShadeBrightness(state, reader, pos), state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,34 @@
|
||||
package mods.betterfoliage.mixin;
|
||||
|
||||
import mods.betterfoliage.Hooks;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@Mixin(ClientWorld.class)
|
||||
public class MixinClientWorld {
|
||||
|
||||
private static final String worldAnimateTick = "Lnet/minecraft/client/world/ClientWorld;animateTick(IIIILjava/util/Random;ZLnet/minecraft/util/math/BlockPos$Mutable;)V";
|
||||
private static final String worldAnimateTick = "Lnet/minecraft/client/world/ClientWorld;doAnimateTick(IIIILjava/util/Random;ZLnet/minecraft/util/math/BlockPos$Mutable;)V";
|
||||
private static final String blockAnimateTick = "Lnet/minecraft/block/Block;animateTick(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Ljava/util/Random;)V";
|
||||
|
||||
private static final String worldNotify = "Lnet/minecraft/client/world/ClientWorld;notifyBlockUpdate(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;I)V";
|
||||
private static final String rendererNotify = "Lnet/minecraft/client/renderer/WorldRenderer;notifyBlockUpdate(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;I)V";
|
||||
private static final String worldNotify = "Lnet/minecraft/client/world/ClientWorld;sendBlockUpdated(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;I)V";
|
||||
private static final String rendererNotify = "Lnet/minecraft/client/renderer/WorldRenderer;blockChanged(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;I)V";
|
||||
|
||||
/**
|
||||
* Inject a callback to call for every random display tick. Used for adding custom particle effects to blocks.
|
||||
*/
|
||||
@Redirect(method = worldAnimateTick, at = @At(value = "INVOKE", target = blockAnimateTick))
|
||||
void onAnimateTick(Block block, BlockState state, World world, BlockPos pos, Random random) {
|
||||
Hooks.onRandomDisplayTick(block, state, world, pos, random);
|
||||
block.animateTick(state, world, pos, random);
|
||||
@Inject(method = worldAnimateTick, at = @At(value = "INVOKE", target = blockAnimateTick))
|
||||
void onAnimateTick(int x, int y, int z, int range, Random random, boolean doBarrier, BlockPos.Mutable pos, CallbackInfo ci) {
|
||||
Hooks.onRandomDisplayTick((ClientWorld) (Object) this, pos, random);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,6 +38,6 @@ public class MixinClientWorld {
|
||||
@Redirect(method = worldNotify, at = @At(value = "INVOKE", target = rendererNotify))
|
||||
void onClientBlockChanged(WorldRenderer renderer, IBlockReader world, BlockPos pos, BlockState oldState, BlockState newState, int flags) {
|
||||
Hooks.onClientBlockChanged((ClientWorld) world, pos, oldState, newState, flags);
|
||||
renderer.notifyBlockUpdate(world, pos, oldState, newState, flags);
|
||||
renderer.blockChanged(world, pos, oldState, newState, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package mods.betterfoliage.mixin;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxForge;
|
||||
import mods.betterfoliage.model.SpecialRenderModel;
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxForge;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.ILightReader;
|
||||
import net.minecraft.world.IBlockDisplayReader;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.pipeline.ForgeBlockModelRenderer;
|
||||
import net.minecraftforge.client.model.pipeline.VertexLighterFlat;
|
||||
@@ -19,14 +19,14 @@ import java.util.Random;
|
||||
@Mixin(ForgeBlockModelRenderer.class)
|
||||
public class MixinForgeBlockModelRenderer {
|
||||
|
||||
private static final String renderModelFlat = "renderModelFlat(Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||
private static final String renderModelSmooth = "renderModelSmooth(Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||
private static final String render = "Lnet/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer;render(Lnet/minecraftforge/client/model/pipeline/VertexLighterFlat;Lnet/minecraft/world/ILightReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;ZLjava/util/Random;JLnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||
private static final String renderModelFlat = "Lnet/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer;renderModelFlat(Lnet/minecraft/world/IBlockDisplayReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||
private static final String renderModelSmooth = "Lnet/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer;renderModelSmooth(Lnet/minecraft/world/IBlockDisplayReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;Lcom/mojang/blaze3d/vertex/IVertexBuilder;ZLjava/util/Random;JILnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||
private static final String render = "Lnet/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer;render(Lnet/minecraftforge/client/model/pipeline/VertexLighterFlat;Lnet/minecraft/world/IBlockDisplayReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lcom/mojang/blaze3d/matrix/MatrixStack;ZLjava/util/Random;JLnet/minecraftforge/client/model/data/IModelData;)Z";
|
||||
|
||||
@Redirect(method = {renderModelFlat, renderModelSmooth}, at = @At(value = "INVOKE", target = render), remap = false)
|
||||
public boolean render(
|
||||
VertexLighterFlat lighter,
|
||||
ILightReader world,
|
||||
IBlockDisplayReader world,
|
||||
IBakedModel model,
|
||||
BlockState state,
|
||||
BlockPos pos,
|
||||
|
||||
@@ -20,13 +20,13 @@ abstract public class MixinModelBakery {
|
||||
|
||||
private static final String processLoading = "Lnet/minecraft/client/renderer/model/ModelBakery;processLoading(Lnet/minecraft/profiler/IProfiler;I)V";
|
||||
private static final String stitch = "Lnet/minecraft/client/renderer/texture/AtlasTexture;stitch(Lnet/minecraft/resources/IResourceManager;Ljava/util/stream/Stream;Lnet/minecraft/profiler/IProfiler;I)Lnet/minecraft/client/renderer/texture/AtlasTexture$SheetData;";
|
||||
private static final String profilerSection = "Lnet/minecraft/profiler/IProfiler;endStartSection(Ljava/lang/String;)V";
|
||||
private static final String profilerSection = "Lnet/minecraft/profiler/IProfiler;popPush(Ljava/lang/String;)V";
|
||||
private static final String getBakedModel = "Lnet/minecraft/client/renderer/model/ModelBakery;getBakedModel(Lnet/minecraft/util/ResourceLocation;Lnet/minecraft/client/renderer/model/IModelTransform;Ljava/util/function/Function;)Lnet/minecraft/client/renderer/model/IBakedModel;";
|
||||
private static final String bakeModel = "Lnet/minecraft/client/renderer/model/IUnbakedModel;bakeModel(Lnet/minecraft/client/renderer/model/ModelBakery;Ljava/util/function/Function;Lnet/minecraft/client/renderer/model/IModelTransform;Lnet/minecraft/util/ResourceLocation;)Lnet/minecraft/client/renderer/model/IBakedModel;";
|
||||
private static final String bakeModel = "Lnet/minecraft/client/renderer/model/IUnbakedModel;bake(Lnet/minecraft/client/renderer/model/ModelBakery;Ljava/util/function/Function;Lnet/minecraft/client/renderer/model/IModelTransform;Lnet/minecraft/util/ResourceLocation;)Lnet/minecraft/client/renderer/model/IBakedModel;";
|
||||
|
||||
@Inject(method = processLoading, at = @At(value = "INVOKE", target = profilerSection, ordinal = 4))
|
||||
void onBeforeTextures(IProfiler profiler, int maxMipmapLevel, CallbackInfo ci) {
|
||||
profiler.endStartSection("betterfoliage");
|
||||
profiler.popPush("betterfoliage");
|
||||
BetterFoliageMod.INSTANCE.getBus().post(new ModelDefinitionsLoadedEvent(ModelBakery.class.cast(this)));
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ abstract public class MixinModelBakery {
|
||||
IBakedModel onBakeModel(
|
||||
IUnbakedModel unbaked,
|
||||
ModelBakery bakery,
|
||||
Function<Material, TextureAtlasSprite> spriteGetter,
|
||||
Function<RenderMaterial, TextureAtlasSprite> spriteGetter,
|
||||
IModelTransform transform,
|
||||
ResourceLocation locationIn
|
||||
) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import mods.betterfoliage.resource.discovery.ModelDefinitionsLoadedEvent
|
||||
import mods.betterfoliage.resource.generated.GeneratedTexturePack
|
||||
import mods.betterfoliage.render.particle.LeafParticleRegistry
|
||||
import mods.betterfoliage.render.particle.RisingSoulParticle
|
||||
import mods.betterfoliage.util.resourceManager
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.resources.IReloadableResourceManager
|
||||
@@ -51,7 +52,7 @@ object BetterFoliage {
|
||||
// discoverers
|
||||
BetterFoliageMod.bus.register(BakeWrapperManager)
|
||||
BetterFoliageMod.bus.register(LeafParticleRegistry)
|
||||
(Minecraft.getInstance().resourceManager as IReloadableResourceManager).addReloadListener(LeafParticleRegistry)
|
||||
resourceManager.registerReloadListener(LeafParticleRegistry)
|
||||
|
||||
ChunkOverlayManager.layers.add(RoundLogOverlayLayer)
|
||||
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
package mods.betterfoliage
|
||||
|
||||
import mods.betterfoliage.config.BlockConfig
|
||||
import mods.betterfoliage.config.Config
|
||||
import net.alexwells.kottle.FMLKotlinModLoadingContext
|
||||
import mods.betterfoliage.config.MainConfig
|
||||
import mods.betterfoliage.util.tryDefault
|
||||
import mods.betterfoliage.config.clothGuiRoot
|
||||
import mods.betterfoliage.config.forgeSpecRoot
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.screen.Screen
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraftforge.fml.ExtensionPoint.CONFIGGUIFACTORY
|
||||
import net.minecraftforge.fml.ExtensionPoint.DISPLAYTEST
|
||||
import net.minecraftforge.fml.ModLoadingContext
|
||||
import net.minecraftforge.fml.common.Mod
|
||||
import net.minecraftforge.fml.config.ModConfig
|
||||
import org.apache.commons.lang3.tuple.Pair
|
||||
import org.apache.logging.log4j.Level
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.apache.logging.log4j.simple.SimpleLogger
|
||||
import org.apache.logging.log4j.util.PropertiesUtil
|
||||
import thedarkcolour.kotlinforforge.forge.MOD_BUS
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
import java.util.Properties
|
||||
import java.util.function.BiFunction
|
||||
import java.util.function.BiPredicate
|
||||
import java.util.function.Supplier
|
||||
|
||||
@Mod(BetterFoliageMod.MOD_ID)
|
||||
object BetterFoliageMod {
|
||||
const val MOD_ID = "betterfoliage"
|
||||
|
||||
val bus = FMLKotlinModLoadingContext.get().modEventBus
|
||||
val bus = MOD_BUS
|
||||
val config = MainConfig()
|
||||
|
||||
val detailLogStream = PrintStream(File("logs/betterfoliage.log").apply {
|
||||
parentFile.mkdirs()
|
||||
@@ -32,8 +44,34 @@ object BetterFoliageMod {
|
||||
)
|
||||
|
||||
init {
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, Config.build())
|
||||
Minecraft.getInstance().resourcePackList.addPackFinder(BetterFoliage.generatedPack.finder)
|
||||
val ctx = ModLoadingContext.get()
|
||||
|
||||
val configSpec = config.forgeSpecRoot()
|
||||
ctx.registerConfig(ModConfig.Type.CLIENT, configSpec)
|
||||
|
||||
// Add config GUI extension if Cloth Config is available
|
||||
val clothLoaded = tryDefault(false) { Class.forName("me.shedaniel.clothconfig2.forge.api.ConfigBuilder"); true }
|
||||
if (clothLoaded) {
|
||||
logger(this).log(Level.INFO, "Cloth Config found, registering GUI")
|
||||
ctx.registerExtensionPoint(CONFIGGUIFACTORY) { BiFunction<Minecraft, Screen, Screen> { client, parent ->
|
||||
config.clothGuiRoot(
|
||||
parentScreen = parent,
|
||||
prefix = listOf(MOD_ID),
|
||||
background = ResourceLocation("minecraft:textures/block/spruce_log.png"),
|
||||
saveAction = { configSpec.save() }
|
||||
)
|
||||
} }
|
||||
}
|
||||
|
||||
// Accept-all version tester (we are client-only)
|
||||
ctx.registerExtensionPoint(DISPLAYTEST) {
|
||||
Pair.of(
|
||||
Supplier { "Honk if you see this!" },
|
||||
BiPredicate<String, Boolean> { _, _ -> true }
|
||||
)
|
||||
}
|
||||
|
||||
Minecraft.getInstance().resourcePackRepository.addPackFinder(BetterFoliage.generatedPack.finder)
|
||||
bus.register(BlockConfig)
|
||||
BetterFoliage.init()
|
||||
}
|
||||
|
||||
@@ -17,11 +17,13 @@ import net.minecraft.client.renderer.model.ModelBakery
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.IBlockDisplayReader
|
||||
import net.minecraft.world.IBlockReader
|
||||
import net.minecraft.world.ILightReader
|
||||
import net.minecraftforge.client.model.pipeline.BlockInfo
|
||||
import net.minecraftforge.client.model.pipeline.VertexLighterFlat
|
||||
import java.util.*
|
||||
import java.util.Random
|
||||
|
||||
typealias Sprite = TextureAtlasSprite
|
||||
|
||||
// Java
|
||||
val String = ClassRef<String>("java.lang.String")
|
||||
@@ -32,7 +34,7 @@ fun <K, V> mapRefMutable() = ClassRef<MutableMap<K, V>>("java.util.Map")
|
||||
|
||||
// Minecraft
|
||||
val IBlockReader = ClassRef<IBlockReader>("net.minecraft.world.IBlockReader")
|
||||
val ILightReader = ClassRef<ILightReader>("net.minecraft.world.ILightReader")
|
||||
val ILightReader = ClassRef<IBlockDisplayReader>("net.minecraft.world.IBlockDisplayReader")
|
||||
val BlockState = ClassRef<BlockState>("net.minecraft.block.BlockState")
|
||||
val BlockPos = ClassRef<BlockPos>("net.minecraft.util.math.BlockPos")
|
||||
val Block = ClassRef<Block>("net.minecraft.block.Block")
|
||||
@@ -77,6 +79,13 @@ object CustomColors : ClassRef<Any>("net.optifine.CustomColors") {
|
||||
}
|
||||
|
||||
// Optifine shaders
|
||||
object Shaders : ClassRef<Any>("net.optifine.shaders.Shaders") {
|
||||
val shaderPackLoaded = FieldRef(this, "shaderPackLoaded", boolean)
|
||||
val blockLightLevel05 = FieldRef(this, "blockLightLevel05", float)
|
||||
val blockLightLevel06 = FieldRef(this, "blockLightLevel06", float)
|
||||
val blockLightLevel08 = FieldRef(this, "blockLightLevel08", float)
|
||||
}
|
||||
|
||||
object SVertexBuilder : ClassRef<Any>("net.optifine.shaders.SVertexBuilder") {
|
||||
val pushState = MethodRef(this, "pushEntity", void, long)
|
||||
val popState = MethodRef(this, "popEntity", void)
|
||||
|
||||
@@ -20,8 +20,8 @@ import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.shapes.VoxelShape
|
||||
import net.minecraft.util.math.shapes.VoxelShapes
|
||||
import net.minecraft.world.IBlockDisplayReader
|
||||
import net.minecraft.world.IBlockReader
|
||||
import net.minecraft.world.ILightReader
|
||||
import net.minecraft.world.World
|
||||
import java.util.Random
|
||||
|
||||
@@ -35,11 +35,12 @@ fun onClientBlockChanged(worldClient: ClientWorld, pos: BlockPos, oldState: Bloc
|
||||
ChunkOverlayManager.onBlockChange(worldClient, pos)
|
||||
}
|
||||
|
||||
fun onRandomDisplayTick(block: Block, state: BlockState, world: World, pos: BlockPos, random: Random) {
|
||||
fun onRandomDisplayTick(world: ClientWorld, pos: BlockPos, random: Random) {
|
||||
val state = world.getBlockState(pos)
|
||||
if (Config.enabled &&
|
||||
Config.risingSoul.enabled &&
|
||||
state.block == Blocks.SOUL_SAND &&
|
||||
world.isAirBlock(pos.offset(UP)) &&
|
||||
world.getBlockState(pos.relative(UP)).isAir &&
|
||||
Math.random() < Config.risingSoul.chance) {
|
||||
RisingSoulParticle(world, pos).addIfValid()
|
||||
}
|
||||
@@ -47,7 +48,7 @@ fun onRandomDisplayTick(block: Block, state: BlockState, world: World, pos: Bloc
|
||||
if (Config.enabled &&
|
||||
Config.fallingLeaves.enabled &&
|
||||
random.nextDouble() < Config.fallingLeaves.chance &&
|
||||
world.isAirBlock(pos.offset(DOWN))
|
||||
world.getBlockState(pos.relative(DOWN)).isAir
|
||||
) {
|
||||
(getActualRenderModel(world, pos, state, random) as? LeafBlockModel)?.let { leafModel ->
|
||||
val blockColor = Minecraft.getInstance().blockColors.getColor(state, world, pos, 0)
|
||||
@@ -63,13 +64,13 @@ fun getVoxelShapeOverride(state: BlockState, reader: IBlockReader, pos: BlockPos
|
||||
}
|
||||
|
||||
fun shouldForceSideRenderOF(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction) =
|
||||
world.getBlockState(pos.offset(face)).let { neighbor -> BetterFoliage.blockTypes.hasTyped<RoundLogKey>(neighbor) }
|
||||
world.getBlockState(pos.relative(face)).let { neighbor -> BetterFoliage.blockTypes.hasTyped<RoundLogKey>(neighbor) }
|
||||
|
||||
fun getActualRenderModel(world: ILightReader, pos: BlockPos, state: BlockState, random: Random): SpecialRenderModel? {
|
||||
val model = Minecraft.getInstance().blockRendererDispatcher.blockModelShapes.getModel(state) as? SpecialRenderModel
|
||||
fun getActualRenderModel(world: IBlockDisplayReader, pos: BlockPos, state: BlockState, random: Random): SpecialRenderModel? {
|
||||
val model = Minecraft.getInstance().blockRenderer.blockModelShaper.getBlockModel(state) as? SpecialRenderModel
|
||||
?: return null
|
||||
if (model is WeightedModelWrapper) {
|
||||
random.setSeed(state.getPositionRandom(pos))
|
||||
random.setSeed(state.getSeed(pos))
|
||||
return model.getModel(random).model
|
||||
}
|
||||
return model
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mods.betterfoliage.chunk
|
||||
|
||||
import mods.betterfoliage.util.Int3
|
||||
import mods.betterfoliage.util.allDirections
|
||||
import mods.betterfoliage.util.offset
|
||||
import mods.betterfoliage.util.plus
|
||||
import mods.betterfoliage.util.semiRandom
|
||||
@@ -10,7 +9,7 @@ import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.renderer.chunk.ChunkRenderCache
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.ILightReader
|
||||
import net.minecraft.world.IBlockDisplayReader
|
||||
import net.minecraft.world.IWorldReader
|
||||
import net.minecraft.world.biome.Biome
|
||||
import net.minecraft.world.level.ColorResolver
|
||||
@@ -20,7 +19,7 @@ import net.minecraft.world.level.ColorResolver
|
||||
* block-relative coordinates.
|
||||
*/
|
||||
interface BlockCtx {
|
||||
val world: ILightReader
|
||||
val world: IBlockDisplayReader
|
||||
val pos: BlockPos
|
||||
|
||||
fun offset(dir: Direction) = offset(dir.offset)
|
||||
@@ -35,13 +34,13 @@ interface BlockCtx {
|
||||
|
||||
val biome: Biome? get() =
|
||||
(world as? IWorldReader)?.getBiome(pos) ?:
|
||||
(world as? ChunkRenderCache)?.world?.getBiome(pos)
|
||||
(world as? ChunkRenderCache)?.level?.getBiome(pos)
|
||||
|
||||
val isNormalCube: Boolean get() = state.isNormalCube(world, pos)
|
||||
val isFullBlock: Boolean get() = state.isCollisionShapeFullBlock(world, pos)
|
||||
|
||||
fun isNeighborSolid(dir: Direction) = offset(dir).let { it.state.isSolidSide(it.world, it.pos, dir.opposite) }
|
||||
fun isNeighborSturdy(dir: Direction) = offset(dir).let { it.state.isFaceSturdy(it.world, it.pos, dir.opposite) }
|
||||
|
||||
fun shouldSideBeRendered(side: Direction) = Block.shouldSideBeRendered(state, world, pos, side)
|
||||
fun shouldSideBeRendered(side: Direction) = Block.shouldRenderFace(state, world, pos, side)
|
||||
|
||||
/** Get a semi-random value based on the block coordinate and the given seed. */
|
||||
fun semiRandom(seed: Int) = pos.semiRandom(seed)
|
||||
@@ -49,11 +48,11 @@ interface BlockCtx {
|
||||
/** Get an array of semi-random values based on the block coordinate. */
|
||||
fun semiRandomArray(num: Int): Array<Int> = Array(num) { semiRandom(it) }
|
||||
|
||||
fun color(resolver: ColorResolver) = world.getBlockColor(pos, resolver)
|
||||
fun color(resolver: ColorResolver) = world.getBlockTint(pos, resolver)
|
||||
}
|
||||
|
||||
class BasicBlockCtx(
|
||||
override val world: ILightReader,
|
||||
override val world: IBlockDisplayReader,
|
||||
override val pos: BlockPos
|
||||
) : BlockCtx {
|
||||
override val state: BlockState = world.getBlockState(pos)
|
||||
|
||||
@@ -1,32 +1,26 @@
|
||||
package mods.betterfoliage.chunk
|
||||
|
||||
import mods.octarinecore.ChunkCacheOF
|
||||
import mods.betterfoliage.util.get
|
||||
import mods.betterfoliage.util.isInstance
|
||||
import mods.octarinecore.ChunkCacheOF
|
||||
import net.minecraft.client.renderer.chunk.ChunkRenderCache
|
||||
import net.minecraft.client.world.ClientWorld
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.ChunkPos
|
||||
import net.minecraft.world.ILightReader
|
||||
import net.minecraft.world.DimensionType
|
||||
import net.minecraft.world.IBlockDisplayReader
|
||||
import net.minecraft.world.IWorldReader
|
||||
import net.minecraft.world.dimension.DimensionType
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
import net.minecraftforge.event.world.ChunkEvent
|
||||
import net.minecraftforge.event.world.WorldEvent
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||
import java.util.*
|
||||
import kotlin.collections.List
|
||||
import kotlin.collections.MutableMap
|
||||
import kotlin.collections.associateWith
|
||||
import kotlin.collections.forEach
|
||||
import kotlin.collections.mutableListOf
|
||||
import kotlin.collections.mutableMapOf
|
||||
import kotlin.collections.set
|
||||
|
||||
val ILightReader.dimType: DimensionType get() = when {
|
||||
this is IWorldReader -> dimension.type
|
||||
this is ChunkRenderCache -> world.dimension.type
|
||||
this.isInstance(ChunkCacheOF) -> this[ChunkCacheOF.chunkCache].world.dimension.type
|
||||
val IBlockDisplayReader.dimType: DimensionType get() = when {
|
||||
this is IWorldReader -> dimensionType()
|
||||
this is ChunkRenderCache -> level.dimensionType()
|
||||
this.isInstance(ChunkCacheOF) -> this[ChunkCacheOF.chunkCache].level.dimensionType()
|
||||
else -> throw IllegalArgumentException("DimensionType of world with class ${this::class.qualifiedName} cannot be determined!")
|
||||
}
|
||||
|
||||
@@ -35,7 +29,7 @@ val ILightReader.dimType: DimensionType get() = when {
|
||||
*/
|
||||
interface ChunkOverlayLayer<T> {
|
||||
fun calculate(ctx: BlockCtx): T
|
||||
fun onBlockUpdate(world: ILightReader, pos: BlockPos)
|
||||
fun onBlockUpdate(world: IBlockDisplayReader, pos: BlockPos)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,150 +6,6 @@ import mods.betterfoliage.resource.discovery.ModelTextureListConfiguration
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||
import net.minecraftforge.fml.config.ModConfig
|
||||
import java.util.Random
|
||||
|
||||
private fun featureEnable() = boolean(true).lang("enabled")
|
||||
|
||||
abstract class PopulationConfigCategory() : ConfigCategory() {
|
||||
abstract val enabled: Boolean
|
||||
abstract val population: Int
|
||||
|
||||
fun enabled(random: Random) = random.nextInt(64) < population && enabled
|
||||
}
|
||||
|
||||
// Config singleton
|
||||
object Config : DelegatingConfig(BetterFoliageMod.MOD_ID, BetterFoliageMod.MOD_ID) {
|
||||
|
||||
val enabled by boolean(true)
|
||||
val nVidia by boolean(false)
|
||||
|
||||
object leaves : ConfigCategory() {
|
||||
val enabled by featureEnable()
|
||||
val snowEnabled by boolean(true)
|
||||
val hOffset by double(max=0.4, default=0.2).lang("hOffset")
|
||||
val vOffset by double(max=0.4, default=0.1).lang("vOffset")
|
||||
val size by double(min=0.75, max=2.5, default=1.4).lang("size")
|
||||
val dense by boolean(false)
|
||||
val hideInternal by boolean(true)
|
||||
val saturationThreshold by double(default=0.1)
|
||||
}
|
||||
|
||||
object shortGrass : PopulationConfigCategory(){
|
||||
override val enabled by featureEnable()
|
||||
val myceliumEnabled by boolean(true)
|
||||
val snowEnabled by boolean(true)
|
||||
val hOffset by double(max=0.4, default=0.2).lang("hOffset")
|
||||
val heightMin by double(min=0.1, max=2.5, default=0.6).lang("heightMin")
|
||||
val heightMax by double(min=0.1, max=2.5, default=0.8).lang("heightMax")
|
||||
val size by double(min=0.5, max=1.5, default=1.0).lang("size")
|
||||
override val population by int(max=64, default=64).lang("population")
|
||||
val useGenerated by boolean(false)
|
||||
val shaderWind by boolean(true).lang("shaderWind")
|
||||
val saturationThreshold by double(default=0.1)
|
||||
}
|
||||
|
||||
object connectedGrass : ConfigCategory(){
|
||||
val enabled by featureEnable()
|
||||
val snowEnabled by boolean(false)
|
||||
}
|
||||
|
||||
object roundLogs : ConfigCategory(){
|
||||
val enabled by featureEnable()
|
||||
val radiusSmall by double(max=0.5, default=0.25)
|
||||
val radiusLarge by double(max=0.5, default=0.44)
|
||||
val dimming by double(default = 0.7)
|
||||
val connectSolids by boolean(false)
|
||||
val lenientConnect by boolean(true)
|
||||
val connectPerpendicular by boolean(true)
|
||||
val connectGrass by boolean(true)
|
||||
val defaultY by boolean(false)
|
||||
val zProtection by double(min = 0.9, default = 0.99)
|
||||
}
|
||||
|
||||
object cactus : ConfigCategory(){
|
||||
val enabled by featureEnable()
|
||||
val size by double(min=1.0, max=2.0, default=1.3).lang("size")
|
||||
val sizeVariation by double(max=0.5, default=0.1)
|
||||
val hOffset by double(max=0.5, default=0.1).lang("hOffset")
|
||||
}
|
||||
|
||||
object lilypad : PopulationConfigCategory(){
|
||||
override val enabled by featureEnable()
|
||||
val hOffset by double(max=0.25, default=0.1).lang("hOffset")
|
||||
override val population by int(max=64, default=16, min=0)
|
||||
val shaderWind by boolean(true).lang("shaderWind")
|
||||
}
|
||||
|
||||
object reed : PopulationConfigCategory(){
|
||||
override val enabled by featureEnable()
|
||||
val hOffset by double(max=0.4, default=0.2).lang("hOffset")
|
||||
val heightMin by double(min=1.5, max=3.5, default=1.7).lang("heightMin")
|
||||
val heightMax by double(min=1.5, max=3.5, default=2.2).lang("heightMax")
|
||||
override val population by int(max=64, default=32).lang("population")
|
||||
val minBiomeTemp by double(default=0.4)
|
||||
val minBiomeRainfall by double(default=0.4)
|
||||
// val biomes by biomeList { it.filterTemp(0.4f, null) && it.filterRain(0.4f, null) }
|
||||
val shaderWind by boolean(true).lang("shaderWind")
|
||||
}
|
||||
|
||||
object algae : PopulationConfigCategory(){
|
||||
override val enabled by featureEnable()
|
||||
val hOffset by double(max=0.25, default=0.1).lang("hOffset")
|
||||
val size by double(min=0.5, max=1.5, default=1.0).lang("size")
|
||||
val heightMin by double(min=0.1, max=1.5, default=0.5).lang("heightMin")
|
||||
val heightMax by double(min=0.1, max=1.5, default=1.0).lang("heightMax")
|
||||
override val population by int(max=64, default=48).lang("population")
|
||||
// val biomes by biomeList { it.filterClass("river", "ocean") }
|
||||
val shaderWind by boolean(true).lang("shaderWind")
|
||||
}
|
||||
|
||||
object coral : PopulationConfigCategory(){
|
||||
override val enabled by featureEnable()
|
||||
val shallowWater by boolean(false)
|
||||
val hOffset by double(max=0.4, default=0.2).lang("hOffset")
|
||||
val vOffset by double(max=0.4, default=0.1).lang("vOffset")
|
||||
val size by double(min=0.5, max=1.5, default=0.7).lang("size")
|
||||
val crustSize by double(min=0.5, max=1.5, default=1.4)
|
||||
val chance by int(max=64, default=32)
|
||||
override val population by int(max=64, default=48).lang("population")
|
||||
// val biomes by biomeList { it.filterClass("river", "ocean", "beach") }
|
||||
}
|
||||
|
||||
object netherrack : ConfigCategory(){
|
||||
val enabled by featureEnable()
|
||||
val hOffset by double(max=0.4, default=0.2).lang("hOffset")
|
||||
val heightMin by double(min=0.1, max=1.5, default=0.2).lang("heightMin")
|
||||
val heightMax by double(min=0.1, max=1.5, default=0.5).lang("heightMax")
|
||||
val size by double(min=0.5, max=1.5, default=1.0).lang("size")
|
||||
}
|
||||
|
||||
object fallingLeaves : ConfigCategory(){
|
||||
val enabled by featureEnable()
|
||||
val speed by double(min=0.01, max=0.15, default=0.05)
|
||||
val windStrength by double(min=0.1, max=2.0, default=0.5)
|
||||
val stormStrength by double(min=0.1, max=2.0, default=0.8)
|
||||
val size by double(min=0.25, max=1.5, default=0.75).lang("size")
|
||||
val chance by double(min=0.001, max=1.0, default=0.02)
|
||||
val perturb by double(min=0.01, max=1.0, default=0.25)
|
||||
val lifetime by double(min=1.0, max=15.0, default=5.0)
|
||||
val opacityHack by boolean(true)
|
||||
}
|
||||
|
||||
object risingSoul : ConfigCategory(){
|
||||
val enabled by featureEnable()
|
||||
val chance by double(min=0.001, max=1.0, default=0.02)
|
||||
val perturb by double(min=0.01, max=0.25, default=0.05)
|
||||
val headSize by double(min=0.25, max=1.5, default=1.0)
|
||||
val trailSize by double(min=0.25, max=1.5, default=0.75)
|
||||
val opacity by double(min=0.05, max=1.0, default=0.5)
|
||||
val sizeDecay by double(min=0.5, max=1.0, default=0.97)
|
||||
val opacityDecay by double(min=0.5, max=1.0, default=0.97)
|
||||
val lifetime by double(min=1.0, max=15.0, default=4.0)
|
||||
val trailLength by int(min=2, max=128, default=48)
|
||||
val trailDensity by int(min=1, max=16, default=3)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object BlockConfig {
|
||||
private val list = mutableListOf<Any>()
|
||||
|
||||
170
src/main/kotlin/mods/betterfoliage/config/Delegate.kt
Normal file
170
src/main/kotlin/mods/betterfoliage/config/Delegate.kt
Normal file
@@ -0,0 +1,170 @@
|
||||
package mods.betterfoliage.config
|
||||
|
||||
import me.shedaniel.clothconfig2.forge.api.AbstractConfigListEntry
|
||||
import me.shedaniel.clothconfig2.forge.api.ConfigBuilder
|
||||
import me.shedaniel.clothconfig2.forge.api.ConfigEntryBuilder
|
||||
import me.shedaniel.clothconfig2.forge.gui.entries.SubCategoryListEntry
|
||||
import mods.betterfoliage.util.asText
|
||||
import net.minecraft.client.gui.screen.Screen
|
||||
import net.minecraft.client.resources.I18n
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraftforge.common.ForgeConfigSpec
|
||||
import java.util.Optional
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
const val MAX_LINE_LEN = 30
|
||||
|
||||
fun DelegatingConfigGroup.forgeSpecRoot() =
|
||||
ForgeConfigSpec.Builder()
|
||||
.also { createForgeNode(it) }
|
||||
.build()
|
||||
|
||||
fun DelegatingConfigGroup.clothGuiRoot(
|
||||
parentScreen: Screen,
|
||||
prefix: List<String>,
|
||||
background: ResourceLocation,
|
||||
saveAction: ()->Unit
|
||||
) = ConfigBuilder.create()
|
||||
.setParentScreen(parentScreen)
|
||||
.setTitle(I18n.get((prefix + "title").joinToString(".")).asText())
|
||||
.setDefaultBackgroundTexture(background)
|
||||
.setSavingRunnable(saveAction)
|
||||
.also { builder ->
|
||||
createClothNode(prefix).value.forEach { rootCategory ->
|
||||
builder.getOrCreateCategory("main".asText()).addEntry(rootCategory)
|
||||
}
|
||||
}
|
||||
.build()
|
||||
|
||||
sealed class DelegatingConfigNode {
|
||||
abstract fun createClothNode(path: List<String>): AbstractConfigListEntry<*>
|
||||
}
|
||||
|
||||
abstract class DelegatingConfigValue<T> : DelegatingConfigNode(), ReadOnlyProperty<DelegatingConfigGroup, T> {
|
||||
lateinit var forgeValue: ForgeConfigSpec.ConfigValue<T>
|
||||
abstract fun createForgeNode(builder: ForgeConfigSpec.Builder, name: String)
|
||||
}
|
||||
|
||||
open class DelegatingConfigGroup : DelegatingConfigNode() {
|
||||
val children = mutableMapOf<String, DelegatingConfigNode>()
|
||||
|
||||
fun createForgeNode(builder: ForgeConfigSpec.Builder) {
|
||||
children.forEach { (name, node) ->
|
||||
when(node) {
|
||||
is DelegatingConfigGroup -> {
|
||||
builder.push(name)
|
||||
node.createForgeNode(builder)
|
||||
builder.pop()
|
||||
}
|
||||
is DelegatingConfigValue<*> -> node.createForgeNode(builder, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun createClothNode(path: List<String>): SubCategoryListEntry {
|
||||
val builder = ConfigEntryBuilder.create()
|
||||
.startSubCategory(path.joinToString(".").translate())
|
||||
.setTooltip(*path.joinToString(".").translateTooltip())
|
||||
.setExpanded(false)
|
||||
children.forEach { (name, node) -> builder.add(node.createClothNode(path + name)) }
|
||||
return builder.build()
|
||||
}
|
||||
}
|
||||
|
||||
interface DelegatingConfigGroupFactory<T> {
|
||||
operator fun provideDelegate(parent: DelegatingConfigGroup, property: KProperty<*>): ReadOnlyProperty<DelegatingConfigGroup, T>
|
||||
}
|
||||
|
||||
fun <T: DelegatingConfigGroup> subNode(factory: ()->T) = object : DelegatingConfigGroupFactory<T> {
|
||||
override operator fun provideDelegate(parent: DelegatingConfigGroup, property: KProperty<*>): ReadOnlyProperty<DelegatingConfigGroup, T> {
|
||||
val child = factory()
|
||||
parent.children[property.name] = child
|
||||
return ReadOnlyProperty { _, _ -> child }
|
||||
}
|
||||
}
|
||||
|
||||
interface DelegatingConfigValueFactory<T> {
|
||||
fun createForgeNode(builder: ForgeConfigSpec.Builder, name: String): ForgeConfigSpec.ConfigValue<T>
|
||||
fun createClothNode(prop: CachingConfigProperty<T>, path: List<String>): AbstractConfigListEntry<T>
|
||||
|
||||
operator fun provideDelegate(parent: DelegatingConfigGroup, property: KProperty<*>): ReadOnlyProperty<DelegatingConfigGroup, T> {
|
||||
return object : CachingConfigProperty<T>(parent, property) {
|
||||
override fun createForgeNode(builder: ForgeConfigSpec.Builder, name: String) {
|
||||
forgeValue = this@DelegatingConfigValueFactory.createForgeNode(builder, name)
|
||||
}
|
||||
|
||||
override fun createClothNode(path: List<String>): AbstractConfigListEntry<*> = createClothNode(this, path)
|
||||
|
||||
}.apply { parent.children[property.name] = this }
|
||||
}
|
||||
}
|
||||
|
||||
abstract class CachingConfigProperty<T>(parent: DelegatingConfigGroup, property: KProperty<*>) : DelegatingConfigValue<T>() {
|
||||
var value: T? = null
|
||||
override fun getValue(thisRef: DelegatingConfigGroup, property: KProperty<*>) =
|
||||
value ?: forgeValue.get().apply { value = this }
|
||||
}
|
||||
|
||||
fun String.translate() = I18n.get(this).asText()
|
||||
fun String.translateTooltip(lineLength: Int = MAX_LINE_LEN) =
|
||||
I18n.get("$this.tooltip").splitToSequence(" ").fold(mutableListOf("")) { tooltips, word ->
|
||||
if (tooltips.last().length + word.length < lineLength) {
|
||||
tooltips[tooltips.lastIndex] += "$word "
|
||||
} else {
|
||||
tooltips.add("$word ")
|
||||
}
|
||||
tooltips
|
||||
}.map { it.trim().asText() }.toTypedArray()
|
||||
|
||||
fun boolean(
|
||||
default: Boolean,
|
||||
langKey: (List<String>)->String = { it.joinToString(".") },
|
||||
valueOverride: (Boolean)->Boolean = { it }
|
||||
) = object : DelegatingConfigValueFactory<Boolean> {
|
||||
override fun createForgeNode(builder: ForgeConfigSpec.Builder, name: String) =
|
||||
builder.define(name, default)
|
||||
|
||||
override fun createClothNode(prop: CachingConfigProperty<Boolean>, path: List<String>) = ConfigEntryBuilder.create()
|
||||
.startBooleanToggle(langKey(path).translate(), prop.forgeValue.get())
|
||||
.setTooltip(langKey(path).let { if (I18n.exists("$it.tooltip")) Optional.of(it.translateTooltip()) else Optional.empty() })
|
||||
.setSaveConsumer { prop.forgeValue.set(valueOverride(it)); prop.value = null }
|
||||
.build()
|
||||
}
|
||||
|
||||
fun integer(
|
||||
default: Int = 0, min: Int = 0, max: Int,
|
||||
langKey: (List<String>)->String = { it.joinToString(".") },
|
||||
valueOverride: (Int)->Int = { it }
|
||||
) = object : DelegatingConfigValueFactory<Int> {
|
||||
override fun createForgeNode(builder: ForgeConfigSpec.Builder, name: String) =
|
||||
builder.defineInRange(name, default, min, max)
|
||||
|
||||
override fun createClothNode(prop: CachingConfigProperty<Int>, path: List<String>) = ConfigEntryBuilder.create()
|
||||
.startIntField(langKey(path).translate(), prop.forgeValue.get())
|
||||
.setTooltip(langKey(path).let { if (I18n.exists("$it.tooltip")) Optional.of(it.translateTooltip()) else Optional.empty() })
|
||||
.setMin(min).setMax(max)
|
||||
.setSaveConsumer { prop.forgeValue.set(valueOverride(it)); prop.value = null }
|
||||
.build()
|
||||
}
|
||||
|
||||
fun double(
|
||||
default: Double = 0.0, min: Double = 0.0, max: Double = 1.0,
|
||||
langKey: (List<String>)->String = { it.joinToString(".") },
|
||||
valueOverride: (Double)->Double = { it }
|
||||
) = object : DelegatingConfigValueFactory<Double> {
|
||||
override fun createForgeNode(builder: ForgeConfigSpec.Builder, name: String) =
|
||||
builder.defineInRange(name, default, min, max)
|
||||
|
||||
override fun createClothNode(prop: CachingConfigProperty<Double>, path: List<String>) = ConfigEntryBuilder.create()
|
||||
.startDoubleField(langKey(path).translate(), prop.forgeValue.get())
|
||||
.setTooltip(langKey(path).let { if (I18n.exists("$it.tooltip")) Optional.of(it.translateTooltip()) else Optional.empty() })
|
||||
.setMin(min).setMax(max)
|
||||
.setSaveConsumer { prop.forgeValue.set(valueOverride(it)); prop.value = null }
|
||||
.build()
|
||||
}
|
||||
|
||||
val recurring = { path: List<String> -> "${path.first()}.${path.last()}" }
|
||||
fun fakeCategory(name: String) = { names: List<String> ->
|
||||
(listOf(names.first(), name) + names.drop(1)).joinToString(".")
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
@file:JvmName("DelegatingConfigKt")
|
||||
|
||||
package mods.betterfoliage.config
|
||||
|
||||
import mods.betterfoliage.util.reflectDelegates
|
||||
import mods.betterfoliage.util.reflectNestedObjects
|
||||
import net.minecraftforge.common.ForgeConfigSpec
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
open class DelegatingConfig(val modId: String, val langPrefix: String) {
|
||||
fun build() = ForgeConfigSpec.Builder().apply { ConfigBuildContext(langPrefix, emptyList(), this).addCategory(this@DelegatingConfig) }.build()
|
||||
}
|
||||
|
||||
class ConfigBuildContext(val langPrefix: String, val path: List<String>, val builder: ForgeConfigSpec.Builder) {
|
||||
|
||||
fun addCategory(configObj: Any) {
|
||||
configObj.reflectNestedObjects.forEach { (name, category) ->
|
||||
builder.push(name)
|
||||
descend(name).addCategory(category)
|
||||
builder.pop()
|
||||
}
|
||||
configObj.reflectDelegates(ConfigDelegate::class.java).forEach { (name, delegate) ->
|
||||
descend(name).apply { delegate.addToBuilder(this) }
|
||||
}
|
||||
}
|
||||
|
||||
fun descend(pathName: String) = ConfigBuildContext(langPrefix, path + pathName, builder)
|
||||
}
|
||||
|
||||
open class ConfigCategory(val comment: String? = null) {
|
||||
}
|
||||
|
||||
abstract class ConfigDelegate<T> : ReadOnlyProperty<Any, T> {
|
||||
lateinit var configValue: ForgeConfigSpec.ConfigValue<T>
|
||||
var cachedValue: T? = null
|
||||
|
||||
override fun getValue(thisRef: Any, property: KProperty<*>): T {
|
||||
if (cachedValue == null) cachedValue = configValue.get()
|
||||
return cachedValue!!
|
||||
}
|
||||
|
||||
abstract fun getConfigValue(name: String, builder: ForgeConfigSpec.Builder): ForgeConfigSpec.ConfigValue<T>
|
||||
fun addToBuilder(ctx: ConfigBuildContext) {
|
||||
val langKey = ctx.langPrefix + "." + (langPrefixOverride ?: ctx.path.joinToString("."))
|
||||
ctx.builder.translation(langKey)
|
||||
configValue = getConfigValue(ctx.path.last(), ctx.builder)
|
||||
}
|
||||
|
||||
var langPrefixOverride: String? = null
|
||||
fun lang(prefix: String) = apply { langPrefixOverride = prefix }
|
||||
|
||||
}
|
||||
|
||||
class DelegatingBooleanValue(val defaultValue: Boolean) : ConfigDelegate<Boolean>() {
|
||||
override fun getConfigValue(name: String, builder: ForgeConfigSpec.Builder) = builder.define(name, defaultValue)
|
||||
}
|
||||
|
||||
class DelegatingIntValue(
|
||||
val minValue: Int = 0,
|
||||
val maxValue: Int = 1,
|
||||
val defaultValue: Int = 0
|
||||
) : ConfigDelegate<Int>() {
|
||||
override fun getConfigValue(name: String, builder: ForgeConfigSpec.Builder) = builder.defineInRange(name, defaultValue, minValue, maxValue)
|
||||
}
|
||||
|
||||
class DelegatingLongValue(
|
||||
val minValue: Long = 0,
|
||||
val maxValue: Long = 1,
|
||||
val defaultValue: Long = 0
|
||||
) : ConfigDelegate<Long>() {
|
||||
override fun getConfigValue(name: String, builder: ForgeConfigSpec.Builder) = builder.defineInRange(name, defaultValue, minValue, maxValue)
|
||||
}
|
||||
|
||||
class DelegatingDoubleValue(
|
||||
val minValue: Double = 0.0,
|
||||
val maxValue: Double = 1.0,
|
||||
val defaultValue: Double = 0.0
|
||||
) : ConfigDelegate<Double>() {
|
||||
override fun getConfigValue(name: String, builder: ForgeConfigSpec.Builder) = builder.defineInRange(name, defaultValue, minValue, maxValue)
|
||||
}
|
||||
|
||||
// ============================
|
||||
// Delegate factory methods
|
||||
// ============================
|
||||
fun double(min: Double = 0.0, max: Double = 1.0, default: Double) = DelegatingDoubleValue(min, max, default)
|
||||
fun int(min: Int = 0, max: Int, default: Int) = DelegatingIntValue(min, max, default)
|
||||
fun long(min: Long = 0, max: Long, default: Long) = DelegatingLongValue(min, max, default)
|
||||
fun boolean(default: Boolean) = DelegatingBooleanValue(default)
|
||||
158
src/main/kotlin/mods/betterfoliage/config/MainConfig.kt
Normal file
158
src/main/kotlin/mods/betterfoliage/config/MainConfig.kt
Normal file
@@ -0,0 +1,158 @@
|
||||
package mods.betterfoliage.config
|
||||
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import java.util.Random
|
||||
|
||||
fun featureEnable(default: Boolean = true) = boolean(default, langKey = recurring)
|
||||
|
||||
val Config get() = BetterFoliageMod.config
|
||||
|
||||
abstract class PopulationConfigGroup : DelegatingConfigGroup() {
|
||||
abstract val enabled: Boolean
|
||||
abstract val population: Int
|
||||
|
||||
fun enabled(random: Random) = random.nextInt(64) < population && enabled
|
||||
}
|
||||
|
||||
class MainConfig : DelegatingConfigGroup() {
|
||||
val enabled by boolean(true, langKey = { "betterfoliage.global.enabled" })
|
||||
val nVidia by boolean(false)
|
||||
|
||||
val leaves by subNode(::LeavesConfig)
|
||||
val shortGrass by subNode(::ShortGrassConfig)
|
||||
val connectedGrass by subNode(::ConnectedGrassConfig)
|
||||
val roundLogs by subNode(::RoundLogConfig)
|
||||
val cactus by subNode(::CactusConfig)
|
||||
val lilypad by subNode(::LilypadConfig)
|
||||
val reed by subNode(::ReedConfig)
|
||||
val algae by subNode(::AlgaeConfig)
|
||||
val coral by subNode(::CoralConfig)
|
||||
val netherrack by subNode(::NetherrackConfig)
|
||||
val fallingLeaves by subNode(::FallingLeavesConfig)
|
||||
val risingSoul by subNode(::RisingSoulConfig)
|
||||
}
|
||||
|
||||
class LeavesConfig : DelegatingConfigGroup() {
|
||||
val enabled by featureEnable()
|
||||
val snowEnabled by boolean(true)
|
||||
val hOffset by double(max=0.4, default=0.2, langKey = recurring)
|
||||
val vOffset by double(max=0.4, default=0.1, langKey = recurring)
|
||||
val size by double(min=0.75, max=2.5, default=1.4, langKey = recurring)
|
||||
val dense by boolean(false)
|
||||
val hideInternal by boolean(true)
|
||||
val saturationThreshold by double(default=0.1, langKey = recurring)
|
||||
}
|
||||
|
||||
class ShortGrassConfig : PopulationConfigGroup() {
|
||||
override val enabled by featureEnable()
|
||||
val grassEnabled by boolean(true)
|
||||
val myceliumEnabled by boolean(true)
|
||||
val snowEnabled by boolean(true)
|
||||
val hOffset by double(max=0.4, default=0.2, langKey = recurring)
|
||||
val heightMin by double(min=0.1, max=2.5, default=0.6, langKey = recurring)
|
||||
val heightMax by double(min=0.1, max=2.5, default=0.8, langKey = recurring)
|
||||
val size by double(min=0.5, max=1.5, default=1.0, langKey = recurring)
|
||||
override val population by integer(max=64, default=64, langKey = recurring)
|
||||
val useGenerated by boolean(false)
|
||||
val shaderWind by boolean(true, langKey = recurring)
|
||||
val saturationThreshold by double(default=0.1, langKey = recurring)
|
||||
}
|
||||
|
||||
class ConnectedGrassConfig : DelegatingConfigGroup() {
|
||||
val enabled by boolean(true)
|
||||
val snowEnabled by boolean(false)
|
||||
}
|
||||
|
||||
class RoundLogConfig : DelegatingConfigGroup() {
|
||||
val enabled by featureEnable()
|
||||
val plantsOnly by boolean(true)
|
||||
val radiusSmall by double(max=0.5, default=0.25)
|
||||
val radiusLarge by double(max=0.5, default=0.44)
|
||||
val dimming by double(default = 0.7)
|
||||
val connectSolids by boolean(false)
|
||||
val lenientConnect by boolean(true)
|
||||
val connectPerpendicular by boolean(true)
|
||||
val connectGrass by boolean(true)
|
||||
val defaultY by boolean(false)
|
||||
val zProtection by double(min = 0.9, default = 0.99)
|
||||
}
|
||||
|
||||
class CactusConfig : DelegatingConfigGroup() {
|
||||
val enabled by featureEnable()
|
||||
val size by double(min=0.5, max=1.5, default=0.8, langKey = recurring)
|
||||
val sizeVariation by double(max=0.5, default=0.1)
|
||||
val hOffset by double(max=0.5, default=0.1, langKey = recurring)
|
||||
}
|
||||
|
||||
class LilypadConfig : PopulationConfigGroup() {
|
||||
override val enabled by featureEnable()
|
||||
val hOffset by double(max=0.25, default=0.1, langKey = recurring)
|
||||
override val population by integer(max=64, default=16, min=0, langKey = recurring)
|
||||
val shaderWind by boolean(true, langKey = recurring)
|
||||
}
|
||||
|
||||
class ReedConfig : PopulationConfigGroup() {
|
||||
override val enabled by featureEnable()
|
||||
val hOffset by double(max=0.4, default=0.2, langKey = recurring)
|
||||
val heightMin by double(min=1.5, max=3.5, default=1.7, langKey = recurring)
|
||||
val heightMax by double(min=1.5, max=3.5, default=2.2, langKey = recurring)
|
||||
override val population by integer(max=64, default=32, langKey = recurring)
|
||||
val minBiomeTemp by double(default=0.4)
|
||||
val minBiomeRainfall by double(default=0.4)
|
||||
val shaderWind by boolean(true, langKey = recurring)
|
||||
}
|
||||
|
||||
class AlgaeConfig : PopulationConfigGroup() {
|
||||
override val enabled by featureEnable()
|
||||
val hOffset by double(max=0.25, default=0.1, langKey = recurring)
|
||||
val size by double(min=0.5, max=1.5, default=1.0, langKey = recurring)
|
||||
val heightMin by double(min=0.1, max=1.5, default=0.5, langKey = recurring)
|
||||
val heightMax by double(min=0.1, max=1.5, default=1.0, langKey = recurring)
|
||||
override val population by integer(max=64, default=48, langKey = recurring)
|
||||
val shaderWind by boolean(true, langKey = recurring)
|
||||
}
|
||||
|
||||
class CoralConfig : PopulationConfigGroup() {
|
||||
override val enabled by featureEnable()
|
||||
val shallowWater by boolean(false)
|
||||
val hOffset by double(max=0.4, default=0.2, langKey = recurring)
|
||||
val vOffset by double(max=0.4, default=0.1, langKey = recurring)
|
||||
val size by double(min=0.5, max=1.5, default=0.7, langKey = recurring)
|
||||
val crustSize by double(min=0.5, max=1.5, default=1.4)
|
||||
val chance by integer(max=64, default=32)
|
||||
override val population by integer(max=64, default=48, langKey = recurring)
|
||||
}
|
||||
|
||||
class NetherrackConfig : DelegatingConfigGroup() {
|
||||
val enabled by featureEnable()
|
||||
val hOffset by double(max=0.4, default=0.2, langKey = recurring)
|
||||
val heightMin by double(min=0.1, max=1.5, default=0.6, langKey = recurring)
|
||||
val heightMax by double(min=0.1, max=1.5, default=0.8, langKey = recurring)
|
||||
val size by double(min=0.5, max=1.5, default=1.0, langKey = recurring)
|
||||
}
|
||||
|
||||
class FallingLeavesConfig : DelegatingConfigGroup() {
|
||||
val enabled by featureEnable()
|
||||
val speed by double(min=0.01, max=0.15, default=0.05)
|
||||
val windStrength by double(min=0.1, max=2.0, default=0.5)
|
||||
val stormStrength by double(min=0.1, max=2.0, default=0.8)
|
||||
val size by double(min=0.25, max=1.5, default=0.75, langKey = recurring)
|
||||
val chance by double(min=0.001, max=1.0, default=0.02)
|
||||
val perturb by double(min=0.01, max=1.0, default=0.25)
|
||||
val lifetime by double(min=1.0, max=15.0, default=5.0)
|
||||
val opacityHack by boolean(true)
|
||||
}
|
||||
|
||||
class RisingSoulConfig : DelegatingConfigGroup() {
|
||||
val enabled by featureEnable()
|
||||
val chance by double(min=0.001, max=1.0, default=0.02)
|
||||
val perturb by double(min=0.01, max=0.25, default=0.05)
|
||||
val headSize by double(min=0.25, max=1.5, default=1.0)
|
||||
val trailSize by double(min=0.25, max=1.5, default=0.75)
|
||||
val opacity by double(min=0.05, max=1.0, default=0.5)
|
||||
val sizeDecay by double(min=0.5, max=1.0, default=0.97)
|
||||
val opacityDecay by double(min=0.5, max=1.0, default=0.97)
|
||||
val lifetime by double(min=1.0, max=15.0, default=4.0)
|
||||
val trailLength by integer(min=2, max=128, default=48)
|
||||
val trailDensity by integer(min=1, max=16, default=3)
|
||||
}
|
||||
@@ -14,5 +14,7 @@ val MYCELIUM_BLOCKS = listOf(Blocks.MYCELIUM)
|
||||
|
||||
val SALTWATER_BIOMES = listOf(Biome.Category.BEACH, Biome.Category.OCEAN)
|
||||
|
||||
val SNOW_MATERIALS = listOf(Material.SNOW_BLOCK, Material.SNOW)
|
||||
val BlockState.isSnow: Boolean get() = material in SNOW_MATERIALS
|
||||
val SNOW_MATERIALS = listOf(Material.TOP_SNOW, Material.SNOW)
|
||||
val BlockState.isSnow: Boolean get() = material in SNOW_MATERIALS
|
||||
|
||||
val ACCEPTED_ROUND_LOG_MATERIALS = listOf(Material.WOOD, Material.GRASS)
|
||||
|
||||
@@ -34,7 +34,7 @@ object OptifineCustomColors {
|
||||
val fakeQuad = BakedQuad(IntArray(0), 1, UP, null, true)
|
||||
|
||||
fun getBlockColor(ctx: BlockCtx, resolver: ColorResolver): Int {
|
||||
val ofColor = if (isColorAvailable && Minecraft.getInstance().gameSettings.reflectField<Boolean>("ofCustomColors") == true) {
|
||||
val ofColor = if (isColorAvailable && Minecraft.getInstance().options.reflectField<Boolean>("ofCustomColors") == true) {
|
||||
renderEnv.reset(ctx.state, ctx.pos)
|
||||
CustomColors.getColorMultiplier.invokeStatic(fakeQuad, ctx.state, ctx.world, ctx.pos, renderEnv.wrapped) as? Int
|
||||
} else null
|
||||
|
||||
@@ -1,48 +1,75 @@
|
||||
package mods.betterfoliage.integration
|
||||
|
||||
import mods.betterfoliage.config.BlockConfig
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxForge
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxVanilla
|
||||
import mods.betterfoliage.resource.discovery.BakeWrapperManager
|
||||
import mods.betterfoliage.util.HasLogger
|
||||
import mods.betterfoliage.util.allAvailable
|
||||
import mods.betterfoliage.util.get
|
||||
import mods.betterfoliage.util.mapArray
|
||||
import mods.octarinecore.*
|
||||
import net.minecraft.block.BlockRenderType
|
||||
import net.minecraft.block.BlockRenderType.MODEL
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.client.renderer.BufferBuilder
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.Direction.DOWN
|
||||
import net.minecraft.util.Direction.EAST
|
||||
import net.minecraft.util.Direction.NORTH
|
||||
import net.minecraft.util.Direction.SOUTH
|
||||
import net.minecraft.util.Direction.WEST
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.ILightReader
|
||||
import net.minecraft.world.IBlockDisplayReader
|
||||
import net.minecraftforge.client.model.pipeline.LightUtil
|
||||
import org.apache.logging.log4j.Level.INFO
|
||||
|
||||
/**
|
||||
* Integration for ShadersMod.
|
||||
*/
|
||||
object ShadersModIntegration : HasLogger() {
|
||||
@JvmStatic val isAvailable = allAvailable(SVertexBuilder, SVertexBuilder.pushState, SVertexBuilder.popState, BlockAliases.getAliasBlockId)
|
||||
@JvmStatic val isEffectsAvailable = allAvailable(SVertexBuilder.pushState, SVertexBuilder.popState, BlockAliases.getAliasBlockId)
|
||||
@JvmStatic val isDiffuseAvailable = allAvailable(Shaders.shaderPackLoaded, Shaders.blockLightLevel05, Shaders.blockLightLevel06, Shaders.blockLightLevel08)
|
||||
|
||||
val defaultLeaves = Blocks.OAK_LEAVES.defaultState
|
||||
val defaultGrass = Blocks.GRASS.defaultState
|
||||
@JvmStatic val defaultLeaves = Blocks.OAK_LEAVES.defaultBlockState()
|
||||
@JvmStatic val defaultGrass = Blocks.GRASS.defaultBlockState()
|
||||
|
||||
@JvmStatic var diffuseShades = Direction.values().mapArray { LightUtil.diffuseLight(it) }
|
||||
|
||||
/**
|
||||
* Called from transformed ShadersMod code.
|
||||
* @see mods.betterfoliage.loader.BetterFoliageTransformer
|
||||
*/
|
||||
@JvmStatic fun getBlockStateOverride(state: BlockState, world: ILightReader, pos: BlockPos): BlockState {
|
||||
@JvmStatic fun getBlockStateOverride(state: BlockState, world: IBlockDisplayReader, pos: BlockPos): BlockState {
|
||||
// if (LeafRegistry[state, world, pos] != null) return defaultLeaves
|
||||
// if (BlockConfig.crops.matchesClass(state.block)) return defaultGrass
|
||||
return state
|
||||
}
|
||||
|
||||
init {
|
||||
logger.log(INFO, "ShadersMod integration is ${if (isAvailable) "enabled" else "disabled" }")
|
||||
logger.log(INFO, "ShadersMod diffuse shading integration is ${if (isDiffuseAvailable) "enabled" else "disabled" }")
|
||||
logger.log(INFO, "ShadersMod vertex shader integration is ${if (isEffectsAvailable) "enabled" else "disabled" }")
|
||||
|
||||
// Recalculate the diffsuse shading values used when resources are reloaded
|
||||
if (isDiffuseAvailable) BakeWrapperManager.onInvalidate {
|
||||
if (Shaders.shaderPackLoaded.getStatic()) {
|
||||
diffuseShades = Direction.values().mapArray { face ->
|
||||
when(face) {
|
||||
DOWN -> Shaders.blockLightLevel05.getStatic()
|
||||
WEST, EAST -> Shaders.blockLightLevel06.getStatic()
|
||||
NORTH, SOUTH -> Shaders.blockLightLevel08.getStatic()
|
||||
else -> LightUtil.diffuseLight(face)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
diffuseShades = Direction.values().mapArray { LightUtil.diffuseLight(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Quads rendered inside this block will use the given block entity data in shader programs. */
|
||||
inline fun renderAs(buffer: BufferBuilder, state: BlockState, renderType: BlockRenderType, enabled: Boolean = true, func: ()->Unit) {
|
||||
if (isAvailable && enabled) {
|
||||
if (isEffectsAvailable && enabled) {
|
||||
val aliasBlockId = BlockAliases.getAliasBlockId.invokeStatic(state)
|
||||
val sVertexBuilder = buffer[BufferBuilder_sVertexBuilder]
|
||||
SVertexBuilder.pushState.invoke(sVertexBuilder, aliasBlockId)
|
||||
|
||||
@@ -68,8 +68,8 @@ fun List<Quad>.bake(applyDiffuseLighting: Boolean) = map { quad ->
|
||||
)
|
||||
// don't fill lightmap UV coords
|
||||
element.usage == VertexFormatElement.Usage.UV && element.type == VertexFormatElement.Type.FLOAT -> builder.put(idx,
|
||||
quad.sprite.minU + (quad.sprite.maxU - quad.sprite.minU) * (vertex.uv.u + 0.5).toFloat(),
|
||||
quad.sprite.minV + (quad.sprite.maxV - quad.sprite.minV) * (vertex.uv.v + 0.5).toFloat(),
|
||||
quad.sprite.u0 + (quad.sprite.u1 - quad.sprite.u0) * (vertex.uv.u + 0.5).toFloat(),
|
||||
quad.sprite.v0 + (quad.sprite.v1 - quad.sprite.v0) * (vertex.uv.v + 0.5).toFloat(),
|
||||
0.0f, 1.0f
|
||||
)
|
||||
element.usage == VertexFormatElement.Usage.COLOR -> builder.put(idx,
|
||||
@@ -96,18 +96,18 @@ fun Array<List<Quad>>.bake(applyDiffuseLighting: Boolean) = mapArray { it.bake(a
|
||||
fun BakedQuad.unbake(): HalfBakedQuad {
|
||||
val size = DefaultVertexFormats.BLOCK.integerSize
|
||||
val verts = Array(4) { vIdx ->
|
||||
val x = java.lang.Float.intBitsToFloat(vertexData[vIdx * size + 0])
|
||||
val y = java.lang.Float.intBitsToFloat(vertexData[vIdx * size + 1])
|
||||
val z = java.lang.Float.intBitsToFloat(vertexData[vIdx * size + 2])
|
||||
val color = vertexData[vIdx * size + 3]
|
||||
val u = java.lang.Float.intBitsToFloat(vertexData[vIdx * size + 4])
|
||||
val v = java.lang.Float.intBitsToFloat(vertexData[vIdx * size + 5])
|
||||
val x = java.lang.Float.intBitsToFloat(vertices[vIdx * size + 0]) - 0.5f
|
||||
val y = java.lang.Float.intBitsToFloat(vertices[vIdx * size + 1]) - 0.5f
|
||||
val z = java.lang.Float.intBitsToFloat(vertices[vIdx * size + 2]) - 0.5f
|
||||
val color = vertices[vIdx * size + 3]
|
||||
val u = java.lang.Float.intBitsToFloat(vertices[vIdx * size + 4])
|
||||
val v = java.lang.Float.intBitsToFloat(vertices[vIdx * size + 5])
|
||||
Vertex(Double3(x, y, z), UV(u.toDouble(), v.toDouble()), Color(color))
|
||||
}
|
||||
val unbaked = Quad(
|
||||
verts[0], verts[1], verts[2], verts[3],
|
||||
colorIndex = if (hasTintIndex()) tintIndex else -1,
|
||||
face = face
|
||||
colorIndex = if (isTinted) tintIndex else -1,
|
||||
face = direction
|
||||
)
|
||||
return HalfBakedQuad(unbaked, this)
|
||||
}
|
||||
|
||||
@@ -1,17 +1,9 @@
|
||||
package mods.betterfoliage.model
|
||||
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||
import mods.betterfoliage.util.HasLogger
|
||||
import net.minecraft.client.renderer.model.IBakedModel
|
||||
import net.minecraft.client.renderer.model.Material
|
||||
import net.minecraft.client.renderer.model.ModelBakery
|
||||
import net.minecraft.client.renderer.model.VariantList
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraft.util.WeightedRandom
|
||||
import org.apache.logging.log4j.Level.WARN
|
||||
import java.util.Random
|
||||
import java.util.function.Function
|
||||
|
||||
/**
|
||||
* Model that makes use of advanced rendering features.
|
||||
@@ -24,9 +16,9 @@ class WeightedModelWrapper(
|
||||
val models: List<WeightedModel>, baseModel: SpecialRenderModel
|
||||
): IBakedModel by baseModel, SpecialRenderModel {
|
||||
class WeightedModel(val model: SpecialRenderModel, weight: Int) : WeightedRandom.Item(weight)
|
||||
val totalWeight = models.sumBy { it.itemWeight }
|
||||
val totalWeight = models.sumBy { it.weight }
|
||||
|
||||
fun getModel(random: Random) = WeightedRandom.getRandomItem(models, random.nextInt(totalWeight))
|
||||
fun getModel(random: Random) = WeightedRandom.getWeightedItem(models, random.nextInt(totalWeight))
|
||||
|
||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
||||
getModel(ctx.random).model.render(ctx, noDecorations)
|
||||
|
||||
@@ -59,7 +59,7 @@ class SpriteSetDelegate(
|
||||
|
||||
@SubscribeEvent
|
||||
fun handlePreStitch(event: TextureStitchEvent.Pre) {
|
||||
if (event.map.textureLocation != Atlas.BLOCKS.resourceId) return
|
||||
if (event.map.location() != atlas.resourceId) return
|
||||
spriteSet = null
|
||||
idList = (0 until 16)
|
||||
.map(idFunc)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package mods.betterfoliage.render.block.vanilla
|
||||
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.config.Config
|
||||
import mods.betterfoliage.config.DIRT_BLOCKS
|
||||
import mods.betterfoliage.config.SALTWATER_BIOMES
|
||||
import mods.betterfoliage.config.isSnow
|
||||
import mods.betterfoliage.integration.ShadersModIntegration
|
||||
import mods.betterfoliage.model.HalfBakedSpecialWrapper
|
||||
import mods.betterfoliage.model.HalfBakedWrapperKey
|
||||
@@ -15,7 +16,6 @@ import mods.betterfoliage.model.tuftModelSet
|
||||
import mods.betterfoliage.model.tuftShapeSet
|
||||
import mods.betterfoliage.render.lighting.LightingPreferredFace
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxVanilla
|
||||
import mods.betterfoliage.resource.discovery.AbstractModelDiscovery
|
||||
import mods.betterfoliage.resource.discovery.BakeWrapperManager
|
||||
import mods.betterfoliage.resource.discovery.ModelBakingContext
|
||||
@@ -27,20 +27,18 @@ import mods.betterfoliage.util.LazyInvalidatable
|
||||
import mods.betterfoliage.util.get
|
||||
import mods.betterfoliage.util.offset
|
||||
import mods.betterfoliage.util.randomI
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.RenderTypeLookup
|
||||
import net.minecraft.client.renderer.model.BlockModel
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraft.world.biome.Biome
|
||||
|
||||
object StandardDirtDiscovery : AbstractModelDiscovery() {
|
||||
fun canRenderInLayer(layer: RenderType) = when {
|
||||
!Config.enabled -> layer == RenderType.getSolid()
|
||||
!Config.connectedGrass.enabled && !Config.algae.enabled && !Config.reed.enabled -> layer == RenderType.getSolid()
|
||||
else -> layer == RenderType.getCutoutMipped()
|
||||
!Config.enabled -> layer == RenderType.solid()
|
||||
!Config.connectedGrass.enabled && !Config.algae.enabled && !Config.reed.enabled -> layer == RenderType.solid()
|
||||
else -> layer == RenderType.cutoutMipped()
|
||||
}
|
||||
|
||||
override fun processModel(ctx: ModelDiscoveryContext) {
|
||||
@@ -67,9 +65,12 @@ class StandardDirtModel(
|
||||
|
||||
val stateUp = ctx.state(UP)
|
||||
val state2Up = ctx.state(Int3(0, 2, 0))
|
||||
val isConnectedGrass = Config.connectedGrass.enabled && stateUp in BetterFoliage.blockTypes.grass
|
||||
val isConnectedGrass = Config.connectedGrass.enabled &&
|
||||
stateUp in BetterFoliage.blockTypes.grass &&
|
||||
(Config.connectedGrass.snowEnabled || !state2Up.isSnow)
|
||||
|
||||
if (isConnectedGrass) {
|
||||
(ctx.blockModelShapes.getModel(stateUp) as? SpecialRenderModel)?.let { grassModel ->
|
||||
(ctx.blockModelShapes.getBlockModel(stateUp) as? SpecialRenderModel)?.let { grassModel ->
|
||||
ctx.renderMasquerade(UP.offset) {
|
||||
grassModel.render(ctx, true)
|
||||
}
|
||||
@@ -81,9 +82,9 @@ class StandardDirtModel(
|
||||
super.render(ctx, false)
|
||||
|
||||
val isWater = stateUp.material == Material.WATER
|
||||
val isDeepWater = isWater && ctx.offset(Int3(2 to UP)).state.material == Material.WATER
|
||||
val isShallowWater = isWater && ctx.offset(Int3(2 to UP)).state.isAir
|
||||
val isSaltWater = isWater && ctx.biome?.category in SALTWATER_BIOMES
|
||||
val isDeepWater = isWater && state2Up.material == Material.WATER
|
||||
val isShallowWater = isWater && state2Up.isAir
|
||||
val isSaltWater = isWater && ctx.biome?.biomeCategory in SALTWATER_BIOMES
|
||||
|
||||
if (Config.algae.enabled(ctx.random) && isDeepWater) {
|
||||
ctx.vertexLighter = vanillaTuftLighting
|
||||
|
||||
@@ -87,7 +87,7 @@ class StandardGrassModel(
|
||||
super.render(ctx, noDecorations)
|
||||
}
|
||||
|
||||
if (Config.shortGrass.enabled(ctx.random) && (isAir || isSnowed)) {
|
||||
if (Config.shortGrass.enabled(ctx.random) && Config.shortGrass.grassEnabled && (isAir || isSnowed)) {
|
||||
ctx.vertexLighter = tuftLighting
|
||||
ShadersModIntegration.grass(ctx, Config.shortGrass.shaderWind) {
|
||||
ctx.renderQuads(if (isSnowed) tuftSnowed[ctx.random] else tuftNormal[ctx.random])
|
||||
|
||||
@@ -31,7 +31,7 @@ object StandardMyceliumDiscovery : AbstractModelDiscovery() {
|
||||
override fun processModel(ctx: ModelDiscoveryContext) {
|
||||
if (ctx.getUnbaked() is BlockModel && ctx.blockState.block in MYCELIUM_BLOCKS) {
|
||||
ctx.addReplacement(StandardMyceliumKey)
|
||||
RenderTypeLookup.setRenderLayer(ctx.blockState.block, RenderType.getCutout())
|
||||
RenderTypeLookup.setRenderLayer(ctx.blockState.block, RenderType.cutout())
|
||||
}
|
||||
super.processModel(ctx)
|
||||
}
|
||||
@@ -50,9 +50,8 @@ class StandardMyceliumModel(
|
||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
||||
super.render(ctx, noDecorations)
|
||||
|
||||
if (Config.shortGrass.enabled &&
|
||||
if (Config.shortGrass.enabled(ctx.random) &&
|
||||
Config.shortGrass.myceliumEnabled &&
|
||||
Config.shortGrass.enabled(ctx.random) &&
|
||||
ctx.state(Direction.UP).isAir(ctx.world, ctx.pos)
|
||||
) {
|
||||
ctx.vertexLighter = tuftLighting
|
||||
|
||||
@@ -32,9 +32,9 @@ import net.minecraft.util.ResourceLocation
|
||||
|
||||
object StandardNetherrackDiscovery : AbstractModelDiscovery() {
|
||||
fun canRenderInLayer(layer: RenderType) = when {
|
||||
!Config.enabled -> layer == RenderType.getSolid()
|
||||
!Config.netherrack.enabled -> layer == RenderType.getSolid()
|
||||
else -> layer == RenderType.getCutoutMipped()
|
||||
!Config.enabled -> layer == RenderType.solid()
|
||||
!Config.netherrack.enabled -> layer == RenderType.solid()
|
||||
else -> layer == RenderType.cutoutMipped()
|
||||
}
|
||||
|
||||
override fun processModel(ctx: ModelDiscoveryContext) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package mods.betterfoliage.render.block.vanilla
|
||||
|
||||
import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.config.ACCEPTED_ROUND_LOG_MATERIALS
|
||||
import mods.betterfoliage.config.BlockConfig
|
||||
import mods.betterfoliage.config.Config
|
||||
import mods.betterfoliage.resource.discovery.ModelTextureList
|
||||
import mods.betterfoliage.model.HalfBakedWrapperKey
|
||||
import mods.betterfoliage.model.SpecialRenderModel
|
||||
import mods.betterfoliage.render.column.ColumnBlockKey
|
||||
@@ -16,11 +16,12 @@ import mods.betterfoliage.resource.discovery.ConfigurableModelDiscovery
|
||||
import mods.betterfoliage.resource.discovery.ModelBakingContext
|
||||
import mods.betterfoliage.resource.discovery.ModelBakingKey
|
||||
import mods.betterfoliage.resource.discovery.ModelDiscoveryContext
|
||||
import mods.betterfoliage.resource.discovery.ModelTextureList
|
||||
import mods.betterfoliage.util.Atlas
|
||||
import mods.betterfoliage.util.LazyMapInvalidatable
|
||||
import mods.betterfoliage.util.tryDefault
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.LogBlock
|
||||
import net.minecraft.block.RotatedPillarBlock
|
||||
import net.minecraft.util.Direction.Axis
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import org.apache.logging.log4j.Level.INFO
|
||||
@@ -43,13 +44,15 @@ object StandardRoundLogDiscovery : ConfigurableModelDiscovery() {
|
||||
|
||||
override fun processModel(ctx: ModelDiscoveryContext, textureMatch: List<ResourceLocation>) {
|
||||
val axis = getAxis(ctx.blockState)
|
||||
detailLogger.log(INFO, " axis $axis")
|
||||
ctx.addReplacement(StandardRoundLogKey(axis, textureMatch[0], textureMatch[1]))
|
||||
|
||||
detailLogger.log(INFO, " axis $axis, material ${ctx.blockState.material}")
|
||||
if (!Config.roundLogs.plantsOnly || ctx.blockState.material in ACCEPTED_ROUND_LOG_MATERIALS)
|
||||
ctx.addReplacement(StandardRoundLogKey(axis, textureMatch[0], textureMatch[1]))
|
||||
}
|
||||
|
||||
fun getAxis(state: BlockState): Axis? {
|
||||
val axis = tryDefault(null) { state.get(LogBlock.AXIS).toString() } ?:
|
||||
state.values.entries.find { it.key.getName().toLowerCase() == "axis" }?.value?.toString()
|
||||
val axis = tryDefault(null) { state.getValue(RotatedPillarBlock.AXIS).toString() } ?:
|
||||
state.values.entries.find { it.key.name.toLowerCase() == "axis" }?.value?.toString()
|
||||
return when (axis) {
|
||||
"x" -> Axis.X
|
||||
"y" -> Axis.Y
|
||||
|
||||
@@ -43,7 +43,7 @@ object StandardSandDiscovery : AbstractModelDiscovery() {
|
||||
if (ctx.getUnbaked() is BlockModel && ctx.blockState.block in SAND_BLOCKS) {
|
||||
BetterFoliage.blockTypes.dirt.add(ctx.blockState)
|
||||
ctx.addReplacement(StandardSandKey)
|
||||
RenderTypeLookup.setRenderLayer(ctx.blockState.block, RenderType.getCutoutMipped())
|
||||
RenderTypeLookup.setRenderLayer(ctx.blockState.block, RenderType.cutoutMipped())
|
||||
}
|
||||
super.processModel(ctx)
|
||||
}
|
||||
@@ -61,7 +61,7 @@ class StandardSandModel(
|
||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
||||
super.render(ctx, noDecorations)
|
||||
if (noDecorations || !Config.enabled || !Config.coral.enabled(ctx.random)) return
|
||||
if (ctx.biome?.category !in SALTWATER_BIOMES) return
|
||||
if (ctx.biome?.biomeCategory !in SALTWATER_BIOMES) return
|
||||
|
||||
allDirections.filter { ctx.random.nextInt(64) < Config.coral.chance }.forEach { face ->
|
||||
val isWater = ctx.state(face).material == Material.WATER
|
||||
|
||||
@@ -23,7 +23,7 @@ import net.minecraft.block.BlockState
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.Direction.Axis
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.ILightReader
|
||||
import net.minecraft.world.IBlockDisplayReader
|
||||
|
||||
/** Index of SOUTH-EAST quadrant. */
|
||||
const val SE = 0
|
||||
@@ -83,13 +83,13 @@ abstract class ColumnRenderLayer : ChunkOverlayLayer<ColumnLayerData> {
|
||||
|
||||
val allNeighborOffsets = (-1..1).flatMap { offsetX -> (-1..1).flatMap { offsetY -> (-1..1).map { offsetZ -> Int3(offsetX, offsetY, offsetZ) }}}
|
||||
|
||||
override fun onBlockUpdate(world: ILightReader, pos: BlockPos) {
|
||||
override fun onBlockUpdate(world: IBlockDisplayReader, pos: BlockPos) {
|
||||
allNeighborOffsets.forEach { offset -> ChunkOverlayManager.clear(world.dimType, this, pos + offset) }
|
||||
}
|
||||
|
||||
override fun calculate(ctx: BlockCtx): ColumnLayerData {
|
||||
// TODO detect round logs
|
||||
if (allDirections.all { dir -> ctx.offset(dir).let { it.isNormalCube } }) return ColumnLayerData.SkipRender
|
||||
if (allDirections.all { dir -> ctx.offset(dir).let { it.isFullBlock } }) return ColumnLayerData.SkipRender
|
||||
val columnTextures = getColumnKey(ctx.state) ?: return ColumnLayerData.ResolveError
|
||||
|
||||
// if log axis is not defined and "Default to vertical" config option is not set, render normally
|
||||
@@ -185,7 +185,7 @@ abstract class ColumnRenderLayer : ChunkOverlayLayer<ColumnLayerData> {
|
||||
val offsetRot = offset.rotate(rotation)
|
||||
val key = getColumnKey(state(offsetRot))
|
||||
return if (key == null) {
|
||||
if (offset(offsetRot).isNormalCube) SOLID else NONSOLID
|
||||
if (offset(offsetRot).isFullBlock) SOLID else NONSOLID
|
||||
} else {
|
||||
(key.axis ?: if (Config.roundLogs.defaultY) Axis.Y else null)?.let {
|
||||
if (it == axis) PARALLEL else PERPENDICULAR
|
||||
|
||||
@@ -5,7 +5,7 @@ import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.renderer.BlockModelRenderer
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.ILightReader
|
||||
import net.minecraft.world.IBlockDisplayReader
|
||||
|
||||
data class LightingData(
|
||||
@JvmField var packedLight: Int = 0,
|
||||
@@ -23,13 +23,17 @@ data class LightingData(
|
||||
}
|
||||
}
|
||||
|
||||
// Vanilla has a very suspicious-looking offset here, which Indigo gets rid of and calls it a fix
|
||||
// Naturally, we're going to believe Indigo, it's a hardcoded option for now
|
||||
const val OCCLUSION_OFFSET_FIX = true
|
||||
|
||||
/**
|
||||
* Replacement for [BlockModelRenderer.AmbientOcclusionFace]
|
||||
* This gets called on a LOT, so object instantiation is avoided.
|
||||
* Not thread-safe, always use a [ThreadLocal] instance
|
||||
*/
|
||||
class VanillaAoCalculator {
|
||||
lateinit var world: ILightReader
|
||||
lateinit var world: IBlockDisplayReader
|
||||
|
||||
/** [blockPos] is used to get block-related information (i.e. tint, opacity, etc.)
|
||||
* [lightPos] is used to get light-related information
|
||||
@@ -37,7 +41,7 @@ class VanillaAoCalculator {
|
||||
lateinit var blockPos: BlockPos
|
||||
lateinit var lightPos: BlockPos
|
||||
|
||||
private val probe = LightProbe(BlockModelRenderer.CACHE_COMBINED_LIGHT.get())
|
||||
private val probe = LightProbe(BlockModelRenderer.CACHE.get())
|
||||
|
||||
val isValid = BooleanArray(6)
|
||||
val aoData = Array(24) { LightingData() }
|
||||
@@ -70,13 +74,13 @@ class VanillaAoCalculator {
|
||||
|
||||
// Bit 0 of the bitset in vanilla calculations
|
||||
// true if the block model is planar with the block boundary
|
||||
val isFullBlock = forceFull ?: world.getBlockState(blockPos).isCollisionShapeOpaque(world, blockPos)
|
||||
val isFullBlock = forceFull ?: world.getBlockState(blockPos).isCollisionShapeFullBlock(world, blockPos)
|
||||
|
||||
val lightOrigin = if (isFullBlock) lightPos.offset(lightFace) else lightPos
|
||||
val lightOrigin = if (isFullBlock) lightPos.relative(lightFace) else lightPos
|
||||
|
||||
// AO calculation for the face center
|
||||
probe.position { setPos(lightOrigin) }.writeTo(centerAo)
|
||||
if (!isFullBlock && !probe.position { move(lightFace) }.state.isOpaqueCube(world, probe.pos)) {
|
||||
probe.position { set(lightOrigin) }.writeTo(centerAo)
|
||||
if (!isFullBlock && !probe.position { move(lightFace) }.state.isSolidRender(world, probe.pos)) {
|
||||
// if the neighboring block in the lightface direction is
|
||||
// transparent (non-opaque), use its packed light instead of our own
|
||||
// (if our block is a full block, we are already using this value)
|
||||
@@ -86,10 +90,11 @@ class VanillaAoCalculator {
|
||||
// AO calculation for the 4 sides
|
||||
sideHelper.sides.forEachIndexed { sideIdx, sideDir ->
|
||||
// record light data in the block 1 step to the side
|
||||
probe.position { setPos(lightOrigin).move(sideDir) }.writeTo(sideAo[sideIdx])
|
||||
probe.position { set(lightOrigin).move(sideDir) }.writeTo(sideAo[sideIdx])
|
||||
// side is considered occluded if the block 1 step to that side and
|
||||
// 1 step forward (in the lightface direction) is not fully transparent
|
||||
isOccluded[sideIdx] = probe.position { move(lightFace) }.isNonTransparent
|
||||
if (!OCCLUSION_OFFSET_FIX) probe.position { move(lightFace) }
|
||||
isOccluded[sideIdx] = probe.isNonTransparent
|
||||
}
|
||||
|
||||
// AO Calculation for the 4 corners
|
||||
@@ -103,7 +108,7 @@ class VanillaAoCalculator {
|
||||
else {
|
||||
// lookup actual packed light from the cornering block in the world
|
||||
probe.position {
|
||||
setPos(lightOrigin)
|
||||
set(lightOrigin)
|
||||
.move(sideHelper.sides[sideIndices.first])
|
||||
.move(sideHelper.sides[sideIndices.second])
|
||||
}.writeTo(cornerAo[cornerIdx])
|
||||
@@ -129,9 +134,9 @@ class VanillaAoCalculator {
|
||||
lateinit var state: BlockState
|
||||
val pos = BlockPos.Mutable()
|
||||
|
||||
val packedLight: Int get() = cache.getPackedLight(state, world, pos)
|
||||
val colorMultiplier: Float get() = cache.getBrightness(state, world, pos)
|
||||
val isNonTransparent: Boolean get() = state.getOpacity(world, pos) > 0
|
||||
val packedLight: Int get() = cache.getLightColor(state, world, pos)
|
||||
val colorMultiplier: Float get() = cache.getShadeBrightness(state, world, pos)
|
||||
val isNonTransparent: Boolean get() = state.getLightBlock(world, pos) > 0
|
||||
|
||||
fun writeTo(data: LightingData) {
|
||||
data.packedLight = packedLight
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package mods.betterfoliage.render.lighting
|
||||
|
||||
import mods.betterfoliage.integration.ShadersModIntegration
|
||||
import mods.betterfoliage.model.HalfBakedQuad
|
||||
import mods.betterfoliage.util.Double3
|
||||
import mods.betterfoliage.util.EPSILON_ONE
|
||||
import mods.betterfoliage.util.EPSILON_ZERO
|
||||
import mods.betterfoliage.util.get
|
||||
import mods.betterfoliage.util.minBy
|
||||
import net.minecraft.client.renderer.color.BlockColors
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.Direction.*
|
||||
import net.minecraft.util.Direction.Axis
|
||||
import net.minecraftforge.client.model.pipeline.LightUtil
|
||||
import kotlin.math.abs
|
||||
|
||||
class VanillaQuadLighting {
|
||||
@@ -34,7 +34,7 @@ class VanillaQuadLighting {
|
||||
}
|
||||
|
||||
fun applyDiffuseLighting(face: Direction) {
|
||||
val factor = LightUtil.diffuseLight(face)
|
||||
val factor = ShadersModIntegration.diffuseShades[face]
|
||||
tint[0] *= factor; tint[1] *= factor; tint[2] *= factor
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ object VanillaFullBlockLighting : VanillaVertexLighter() {
|
||||
lighting.calc.fillLightData(face, true)
|
||||
lighting.updateWithCornerAo(quad) { nearestCornerOnFace(it, face) }
|
||||
lighting.updateBlockTint(quad.baked.tintIndex)
|
||||
if (quad.baked.shouldApplyDiffuseLighting()) lighting.applyDiffuseLighting(face)
|
||||
if (quad.baked.isShade) lighting.applyDiffuseLighting(face)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@ import mods.betterfoliage.util.Double3
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.particle.SpriteTexturedParticle
|
||||
import net.minecraft.client.renderer.ActiveRenderInfo
|
||||
import net.minecraft.client.renderer.Vector3f
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||
import net.minecraft.client.world.ClientWorld
|
||||
import net.minecraft.util.math.MathHelper
|
||||
import net.minecraft.world.World
|
||||
import net.minecraft.util.math.vector.Vector3f
|
||||
|
||||
abstract class AbstractParticle(world: World, x: Double, y: Double, z: Double) : SpriteTexturedParticle(world, x, y, z) {
|
||||
abstract class AbstractParticle(world: ClientWorld, x: Double, y: Double, z: Double) : SpriteTexturedParticle(world, x, y, z) {
|
||||
|
||||
companion object {
|
||||
// @JvmStatic val sin = Array(64) { idx -> Math.sin(PI2 / 64.0 * idx) }
|
||||
@@ -24,12 +24,12 @@ abstract class AbstractParticle(world: World, x: Double, y: Double, z: Double) :
|
||||
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
currentPos.setTo(posX, posY, posZ)
|
||||
prevPos.setTo(prevPosX, prevPosY, prevPosZ)
|
||||
velocity.setTo(motionX, motionY, motionZ)
|
||||
currentPos.setTo(x, y, z)
|
||||
prevPos.setTo(xo, yo, zo)
|
||||
velocity.setTo(xd, yd, zd)
|
||||
update()
|
||||
posX = currentPos.x; posY = currentPos.y; posZ = currentPos.z;
|
||||
motionX = velocity.x; motionY = velocity.y; motionZ = velocity.z;
|
||||
x = currentPos.x; y = currentPos.y; z = currentPos.z;
|
||||
xd = velocity.x; yd = velocity.y; zd = velocity.z;
|
||||
}
|
||||
|
||||
/** Update particle on world tick. */
|
||||
@@ -39,10 +39,10 @@ abstract class AbstractParticle(world: World, x: Double, y: Double, z: Double) :
|
||||
abstract val isValid: Boolean
|
||||
|
||||
/** Add the particle to the effect renderer if it is valid. */
|
||||
fun addIfValid() { if (isValid) Minecraft.getInstance().particles.addEffect(this) }
|
||||
fun addIfValid() { if (isValid) Minecraft.getInstance().particleEngine.add(this) }
|
||||
|
||||
override fun renderParticle(vertexBuilder: IVertexBuilder, camera: ActiveRenderInfo, tickDelta: Float) {
|
||||
super.renderParticle(vertexBuilder, camera, tickDelta)
|
||||
override fun render(vertexBuilder: IVertexBuilder, camera: ActiveRenderInfo, tickDelta: Float) {
|
||||
super.render(vertexBuilder, camera, tickDelta)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,39 +63,39 @@ abstract class AbstractParticle(world: World, x: Double, y: Double, z: Double) :
|
||||
tickDelta: Float,
|
||||
currentPos: Double3 = this.currentPos,
|
||||
prevPos: Double3 = this.prevPos,
|
||||
size: Double = particleScale.toDouble(),
|
||||
currentAngle: Float = this.particleAngle,
|
||||
prevAngle: Float = this.prevParticleAngle,
|
||||
size: Double = quadSize.toDouble(),
|
||||
currentAngle: Float = this.roll,
|
||||
prevAngle: Float = this.oRoll,
|
||||
sprite: TextureAtlasSprite = this.sprite,
|
||||
alpha: Float = this.particleAlpha) {
|
||||
alpha: Float = this.alpha) {
|
||||
|
||||
val center = Double3.lerp(tickDelta.toDouble(), prevPos, currentPos)
|
||||
val angle = MathHelper.lerp(tickDelta, prevAngle, currentAngle)
|
||||
val rotation = camera.rotation.copy().apply { multiply(Vector3f.ZP.rotation(angle)) }
|
||||
val lightmapCoord = getBrightnessForRender(tickDelta)
|
||||
val rotation = camera.rotation().copy().apply { mul(Vector3f.ZP.rotation(angle)) }
|
||||
val lightmapCoord = getLightColor(tickDelta)
|
||||
|
||||
val coords = arrayOf(
|
||||
Double3(-1.0, -1.0, 0.0),
|
||||
Double3(-1.0, 1.0, 0.0),
|
||||
Double3(1.0, 1.0, 0.0),
|
||||
Double3(1.0, -1.0, 0.0)
|
||||
).map { it.rotate(rotation).mul(size).add(center).sub(camera.projectedView.x, camera.projectedView.y, camera.projectedView.z) }
|
||||
).map { it.rotate(rotation).mul(size).add(center).sub(camera.position.x, camera.position.y, camera.position.z) }
|
||||
|
||||
fun renderVertex(vertex: Double3, u: Float, v: Float) = vertexConsumer
|
||||
.pos(vertex.x, vertex.y, vertex.z).tex(u, v)
|
||||
.color(particleRed, particleGreen, particleBlue, alpha).lightmap(lightmapCoord)
|
||||
.vertex(vertex.x, vertex.y, vertex.z).uv(u, v)
|
||||
.color(rCol, gCol, bCol, alpha).uv2(lightmapCoord)
|
||||
.endVertex()
|
||||
|
||||
renderVertex(coords[0], sprite.maxU, sprite.maxV)
|
||||
renderVertex(coords[1], sprite.maxU, sprite.minV)
|
||||
renderVertex(coords[2], sprite.minU, sprite.minV)
|
||||
renderVertex(coords[3], sprite.minU, sprite.maxV)
|
||||
renderVertex(coords[0], sprite.u1, sprite.v1)
|
||||
renderVertex(coords[1], sprite.u1, sprite.v0)
|
||||
renderVertex(coords[2], sprite.u0, sprite.v0)
|
||||
renderVertex(coords[3], sprite.u0, sprite.v1)
|
||||
}
|
||||
|
||||
fun setColor(color: Int) {
|
||||
particleBlue = (color and 255) / 256.0f
|
||||
particleGreen = ((color shr 8) and 255) / 256.0f
|
||||
particleRed = ((color shr 16) and 255) / 256.0f
|
||||
bCol = (color and 255) / 256.0f
|
||||
gCol = ((color shr 8) and 255) / 256.0f
|
||||
rCol = ((color shr 16) and 255) / 256.0f
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,22 +8,22 @@ import mods.betterfoliage.util.randomB
|
||||
import mods.betterfoliage.util.randomD
|
||||
import mods.betterfoliage.util.randomF
|
||||
import mods.betterfoliage.util.randomI
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.particle.IParticleRenderType
|
||||
import net.minecraft.client.world.ClientWorld
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.MathHelper
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
import net.minecraftforge.event.TickEvent
|
||||
import net.minecraftforge.event.world.WorldEvent
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||
import net.minecraftforge.fml.LogicalSide
|
||||
import java.util.Random
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
class FallingLeafParticle(
|
||||
world: World, pos: BlockPos, leaf: LeafParticleKey, blockColor: Int, random: Random
|
||||
world: ClientWorld, pos: BlockPos, leaf: LeafParticleKey, blockColor: Int, random: Random
|
||||
) : AbstractParticle(
|
||||
world, pos.x.toDouble() + 0.5, pos.y.toDouble(), pos.z.toDouble() + 0.5
|
||||
) {
|
||||
@@ -37,13 +37,13 @@ class FallingLeafParticle(
|
||||
var wasCollided = false
|
||||
|
||||
init {
|
||||
particleAngle = random.randomF(max = PI2)
|
||||
prevParticleAngle = particleAngle - rotationSpeed
|
||||
roll = random.randomF(max = PI2)
|
||||
oRoll = roll - rotationSpeed
|
||||
|
||||
maxAge = MathHelper.floor(randomD(0.6, 1.0) * Config.fallingLeaves.lifetime * 20.0)
|
||||
motionY = -Config.fallingLeaves.speed
|
||||
lifetime = MathHelper.floor(randomD(0.6, 1.0) * Config.fallingLeaves.lifetime * 20.0)
|
||||
yd = -Config.fallingLeaves.speed
|
||||
|
||||
particleScale = Config.fallingLeaves.size.toFloat() * 0.1f
|
||||
quadSize = Config.fallingLeaves.size.toFloat() * 0.1f
|
||||
setColor(leaf.overrideColor?.asInt ?: blockColor)
|
||||
sprite = LeafParticleRegistry[leaf.leafType][randomI(max = 1024)]
|
||||
}
|
||||
@@ -52,21 +52,21 @@ class FallingLeafParticle(
|
||||
|
||||
|
||||
override fun update() {
|
||||
if (rand.nextFloat() > 0.95f) rotationSpeed *= -1.0f
|
||||
if (age > maxAge - 20) particleAlpha = 0.05f * (maxAge - age)
|
||||
if (random.nextFloat() > 0.95f) rotationSpeed *= -1.0f
|
||||
if (age > lifetime - 20) alpha = 0.05f * (lifetime - age)
|
||||
|
||||
if (onGround || wasCollided) {
|
||||
velocity.setTo(0.0, 0.0, 0.0)
|
||||
if (!wasCollided) {
|
||||
age = age.coerceAtLeast(maxAge - 20)
|
||||
age = age.coerceAtLeast(lifetime - 20)
|
||||
wasCollided = true
|
||||
}
|
||||
} else {
|
||||
val cosRotation = cos(particleAngle).toDouble(); val sinRotation = sin(particleAngle).toDouble()
|
||||
val cosRotation = cos(roll).toDouble(); val sinRotation = sin(roll).toDouble()
|
||||
velocity.setTo(cosRotation, 0.0, sinRotation).mul(Config.fallingLeaves.perturb)
|
||||
.add(LeafWindTracker.current).add(0.0, -1.0, 0.0).mul(Config.fallingLeaves.speed)
|
||||
prevParticleAngle = particleAngle
|
||||
particleAngle += rotationSpeed
|
||||
oRoll = roll
|
||||
roll += rotationSpeed
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ object LeafWindTracker {
|
||||
}
|
||||
|
||||
fun changeWind(world: World) {
|
||||
nextChange = world.worldInfo.gameTime + 120 + random.nextInt(80)
|
||||
nextChange = world.gameTime + 120 + random.nextInt(80)
|
||||
val direction = PI2 * random.nextDouble()
|
||||
val speed = abs(random.nextGaussian()) * Config.fallingLeaves.windStrength +
|
||||
(if (!world.isRaining) 0.0 else abs(random.nextGaussian()) * Config.fallingLeaves.stormStrength)
|
||||
@@ -92,10 +92,10 @@ object LeafWindTracker {
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun handleWorldTick(event: TickEvent.ClientTickEvent) {
|
||||
if (event.phase == TickEvent.Phase.START) Minecraft.getInstance().world?.let { world ->
|
||||
fun handleWorldTick(event: TickEvent.WorldTickEvent) {
|
||||
if (event.phase == TickEvent.Phase.START && event.side == LogicalSide.CLIENT) event.world.let { world ->
|
||||
// change target wind speed
|
||||
if (world.worldInfo.dayTime >= nextChange) changeWind(world)
|
||||
if (world.dayTime >= nextChange) changeWind(world)
|
||||
|
||||
// change current wind speed
|
||||
val changeRate = if (world.isRaining) 0.015 else 0.005
|
||||
@@ -107,6 +107,6 @@ object LeafWindTracker {
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun handleWorldLoad(event: WorldEvent.Load) { if (event.world.isRemote) changeWind(event.world.world) }
|
||||
// @SubscribeEvent
|
||||
// fun handleWorldLoad(event: WorldEvent.Load) { if (event.world.isClientSide) changeWind(event.world) }
|
||||
}
|
||||
@@ -41,7 +41,7 @@ object LeafParticleRegistry : HasLogger(), VeryEarlyReloadListener {
|
||||
|
||||
@SubscribeEvent
|
||||
fun handlePreStitch(event: TextureStitchEvent.Pre) {
|
||||
if (event.map.textureLocation == Atlas.PARTICLES.resourceId) {
|
||||
if (event.map.location() == Atlas.PARTICLES.resourceId) {
|
||||
allTypes.forEach { leafType ->
|
||||
val locations = (0 until 16).map { idx ->
|
||||
ResourceLocation(BetterFoliageMod.MOD_ID, "particle/falling_leaf_${leafType}_$idx")
|
||||
@@ -55,7 +55,7 @@ object LeafParticleRegistry : HasLogger(), VeryEarlyReloadListener {
|
||||
|
||||
@SubscribeEvent
|
||||
fun handlePostStitch(event: TextureStitchEvent.Post) {
|
||||
if (event.map.textureLocation == Atlas.PARTICLES.resourceId) {
|
||||
if (event.map.location() == Atlas.PARTICLES.resourceId) {
|
||||
(typeMappings.mappings.map { it.type } + "default").distinct().forEach { leafType ->
|
||||
val sprites = (0 until 16).map { idx ->
|
||||
ResourceLocation(BetterFoliageMod.MOD_ID, "particle/falling_leaf_${leafType}_$idx")
|
||||
|
||||
@@ -13,6 +13,7 @@ import mods.betterfoliage.util.randomD
|
||||
import mods.betterfoliage.util.randomI
|
||||
import net.minecraft.client.particle.IParticleRenderType
|
||||
import net.minecraft.client.renderer.ActiveRenderInfo
|
||||
import net.minecraft.client.world.ClientWorld
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.MathHelper
|
||||
@@ -23,7 +24,7 @@ import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
class RisingSoulParticle(
|
||||
world: World, pos: BlockPos
|
||||
world: ClientWorld, pos: BlockPos
|
||||
) : AbstractParticle(
|
||||
world, pos.x.toDouble() + 0.5, pos.y.toDouble() + 1.0, pos.z.toDouble() + 0.5
|
||||
) {
|
||||
@@ -32,10 +33,10 @@ class RisingSoulParticle(
|
||||
val initialPhase = randomD(max = PI2)
|
||||
|
||||
init {
|
||||
motionY = 0.1
|
||||
particleGravity = 0.0f
|
||||
yd = 0.1
|
||||
gravity = 0.0f
|
||||
sprite = headIcons[randomI(max = 1024)]
|
||||
maxAge = MathHelper.floor((0.6 + 0.4 * randomD()) * Config.risingSoul.lifetime * 20.0)
|
||||
lifetime = MathHelper.floor((0.6 + 0.4 * randomD()) * Config.risingSoul.lifetime * 20.0)
|
||||
}
|
||||
|
||||
override val isValid: Boolean get() = true
|
||||
@@ -49,12 +50,12 @@ class RisingSoulParticle(
|
||||
particleTrail.addFirst(currentPos.copy())
|
||||
while (particleTrail.size > Config.risingSoul.trailLength) particleTrail.removeLast()
|
||||
|
||||
if (!Config.enabled) setExpired()
|
||||
if (!Config.enabled) remove()
|
||||
}
|
||||
|
||||
override fun renderParticle(vertexBuilder: IVertexBuilder, camera: ActiveRenderInfo, tickDelta: Float) {
|
||||
override fun render(vertexBuilder: IVertexBuilder, camera: ActiveRenderInfo, tickDelta: Float) {
|
||||
var alpha = Config.risingSoul.opacity.toFloat()
|
||||
if (age > maxAge - 40) alpha *= (maxAge - age) / 40.0f
|
||||
if (age > lifetime - 40) alpha *= (lifetime - age) / 40.0f
|
||||
|
||||
renderParticleQuad(
|
||||
vertexBuilder, camera, tickDelta,
|
||||
|
||||
@@ -3,18 +3,18 @@ package mods.betterfoliage.render.pipeline
|
||||
import com.mojang.blaze3d.matrix.MatrixStack
|
||||
import mods.betterfoliage.chunk.BasicBlockCtx
|
||||
import mods.betterfoliage.chunk.BlockCtx
|
||||
import mods.betterfoliage.model.HalfBakedQuad
|
||||
import mods.betterfoliage.model.SpecialRenderModel
|
||||
import mods.betterfoliage.render.lighting.VanillaFullBlockLighting
|
||||
import mods.betterfoliage.render.lighting.VanillaQuadLighting
|
||||
import mods.betterfoliage.render.lighting.VanillaVertexLighter
|
||||
import mods.betterfoliage.model.HalfBakedQuad
|
||||
import mods.betterfoliage.util.Int3
|
||||
import mods.betterfoliage.util.plus
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.ILightReader
|
||||
import net.minecraft.world.IBlockDisplayReader
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import java.util.Random
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.Random
|
||||
* push-based partial rendering pipeline for [SpecialRenderModel] instances.
|
||||
*/
|
||||
abstract class RenderCtxBase(
|
||||
world: ILightReader,
|
||||
world: IBlockDisplayReader,
|
||||
pos: BlockPos,
|
||||
val matrixStack: MatrixStack,
|
||||
var checkSides: Boolean,
|
||||
@@ -36,14 +36,14 @@ abstract class RenderCtxBase(
|
||||
abstract fun renderQuad(quad: HalfBakedQuad)
|
||||
|
||||
var hasRendered = false
|
||||
val blockModelShapes = Minecraft.getInstance().blockRendererDispatcher.blockModelShapes
|
||||
val blockModelShapes = Minecraft.getInstance().blockRenderer.blockModelShaper
|
||||
var vertexLighter: VanillaVertexLighter = VanillaFullBlockLighting
|
||||
protected val lightingData = RenderCtxBase.lightingData.get().apply {
|
||||
calc.reset(this@RenderCtxBase)
|
||||
blockColors = Minecraft.getInstance().blockColors
|
||||
}
|
||||
|
||||
inline fun Direction?.shouldRender() = this == null || !checkSides || Block.shouldSideBeRendered(state, world, pos, this)
|
||||
inline fun Direction?.shouldRender() = this == null || !checkSides || Block.shouldRenderFace(state, world, pos, this)
|
||||
|
||||
fun renderQuads(quads: Iterable<HalfBakedQuad>) {
|
||||
quads.forEach { quad ->
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package mods.betterfoliage.render.pipeline
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack
|
||||
import mods.betterfoliage.model.HalfBakedQuad
|
||||
import mods.betterfoliage.model.SpecialRenderModel
|
||||
import mods.betterfoliage.render.lighting.ForgeVertexLighter
|
||||
import mods.betterfoliage.render.lighting.ForgeVertexLighterAccess
|
||||
import mods.betterfoliage.model.HalfBakedQuad
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.renderer.LightTexture
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.ILightReader
|
||||
import net.minecraft.world.IBlockDisplayReader
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import net.minecraftforge.client.model.pipeline.VertexLighterFlat
|
||||
import java.util.Random
|
||||
|
||||
class RenderCtxForge(
|
||||
world: ILightReader,
|
||||
world: IBlockDisplayReader,
|
||||
pos: BlockPos,
|
||||
val lighter: VertexLighterFlat,
|
||||
matrixStack: MatrixStack,
|
||||
@@ -33,8 +33,8 @@ class RenderCtxForge(
|
||||
var vIdx = 0
|
||||
override fun updateVertexLightmap(normal: FloatArray, lightmap: FloatArray, x: Float, y: Float, z: Float) {
|
||||
lightingData.packedLight[vIdx].let { packedLight ->
|
||||
lightmap[0] = LightTexture.getLightBlock(packedLight) / 0xF.toFloat()
|
||||
lightmap[1] = LightTexture.getLightSky(packedLight) / 0xF.toFloat()
|
||||
lightmap[0] = LightTexture.block(packedLight) / 0xF.toFloat()
|
||||
lightmap[1] = LightTexture.sky(packedLight) / 0xF.toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class RenderCtxForge(
|
||||
@JvmStatic
|
||||
fun render(
|
||||
lighter: VertexLighterFlat,
|
||||
world: ILightReader,
|
||||
world: IBlockDisplayReader,
|
||||
model: SpecialRenderModel,
|
||||
state: BlockState,
|
||||
pos: BlockPos,
|
||||
|
||||
@@ -2,18 +2,18 @@ package mods.betterfoliage.render.pipeline
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder
|
||||
import mods.betterfoliage.model.SpecialRenderModel
|
||||
import mods.betterfoliage.model.HalfBakedQuad
|
||||
import mods.betterfoliage.model.SpecialRenderModel
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.renderer.BlockModelRenderer
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.ILightReader
|
||||
import net.minecraft.world.IBlockDisplayReader
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import java.util.Random
|
||||
|
||||
class RenderCtxVanilla(
|
||||
val renderer: BlockModelRenderer,
|
||||
world: ILightReader,
|
||||
world: IBlockDisplayReader,
|
||||
pos: BlockPos,
|
||||
val buffer: IVertexBuilder,
|
||||
val combinedOverlay: Int,
|
||||
@@ -27,8 +27,8 @@ class RenderCtxVanilla(
|
||||
|
||||
override fun renderQuad(quad: HalfBakedQuad) {
|
||||
vertexLighter.updateLightmapAndColor(quad, lightingData)
|
||||
buffer.addQuad(
|
||||
matrixStack.last, quad.baked,
|
||||
buffer.putBulkData(
|
||||
matrixStack.last(), quad.baked,
|
||||
lightingData.colorMultiplier,
|
||||
lightingData.tint[0], lightingData.tint[1], lightingData.tint[2],
|
||||
lightingData.packedLight, combinedOverlay, true
|
||||
@@ -39,7 +39,7 @@ class RenderCtxVanilla(
|
||||
@JvmStatic
|
||||
fun render(
|
||||
renderer: BlockModelRenderer,
|
||||
world: ILightReader,
|
||||
world: IBlockDisplayReader,
|
||||
model: SpecialRenderModel,
|
||||
state: BlockState,
|
||||
pos: BlockPos,
|
||||
|
||||
@@ -20,7 +20,7 @@ interface VeryEarlyReloadListener : IFutureReloadListener {
|
||||
gameExecutor: Executor
|
||||
): CompletableFuture<Void> {
|
||||
onReloadStarted()
|
||||
return stage.markCompleteAwaitingOthers(null)
|
||||
return stage.wait(null)
|
||||
}
|
||||
|
||||
fun onReloadStarted() {}
|
||||
|
||||
@@ -8,8 +8,8 @@ import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.renderer.model.IBakedModel
|
||||
import net.minecraft.client.renderer.model.IModelTransform
|
||||
import net.minecraft.client.renderer.model.IUnbakedModel
|
||||
import net.minecraft.client.renderer.model.Material
|
||||
import net.minecraft.client.renderer.model.ModelBakery
|
||||
import net.minecraft.client.renderer.model.RenderMaterial
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraftforge.client.event.ModelBakeEvent
|
||||
@@ -30,7 +30,7 @@ data class ModelDefinitionsLoadedEvent(
|
||||
|
||||
interface ModelBakingKey {
|
||||
fun bake(ctx: ModelBakingContext): IBakedModel? =
|
||||
ctx.getUnbaked().bakeModel(ctx.bakery, ctx.spriteGetter, ctx.transform, ctx.location)
|
||||
ctx.getUnbaked().bake(ctx.bakery, ctx.spriteGetter, ctx.transform, ctx.location)
|
||||
}
|
||||
|
||||
interface ModelDiscovery {
|
||||
@@ -49,7 +49,7 @@ data class ModelDiscoveryContext(
|
||||
val replacements: MutableMap<ResourceLocation, ModelBakingKey>,
|
||||
val logger: Logger
|
||||
) {
|
||||
fun getUnbaked(location: ResourceLocation = modelLocation) = bakery.getUnbakedModel(location)
|
||||
fun getUnbaked(location: ResourceLocation = modelLocation) = bakery.getModel(location)
|
||||
fun addReplacement(key: ModelBakingKey, addToStateKeys: Boolean = true) {
|
||||
replacements[modelLocation] = key
|
||||
if (addToStateKeys) BetterFoliage.blockTypes.stateKeys[blockState] = key
|
||||
@@ -59,12 +59,12 @@ data class ModelDiscoveryContext(
|
||||
|
||||
data class ModelBakingContext(
|
||||
val bakery: ModelBakery,
|
||||
val spriteGetter: Function<Material, TextureAtlasSprite>,
|
||||
val spriteGetter: Function<RenderMaterial, TextureAtlasSprite>,
|
||||
val location: ResourceLocation,
|
||||
val transform: IModelTransform,
|
||||
val logger: Logger
|
||||
) {
|
||||
fun getUnbaked() = bakery.getUnbakedModel(location)
|
||||
fun getUnbaked() = bakery.getModel(location)
|
||||
fun getBaked() = bakery.getBakedModel(location, transform, spriteGetter)
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ object BakeWrapperManager : Invalidator, HasLogger() {
|
||||
|
||||
@SubscribeEvent
|
||||
fun handleStitch(event: TextureStitchEvent.Pre) {
|
||||
if (event.map.textureLocation == Atlas.BLOCKS.resourceId) {
|
||||
if (event.map.location() == Atlas.BLOCKS.resourceId) {
|
||||
logger.log(INFO, "Adding ${sprites.size} sprites to block atlas")
|
||||
sprites.forEach { event.addSprite(it) }
|
||||
sprites.clear()
|
||||
@@ -109,7 +109,7 @@ object BakeWrapperManager : Invalidator, HasLogger() {
|
||||
fun onBake(
|
||||
unbaked: IUnbakedModel,
|
||||
bakery: ModelBakery,
|
||||
spriteGetter: Function<Material, TextureAtlasSprite>,
|
||||
spriteGetter: Function<RenderMaterial, TextureAtlasSprite>,
|
||||
transform: IModelTransform,
|
||||
location: ResourceLocation
|
||||
): IBakedModel? {
|
||||
@@ -124,6 +124,6 @@ object BakeWrapperManager : Invalidator, HasLogger() {
|
||||
logger.log(WARN, "Error while baking $replacement", e)
|
||||
}
|
||||
}
|
||||
return unbaked.bakeModel(bakery, spriteGetter, transform, location)
|
||||
return unbaked.bake(bakery, spriteGetter, transform, location)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package mods.betterfoliage.resource.discovery
|
||||
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.util.HasLogger
|
||||
import mods.betterfoliage.util.getJavaClass
|
||||
import mods.betterfoliage.util.getLines
|
||||
@@ -45,8 +44,8 @@ class ConfigurableBlockMatcher(val location: ResourceLocation) : HasLogger(), IB
|
||||
fun readDefaults() {
|
||||
blackList.clear()
|
||||
whiteList.clear()
|
||||
resourceManager.getAllResources(location).forEach { resource ->
|
||||
detailLogger.log(INFO, "Reading block class configuration $location from pack ${resource.packName}")
|
||||
resourceManager.getResources(location).forEach { resource ->
|
||||
detailLogger.log(INFO, "Reading block class configuration $location from pack ${resource.sourceName}")
|
||||
resource.getLines().map{ it.trim() }.filter { !it.startsWith("//") && it.isNotEmpty() }.forEach { line ->
|
||||
if (line.startsWith("-")) getJavaClass(line.substring(1))?.let { blackList.add(it) }
|
||||
else getJavaClass(line)?.let { whiteList.add(it) }
|
||||
@@ -63,8 +62,8 @@ data class ModelTextureList(val modelLocation: ResourceLocation, val textureName
|
||||
class ModelTextureListConfiguration(val location: ResourceLocation) : HasLogger() {
|
||||
val modelList = mutableListOf<ModelTextureList>()
|
||||
fun readDefaults() {
|
||||
resourceManager.getAllResources(location).forEach { resource ->
|
||||
detailLogger.log(INFO, "Reading model/texture configuration $location from pack ${resource.packName}")
|
||||
resourceManager.getResources(location).forEach { resource ->
|
||||
detailLogger.log(INFO, "Reading model/texture configuration $location from pack ${resource.sourceName}")
|
||||
resource.getLines().map{ it.trim() }.filter { !it.startsWith("//") && it.isNotEmpty() }.forEach { line ->
|
||||
val elements = line.split(",")
|
||||
modelList.add(ModelTextureList(ResourceLocation(elements.first()), elements.drop(1)))
|
||||
|
||||
@@ -18,9 +18,9 @@ abstract class AbstractModelDiscovery : HasLogger(), ModelDiscovery {
|
||||
replacements: MutableMap<ResourceLocation, ModelBakingKey>
|
||||
) {
|
||||
ForgeRegistries.BLOCKS
|
||||
.flatMap { block -> block.stateContainer.validStates }
|
||||
.flatMap { block -> block.stateDefinition.possibleStates }
|
||||
.forEach { state ->
|
||||
val location = BlockModelShapes.getModelLocation(state)
|
||||
val location = BlockModelShapes.stateToModelLocation(state)
|
||||
val ctx = ModelDiscoveryContext(bakery, state, location, sprites, replacements, detailLogger)
|
||||
try {
|
||||
processModel(ctx)
|
||||
@@ -38,7 +38,7 @@ abstract class AbstractModelDiscovery : HasLogger(), ModelDiscovery {
|
||||
// per-location replacements need to be scoped to the variant list, as replacement models
|
||||
// may need information from the BlockState which is not available at baking time
|
||||
val scopedReplacements = mutableMapOf<ResourceLocation, ModelBakingKey>()
|
||||
model.variantList.forEach { variant ->
|
||||
model.variants.forEach { variant ->
|
||||
processModel(ctx.copy(modelLocation = variant.modelLocation, replacements = scopedReplacements))
|
||||
}
|
||||
if (scopedReplacements.isNotEmpty()) {
|
||||
@@ -73,15 +73,18 @@ abstract class ConfigurableModelDiscovery : AbstractModelDiscovery() {
|
||||
matches.forEach { match ->
|
||||
detailLogger.log(Level.INFO, " model $model matches ${match.modelLocation}")
|
||||
|
||||
val materials = match.textureNames.map { it to model.resolveTextureName(it) }
|
||||
val texMapString = Joiner.on(", ").join(materials.map { "${it.first}=${it.second.textureLocation}" })
|
||||
detailLogger.log(Level.INFO, " sprites [$texMapString]")
|
||||
val materials = match.textureNames.map { it to model.getMaterial(it) }
|
||||
val texMapString = Joiner.on(", ").join(materials.map { "${it.first}=${it.second.texture()}" })
|
||||
detailLogger.log(Level.INFO, " sprites [$texMapString]")
|
||||
|
||||
if (materials.all { it.second.textureLocation != MissingTextureSprite.getLocation() }) {
|
||||
// found a valid model (all required textures exist)
|
||||
processModel(ctx, materials.map { it.second.textureLocation })
|
||||
}
|
||||
if (materials.all { it.second.texture() != MissingTextureSprite.getLocation() }) {
|
||||
// found a valid model (all required textures exist)
|
||||
processModel(ctx, materials.map { it.second.texture() })
|
||||
}
|
||||
}
|
||||
if (matches.isEmpty()) {
|
||||
detailLogger.log(Level.INFO, " no matches for model ${ctx.modelLocation}, inheritance chain ${ancestry.joinToString(" -> ")}")
|
||||
}
|
||||
}
|
||||
return super.processModel(ctx)
|
||||
}
|
||||
@@ -90,12 +93,12 @@ abstract class ConfigurableModelDiscovery : AbstractModelDiscovery() {
|
||||
fun ModelBakery.modelDerivesFrom(model: BlockModel, location: ResourceLocation, target: ResourceLocation): Boolean =
|
||||
if (location == target) true
|
||||
else model.parentLocation
|
||||
?.let { getUnbakedModel(it) as? BlockModel }
|
||||
?.let { getModel(it) as? BlockModel }
|
||||
?.let { parent -> modelDerivesFrom(parent, model.parentLocation!!, target) }
|
||||
?: false
|
||||
|
||||
fun ModelBakery.getAncestry(location: ResourceLocation): List<ResourceLocation> {
|
||||
val model = getUnbakedModel(location) as? BlockModel ?: return listOf(location)
|
||||
val model = getModel(location) as? BlockModel ?: return listOf(location)
|
||||
val parentAncestry = model.parentLocation?.let { getAncestry(it) } ?: emptyList()
|
||||
return listOf(location) + parentAncestry
|
||||
}
|
||||
@@ -20,7 +20,7 @@ class WeightedUnbakedKey(
|
||||
if (unbaked !is VariantList) return super.bake(ctx)
|
||||
|
||||
// bake all variants, replace as needed
|
||||
val bakedModels = unbaked.variantList.mapNotNull {
|
||||
val bakedModels = unbaked.variants.mapNotNull {
|
||||
val variantCtx = ctx.copy(location = it.modelLocation, transform = it)
|
||||
val replacement = replacements[it.modelLocation]
|
||||
val baked = replacement?.let { replacement ->
|
||||
@@ -40,10 +40,10 @@ class WeightedUnbakedKey(
|
||||
// let it through unchanged
|
||||
if (bakedModels.isEmpty()) return super.bake(ctx)
|
||||
|
||||
if (bakedModels.size < unbaked.variantList.size) {
|
||||
if (bakedModels.size < unbaked.variants.size) {
|
||||
detailLogger.log(
|
||||
WARN,
|
||||
"Dropped ${unbaked.variantList.size - bakedModels.size} variants from model ${ctx.location}"
|
||||
"Dropped ${unbaked.variants.size - bakedModels.size} variants from model ${ctx.location}"
|
||||
)
|
||||
}
|
||||
val weightedSpecials = bakedModels.map { (variant, model) ->
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package mods.betterfoliage.resource.generated
|
||||
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.util.Atlas
|
||||
import mods.betterfoliage.util.HasLogger
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.resources.ClientResourcePackInfo
|
||||
import net.minecraft.resources.*
|
||||
import net.minecraft.resources.ResourcePackType.CLIENT_RESOURCES
|
||||
import net.minecraft.resources.data.IMetadataSectionSerializer
|
||||
@@ -12,6 +10,7 @@ import net.minecraft.util.ResourceLocation
|
||||
import net.minecraft.util.text.StringTextComponent
|
||||
import org.apache.logging.log4j.Level.INFO
|
||||
import java.util.*
|
||||
import java.util.function.Consumer
|
||||
import java.util.function.Predicate
|
||||
import java.util.function.Supplier
|
||||
|
||||
@@ -25,10 +24,10 @@ class GeneratedTexturePack(
|
||||
val nameSpace: String, val packName: String
|
||||
) : HasLogger(), IResourcePack {
|
||||
override fun getName() = packName
|
||||
override fun getResourceNamespaces(type: ResourcePackType) = setOf(nameSpace)
|
||||
override fun <T : Any?> getMetadata(deserializer: IMetadataSectionSerializer<T>) = null
|
||||
override fun getRootResourceStream(id: String) = null
|
||||
override fun getAllResourceLocations(type: ResourcePackType, namespace:String, path: String, maxDepth: Int, filter: Predicate<String>) = emptyList<ResourceLocation>()
|
||||
override fun getNamespaces(type: ResourcePackType) = setOf(nameSpace)
|
||||
override fun <T : Any?> getMetadataSection(deserializer: IMetadataSectionSerializer<T>) = null
|
||||
override fun getRootResource(id: String) = null
|
||||
override fun getResources(type: ResourcePackType, namespace:String, path: String, maxDepth: Int, filter: Predicate<String>) = emptyList<ResourceLocation>()
|
||||
|
||||
override fun close() {}
|
||||
|
||||
@@ -49,21 +48,22 @@ class GeneratedTexturePack(
|
||||
return id
|
||||
}
|
||||
|
||||
override fun getResourceStream(type: ResourcePackType, id: ResourceLocation) =
|
||||
override fun getResource(type: ResourcePackType, id: ResourceLocation) =
|
||||
if (type != CLIENT_RESOURCES) null else resources[id]?.inputStream()
|
||||
|
||||
override fun resourceExists(type: ResourcePackType, id: ResourceLocation) =
|
||||
override fun hasResource(type: ResourcePackType, id: ResourceLocation) =
|
||||
type == CLIENT_RESOURCES && resources.containsKey(id)
|
||||
|
||||
val finder = object : IPackFinder {
|
||||
val packInfo = ClientResourcePackInfo(
|
||||
val packInfo = ResourcePackInfo(
|
||||
packName, true, Supplier { this@GeneratedTexturePack },
|
||||
StringTextComponent(packName),
|
||||
StringTextComponent("Generated block textures resource pack"),
|
||||
PackCompatibility.COMPATIBLE, ResourcePackInfo.Priority.TOP, true, null, true
|
||||
PackCompatibility.COMPATIBLE, ResourcePackInfo.Priority.TOP, true, IPackNameDecorator.DEFAULT, true
|
||||
)
|
||||
override fun <T : ResourcePackInfo> addPackInfosToMap(nameToPackMap: MutableMap<String, T>, packInfoFactory: ResourcePackInfo.IFactory<T>) {
|
||||
(nameToPackMap as MutableMap<String, ResourcePackInfo>).put(packName, packInfo)
|
||||
|
||||
override fun loadPacks(p0: Consumer<ResourcePackInfo>, p1: ResourcePackInfo.IFactory) {
|
||||
p0.accept(packInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package mods.betterfoliage.util
|
||||
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.block.material.Material
|
||||
|
||||
|
||||
|
||||
val DIRT_BLOCKS = listOf(Blocks.DIRT, Blocks.COARSE_DIRT)
|
||||
@@ -1,12 +1,12 @@
|
||||
package mods.betterfoliage.util
|
||||
|
||||
import net.minecraft.client.renderer.Quaternion
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.Direction.*
|
||||
import net.minecraft.util.Direction.Axis.*
|
||||
import net.minecraft.util.Direction.AxisDirection.NEGATIVE
|
||||
import net.minecraft.util.Direction.AxisDirection.POSITIVE
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.vector.Quaternion
|
||||
|
||||
val EPSILON_ZERO = 0.05
|
||||
val EPSILON_ONE = 0.95
|
||||
@@ -55,15 +55,15 @@ val ROTATION_MATRIX: Array<IntArray> get() = arrayOf(
|
||||
// Vectors
|
||||
// ================================
|
||||
operator fun Direction.times(scale: Double) =
|
||||
Double3(directionVec.x.toDouble() * scale, directionVec.y.toDouble() * scale, directionVec.z.toDouble() * scale)
|
||||
val Direction.vec: Double3 get() = Double3(directionVec.x.toDouble(), directionVec.y.toDouble(), directionVec.z.toDouble())
|
||||
Double3(normal.x.toDouble() * scale, normal.y.toDouble() * scale, normal.z.toDouble() * scale)
|
||||
val Direction.vec: Double3 get() = Double3(normal.x.toDouble(), normal.y.toDouble(), normal.z.toDouble())
|
||||
|
||||
operator fun BlockPos.plus(other: Int3) = BlockPos(x + other.x, y + other.y, z + other.z)
|
||||
|
||||
/** 3D vector of [Double]s. Offers both mutable operations, and immutable operations in operator notation. */
|
||||
data class Double3(var x: Double, var y: Double, var z: Double) {
|
||||
constructor(x: Float, y: Float, z: Float) : this(x.toDouble(), y.toDouble(), z.toDouble())
|
||||
constructor(dir: Direction) : this(dir.directionVec.x.toDouble(), dir.directionVec.y.toDouble(), dir.directionVec.z.toDouble())
|
||||
constructor(dir: Direction) : this(dir.normal.x.toDouble(), dir.normal.y.toDouble(), dir.normal.z.toDouble())
|
||||
companion object {
|
||||
val zero: Double3 get() = Double3(0.0, 0.0, 0.0)
|
||||
fun weight(v1: Double3, weight1: Double, v2: Double3, weight2: Double) =
|
||||
@@ -88,9 +88,9 @@ data class Double3(var x: Double, var y: Double, var z: Double) {
|
||||
/** Rotate vector by the given [Quaternion] */
|
||||
fun rotate(quat: Quaternion) =
|
||||
quat.copy()
|
||||
.apply { multiply(Quaternion(x, y, z, 0.0F)) }
|
||||
.apply { multiply(quat.copy().apply(Quaternion::conjugate)) }
|
||||
.let { Double3(it.x, it.y, it.z) }
|
||||
.apply { mul(Quaternion(x.toFloat(), y.toFloat(), z.toFloat(), 0.0F)) }
|
||||
.apply { mul(quat.copy().apply(Quaternion::conj)) }
|
||||
.let { Double3(it.i().toDouble(), it.j().toDouble(), it.k().toDouble()) }
|
||||
|
||||
// mutable operations
|
||||
fun setTo(other: Double3): Double3 { x = other.x; y = other.y; z = other.z; return this }
|
||||
@@ -120,11 +120,11 @@ data class Double3(var x: Double, var y: Double, var z: Double) {
|
||||
|
||||
/** 3D vector of [Int]s. Offers both mutable operations, and immutable operations in operator notation. */
|
||||
data class Int3(var x: Int, var y: Int, var z: Int) {
|
||||
constructor(dir: Direction) : this(dir.directionVec.x, dir.directionVec.y, dir.directionVec.z)
|
||||
constructor(dir: Direction) : this(dir.normal.x, dir.normal.y, dir.normal.z)
|
||||
constructor(offset: Pair<Int, Direction>) : this(
|
||||
offset.first * offset.second.directionVec.x,
|
||||
offset.first * offset.second.directionVec.y,
|
||||
offset.first * offset.second.directionVec.z
|
||||
offset.first * offset.second.normal.x,
|
||||
offset.first * offset.second.normal.y,
|
||||
offset.first * offset.second.normal.z
|
||||
)
|
||||
companion object {
|
||||
val zero = Int3(0, 0, 0)
|
||||
@@ -133,9 +133,9 @@ data class Int3(var x: Int, var y: Int, var z: Int) {
|
||||
// immutable operations
|
||||
operator fun plus(other: Int3) = Int3(x + other.x, y + other.y, z + other.z)
|
||||
operator fun plus(other: Pair<Int, Direction>) = Int3(
|
||||
x + other.first * other.second.directionVec.x,
|
||||
y + other.first * other.second.directionVec.y,
|
||||
z + other.first * other.second.directionVec.z
|
||||
x + other.first * other.second.normal.x,
|
||||
y + other.first * other.second.normal.y,
|
||||
z + other.first * other.second.normal.z
|
||||
)
|
||||
operator fun unaryMinus() = Int3(-x, -y, -z)
|
||||
operator fun minus(other: Int3) = Int3(x - other.x, y - other.y, z - other.z)
|
||||
|
||||
@@ -7,16 +7,19 @@ import net.minecraft.util.text.TextFormatting
|
||||
import net.minecraft.util.text.TextFormatting.AQUA
|
||||
import net.minecraft.util.text.TextFormatting.GRAY
|
||||
|
||||
fun stripTooltipDefaultText(tooltip: MutableList<String>) {
|
||||
var defaultRows = false
|
||||
val iter = tooltip.iterator()
|
||||
while (iter.hasNext()) {
|
||||
if (iter.next().startsWith(AQUA.toString())) defaultRows = true
|
||||
if (defaultRows) iter.remove()
|
||||
}
|
||||
}
|
||||
//fun stripTooltipDefaultText(tooltip: MutableList<String>) {
|
||||
// var defaultRows = false
|
||||
// val iter = tooltip.iterator()
|
||||
// while (iter.hasNext()) {
|
||||
// if (iter.next().startsWith(AQUA.toString())) defaultRows = true
|
||||
// if (defaultRows) iter.remove()
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//fun textComponent(msg: String, color: TextFormatting = GRAY): StringTextComponent {
|
||||
// val style = Style().apply { this.color = color }
|
||||
// return StringTextComponent(msg).apply { this.style = style }
|
||||
//}
|
||||
val styleGray = Style.EMPTY.applyFormats(GRAY)
|
||||
|
||||
fun textComponent(msg: String, color: TextFormatting = GRAY): StringTextComponent {
|
||||
val style = Style().apply { this.color = color }
|
||||
return StringTextComponent(msg).apply { this.style = style }
|
||||
}
|
||||
fun String.asText() = StringTextComponent(this).setStyle(styleGray)
|
||||
@@ -1,8 +1,6 @@
|
||||
package mods.betterfoliage.util
|
||||
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.renderer.model.Material
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture
|
||||
import net.minecraft.resources.IReloadableResourceManager
|
||||
import net.minecraft.resources.IResource
|
||||
import net.minecraft.resources.IResourceManager
|
||||
@@ -19,11 +17,6 @@ operator fun ResourceLocation.plus(str: String) = ResourceLocation(namespace, pa
|
||||
fun ResourceLocation.prependLocation(basePath: String) =
|
||||
ResourceLocation(namespace, basePath.stripEnd("/").let { "$it/$path" })
|
||||
|
||||
val ResourceLocation.asBlockMaterial: Material get() = Material(
|
||||
AtlasTexture.LOCATION_BLOCKS_TEXTURE,
|
||||
this
|
||||
)
|
||||
|
||||
/** Index operator to get a resource. */
|
||||
operator fun IResourceManager.get(domain: String, path: String): IResource? = get(ResourceLocation(domain, path))
|
||||
/** Index operator to get a resource. */
|
||||
|
||||
@@ -3,7 +3,6 @@ package mods.betterfoliage.util
|
||||
import mods.betterfoliage.model.Color
|
||||
import mods.betterfoliage.model.HSB
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.renderer.model.Material
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite
|
||||
import net.minecraft.resources.IResource
|
||||
@@ -20,8 +19,8 @@ import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
enum class Atlas(val resourceId: ResourceLocation) {
|
||||
BLOCKS(AtlasTexture.LOCATION_BLOCKS_TEXTURE),
|
||||
PARTICLES(AtlasTexture.LOCATION_PARTICLES_TEXTURE);
|
||||
BLOCKS(AtlasTexture.LOCATION_BLOCKS),
|
||||
PARTICLES(AtlasTexture.LOCATION_PARTICLES);
|
||||
|
||||
/** Get the fully-qualified resource name for sprites belonging to this atlas */
|
||||
fun file(resource: ResourceLocation) = ResourceLocation(resource.namespace, "textures/${resource.path}.png")
|
||||
@@ -33,7 +32,7 @@ enum class Atlas(val resourceId: ResourceLocation) {
|
||||
operator fun get(location: ResourceLocation) = atlas.getSprite(location)
|
||||
}
|
||||
|
||||
val Material.atlas: Atlas get() = Atlas.values().find { it.resourceId == atlasLocation } ?: Atlas.BLOCKS
|
||||
//val Spr.atlas: Atlas get() = Atlas.values().find { it.resourceId == atlasLocation } ?: Atlas.BLOCKS
|
||||
|
||||
inline operator fun AtlasTexture.get(res: ResourceLocation): TextureAtlasSprite? = this.getSprite(res)
|
||||
inline operator fun AtlasTexture.get(name: String): TextureAtlasSprite? = get(ResourceLocation(name))
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
#public net.minecraft.client.renderer.BlockModelRenderer$AmbientOcclusionFace
|
||||
#public net.minecraft.client.renderer.BlockModelRenderer$AmbientOcclusionFace <init>
|
||||
#public net.minecraft.client.renderer.BlockModelRenderer$AmbientOcclusionFace field_178206_b #vertexColorMultiplier
|
||||
#public net.minecraft.client.renderer.BlockModelRenderer$AmbientOcclusionFace field_178207_c #vertexBrightness
|
||||
|
||||
#public net.minecraft.block.BlockState$Cache
|
||||
|
||||
public net.minecraft.client.renderer.chunk.ChunkRenderCache field_212408_i #world
|
||||
|
||||
#public net.minecraft.client.renderer.texture.AtlasTexture$SheetData field_217808_d # sprites
|
||||
|
||||
public net.minecraft.client.renderer.BlockModelRenderer$Cache
|
||||
public net.minecraft.client.renderer.BlockModelRenderer field_210267_b
|
||||
public net.minecraft.client.renderer.BlockModelRenderer field_187499_a
|
||||
public net.minecraft.client.renderer.BlockModelRenderer field_187499_a
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
modLoader="kotlinfml"
|
||||
loaderVersion="[1.4,)"
|
||||
modLoader="kotlinforforge"
|
||||
loaderVersion="[1,)"
|
||||
issueTrackerURL="https://github.com/octarine-noise/BetterFoliage/issues"
|
||||
|
||||
license="MIT"
|
||||
[[mods]]
|
||||
modId="betterfoliage"
|
||||
version="${version}"
|
||||
|
||||
177
src/main/resources/assets/betterfoliage/lang/en_us.json
Normal file
177
src/main/resources/assets/betterfoliage/lang/en_us.json
Normal file
@@ -0,0 +1,177 @@
|
||||
{
|
||||
"key.betterfoliage.gui": "Open Settings",
|
||||
|
||||
"betterfoliage.title": "Better Foliage configuration",
|
||||
|
||||
"betterfoliage.global.enabled": "Enable Mod",
|
||||
"betterfoliage.global.enabled.tooltip": "If set to false, BetterFoliage will not render anything",
|
||||
"betterfoliage.nVidia": "nVidia GPU",
|
||||
"betterfoliage.nVidia.tooltip": "Specify whether you have an nVidia GPU",
|
||||
|
||||
"betterfoliage.enabled": "Enable",
|
||||
"betterfoliage.enabled.tooltip": "Is this feature enabled?",
|
||||
"betterfoliage.hOffset": "Horizontal offset",
|
||||
"betterfoliage.hOffset.tooltip": "The distance this element is shifted horizontally, in blocks",
|
||||
"betterfoliage.vOffset": "Vertical offset",
|
||||
"betterfoliage.vOffset.tooltip": "The distance this element is shifted vertically, in blocks",
|
||||
"betterfoliage.size": "Size",
|
||||
"betterfoliage.size.tooltip": "Size of this element",
|
||||
"betterfoliage.heightMin": "Minimum height",
|
||||
"betterfoliage.heightMin.tooltip": "Minimum height of element",
|
||||
"betterfoliage.heightMax": "Maximum height",
|
||||
"betterfoliage.heightMax.tooltip": "Maximum height of element",
|
||||
"betterfoliage.population": "Population",
|
||||
"betterfoliage.population.tooltip": "Chance (N in 64) that an eligible block will have this feature",
|
||||
"betterfoliage.shaderWind": "Shader wind effects",
|
||||
"betterfoliage.shaderWind.tooltip": "Apply wind effects from ShaderMod shaders to this element?",
|
||||
"betterfoliage.distance": "Distance limit",
|
||||
"betterfoliage.distance.tooltip": "Maximum distance from player at which to render this feature",
|
||||
"betterfoliage.saturationThreshold": "Saturation threshold",
|
||||
"betterfoliage.saturationThreshold.tooltip": "Color saturation cutoff between \"colorless\" blocks (using biome color) and \"colorful\" blocks (using their own specific color)",
|
||||
|
||||
"betterfoliage.rendererror": "§a[BetterFoliage]§f Error rendering block %s at position %s",
|
||||
|
||||
"betterfoliage.shaders": "Shader configuration",
|
||||
"betterfoliage.shaders.tooltip": "Configure integration with shaders",
|
||||
"betterfoliage.shaders.leavesId": "Leaves ID",
|
||||
"betterfoliage.shaders.leavesId.tooltip": "Block ID reported to shader programs for all kinds of leaves. If your shader uses a §6block.properties§e file, you'll probably need to change this to match the shader's mappings.",
|
||||
"betterfoliage.shaders.grassId": "Grass ID",
|
||||
"betterfoliage.shaders.grassId.tooltip": "Block ID reported to shader programs for all grasses and crops. If your shader uses a §6block.properties§e file, you'll probably need to change this to match the shader's mappings.",
|
||||
|
||||
"betterfoliage.leaves": "Extra Leaves",
|
||||
"betterfoliage.leaves.tooltip": "Extra round leaves on leaf blocks",
|
||||
"betterfoliage.leaves.dense": "Dense mode",
|
||||
"betterfoliage.leaves.dense.tooltip": "Dense mode has more round leaves",
|
||||
"betterfoliage.leaves.snowEnabled": "Enable snow",
|
||||
"betterfoliage.leaves.snowEnabled.tooltip": "Enable snow on extra leaves?",
|
||||
"betterfoliage.leaves.hideInternal": "Hide internal leaves",
|
||||
"betterfoliage.leaves.hideInternal.tooltip": "Skip rendering extra leaves if leaf block is completely surrounded by other leaves or solid blocks",
|
||||
|
||||
"betterfoliage.shortGrass": "Short Grass & Mycelium",
|
||||
"betterfoliage.shortGrass.tooltip": "Tufts of grass/mycelium on top of appropriate blocks",
|
||||
"betterfoliage.shortGrass.useGenerated": "Use generated texture for grass",
|
||||
"betterfoliage.shortGrass.useGenerated.tooltip": "Generated texture is made by slicing the tallgrass texture from the active resource pack in half",
|
||||
"betterfoliage.shortGrass.myceliumEnabled": "Enable Mycelium",
|
||||
"betterfoliage.shortGrass.myceliumEnabled.tooltip": "Is this feature enabled for mycelium blocks?",
|
||||
"betterfoliage.shortGrass.grassEnabled": "Enable Grass",
|
||||
"betterfoliage.shortGrass.grassEnabled.tooltip": "Is this feature enabled for grass blocks?",
|
||||
"betterfoliage.shortGrass.snowEnabled": "Enable under snow",
|
||||
"betterfoliage.shortGrass.snowEnabled.tooltip": "Enable on snowed grass blocks?",
|
||||
|
||||
"betterfoliage.connectedGrass": "Connected grass textures",
|
||||
"betterfoliage.connectedGrass.tooltip": "Connected grass textures",
|
||||
"betterfoliage.connectedGrass.enabled": "Enable",
|
||||
"betterfoliage.connectedGrass.enabled.tooltip": "If there is a grass block on top of a dirt block: draw grass top texture on all grass block sides,",
|
||||
"betterfoliage.connectedGrass.snowEnabled": "Enable under snow",
|
||||
"betterfoliage.connectedGrass.snowEnabled.tooltip": "Enable on snowed grass blocks?",
|
||||
|
||||
"betterfoliage.hangingGrass": "Hanging Grass",
|
||||
"betterfoliage.hangingGrass.tooltip": "Grass tufts hanging down from the top edges of grass blocks",
|
||||
"betterfoliage.hangingGrass.separation": "Separation",
|
||||
"betterfoliage.hangingGrass.separation.tooltip": "How much the hanging grass stands out from the block",
|
||||
|
||||
"betterfoliage.cactus": "Better Cactus",
|
||||
"betterfoliage.cactus.tooltip": "Enhance cactus with extra bits and smooth shading",
|
||||
"betterfoliage.cactus.sizeVariation": "Size variation",
|
||||
"betterfoliage.cactus.sizeVariation.tooltip": "Amount of random variation on cactus size",
|
||||
|
||||
"betterfoliage.lilypad": "Better Lilypad",
|
||||
"betterfoliage.lilypad.tooltip": "Enhance lilypad with roots and occasional flowers",
|
||||
"betterfoliage.lilypad.flowerChance": "Flower chance",
|
||||
"betterfoliage.lilypad.flowerChance.tooltip": "Chance (N in 64) of a lilypad having a flower on it",
|
||||
|
||||
"betterfoliage.reed": "Reeds",
|
||||
"betterfoliage.reed.tooltip": "Reeds on dirt blocks in shallow water",
|
||||
"betterfoliage.reed.biomes": "Biome List",
|
||||
"betterfoliage.reed.biomes.tooltip": "Configure which biomes reeds are allowed to appear in",
|
||||
"betterfoliage.reed.biomes.tooltip.element": "Should reeds appear in the %s biome?",
|
||||
|
||||
"betterfoliage.algae": "Algae",
|
||||
"betterfoliage.algae.tooltip": "Algae on dirt blocks in deep water",
|
||||
"betterfoliage.algae.biomes": "Biome List",
|
||||
"betterfoliage.algae.biomes.tooltip": "Configure which biomes algae is allowed to appear in",
|
||||
"betterfoliage.algae.biomes.tooltip.element": "Should algae appear in the %s biome?",
|
||||
|
||||
"betterfoliage.coral": "Coral",
|
||||
"betterfoliage.coral.tooltip": "Coral on sand blocks in deep water",
|
||||
"betterfoliage.coral.size": "Coral size",
|
||||
"betterfoliage.coral.size.tooltip": "Size of coral bits sticking out",
|
||||
"betterfoliage.coral.crustSize": "Crust size",
|
||||
"betterfoliage.coral.crustSize.tooltip": "Size of the flat coral part",
|
||||
"betterfoliage.coral.chance": "Coral chance",
|
||||
"betterfoliage.coral.chance.tooltip": "Chance (N in 64) of a specific face of the block to show coral",
|
||||
"betterfoliage.coral.biomes": "Biome List",
|
||||
"betterfoliage.coral.biomes.tooltip": "Configure which biomes coral is allowed to appear in",
|
||||
"betterfoliage.coral.biomes.tooltip.element": "Should coral appear in the %s biome?",
|
||||
"betterfoliage.coral.shallowWater": "Shallow water coral",
|
||||
"betterfoliage.coral.shallowWater.tooltip": "Should coral appear in 1 block deep water?",
|
||||
|
||||
"betterfoliage.netherrack": "Netherrack Vines",
|
||||
"betterfoliage.netherrack.tooltip": "Hanging Vines under netherrack",
|
||||
|
||||
"betterfoliage.fallingLeaves": "Falling leaves",
|
||||
"betterfoliage.fallingLeaves.tooltip": "Falling leaf particle FX emitted from the bottom of leaf blocks",
|
||||
"betterfoliage.fallingLeaves.speed": "Particle speed",
|
||||
"betterfoliage.fallingLeaves.speed.tooltip": "Overall particle speed",
|
||||
"betterfoliage.fallingLeaves.windStrength": "Wind strength",
|
||||
"betterfoliage.fallingLeaves.windStrength.tooltip": "Magnitude of wind effects in good weather (spread of normal distribution centered on 0)",
|
||||
"betterfoliage.fallingLeaves.stormStrength": "Storm strength",
|
||||
"betterfoliage.fallingLeaves.stormStrength.tooltip": "Additional magnitude of wind effects in rainy weather (spread of normal distribution centered on 0)",
|
||||
"betterfoliage.fallingLeaves.size": "Particle size",
|
||||
"betterfoliage.fallingLeaves.chance": "Particle chance",
|
||||
"betterfoliage.fallingLeaves.chance.tooltip": "Chance of each random render tick hitting a leaf block to spawn a particle",
|
||||
"betterfoliage.fallingLeaves.perturb": "Perturbation",
|
||||
"betterfoliage.fallingLeaves.perturb.tooltip": "Magnitude of perturbation effect. Adds a corkscrew-like motion to the particle synchronized to its rotation",
|
||||
"betterfoliage.fallingLeaves.lifetime": "Maximum lifetime",
|
||||
"betterfoliage.fallingLeaves.lifetime.tooltip": "Maximum lifetime of particle in seconds. Minimum lifetime is 60%% of this value",
|
||||
"betterfoliage.fallingLeaves.opacityHack": "Opaque particles",
|
||||
"betterfoliage.fallingLeaves.opacityHack.tooltip": "Stop transparent blocks obscuring particles even when particle is in front. WARNING: may cause glitches.",
|
||||
|
||||
"betterfoliage.risingSoul": "Rising souls",
|
||||
"betterfoliage.risingSoul.tooltip": "Rising soul particle FX emitted from the top of soulsand blocks",
|
||||
"betterfoliage.risingSoul.chance": "Particle chance",
|
||||
"betterfoliage.risingSoul.chance.tooltip": "Chance of each random render tick hitting a soulsand block to spawn a particle",
|
||||
"betterfoliage.risingSoul.speed": "Particle speed",
|
||||
"betterfoliage.risingSoul.speed.tooltip": "Vertical speed of soul particles",
|
||||
"betterfoliage.risingSoul.perturb": "Perturbation",
|
||||
"betterfoliage.risingSoul.perturb.tooltip": "Magnitude of perturbation effect. Adds a corkscrew-like motion to the particle",
|
||||
"betterfoliage.risingSoul.headSize": "Soul size",
|
||||
"betterfoliage.risingSoul.headSize.tooltip": "Size of the soul particle",
|
||||
"betterfoliage.risingSoul.trailSize": "Trail size",
|
||||
"betterfoliage.risingSoul.trailSize.tooltip": "Initial size of the particle trail",
|
||||
"betterfoliage.risingSoul.opacity": "Opacity",
|
||||
"betterfoliage.risingSoul.opacity.tooltip": "Opacity of the particle effect",
|
||||
"betterfoliage.risingSoul.sizeDecay": "Size decay",
|
||||
"betterfoliage.risingSoul.sizeDecay.tooltip": "Trail particle size relative to its size in the previous tick",
|
||||
"betterfoliage.risingSoul.opacityDecay": "Opacity decay",
|
||||
"betterfoliage.risingSoul.opacityDecay.tooltip": "Trail particle opacity relative to its opacity in the previous tick",
|
||||
"betterfoliage.risingSoul.lifetime": "Maximum lifetime",
|
||||
"betterfoliage.risingSoul.lifetime.tooltip": "Maximum lifetime of particle effect in seconds. Minimum lifetime is 60%% of this value",
|
||||
"betterfoliage.risingSoul.trailLength": "Trail length",
|
||||
"betterfoliage.risingSoul.trailLength.tooltip": "Number of previous positions the particle remembers in ticks",
|
||||
"betterfoliage.risingSoul.trailDensity": "Trail density",
|
||||
"betterfoliage.risingSoul.trailDensity.tooltip": "Render every Nth previous position in the particle trail",
|
||||
|
||||
"betterfoliage.roundLogs": "Round Logs",
|
||||
"betterfoliage.roundLogs.tooltip": "Round Logs",
|
||||
"betterfoliage.roundLogs.connectSolids": "Connect to solid",
|
||||
"betterfoliage.roundLogs.connectSolids.tooltip": "Connect round blocks to solid full blocks?",
|
||||
"betterfoliage.roundLogs.connectPerpendicular": "Connect to perpendicular logs",
|
||||
"betterfoliage.roundLogs.connectPerpendicular.tooltip": "Connect round logs to perpendicular logs along its axis?",
|
||||
"betterfoliage.roundLogs.lenientConnect": "Lenient rounding",
|
||||
"betterfoliage.roundLogs.lenientConnect.tooltip": "Connect parallel round logs in an L-shape too, not just 2x2",
|
||||
"betterfoliage.roundLogs.connectGrass": "Connect Grass",
|
||||
"betterfoliage.roundLogs.connectGrass.tooltip": "Render grass block under trees instead of dirt if there is grass nearby",
|
||||
"betterfoliage.roundLogs.radiusSmall": "Chamfer radius",
|
||||
"betterfoliage.roundLogs.radiusSmall.tooltip": "How much to chop off from the log corner",
|
||||
"betterfoliage.roundLogs.radiusLarge": "Connected chamfer radius",
|
||||
"betterfoliage.roundLogs.radiusLarge.tooltip": "How much to chop off from the outer corner of connected logs",
|
||||
"betterfoliage.roundLogs.dimming": "Dimming",
|
||||
"betterfoliage.roundLogs.dimming.tooltip": "Amount to darken obscured log faces",
|
||||
"betterfoliage.roundLogs.zProtection": "Z-Protection",
|
||||
"betterfoliage.roundLogs.zProtection.tooltip": "Amount to scale parallel log connection bits to stop Z-fighting (flickering). Try to set it as high as possible without having glitches.",
|
||||
"betterfoliage.roundLogs.defaultY": "Default to vertical",
|
||||
"betterfoliage.roundLogs.defaultY.tooltip": "If true, log blocks where the orientation cannot be determined will be rendered as vertical. Otherwise, they will be rendered as cube blocks.",
|
||||
"betterfoliage.roundLogs.plantsOnly": "Plants only",
|
||||
"betterfoliage.roundLogs.plantsOnly.tooltip": "If true, only blocks with plant materials (wood, grass) will be rounded. If false, all column blocks will be rounded, including stone columns."
|
||||
}
|
||||
@@ -1,250 +0,0 @@
|
||||
key.betterfoliage.gui=Open Settings
|
||||
|
||||
betterfoliage.global.enabled=Enable Mod
|
||||
betterfoliage.global.enabled.tooltip=If set to false, BetterFoliage will not render anything
|
||||
betterfoliage.global.nVidia=nVidia GPU
|
||||
betterfoliage.global.nVidia.tooltip=Specify whether you have an nVidia GPU
|
||||
|
||||
betterfoliage.enabled=Enable
|
||||
betterfoliage.enabled.tooltip=Is this feature enabled?
|
||||
betterfoliage.hOffset=Horizontal offset
|
||||
betterfoliage.hOffset.tooltip=The distance this element is shifted horizontally, in blocks
|
||||
betterfoliage.vOffset=Vertical offset
|
||||
betterfoliage.vOffset.tooltip=The distance this element is shifted vertically, in blocks
|
||||
betterfoliage.size=Size
|
||||
betterfoliage.size.tooltip=Size of this element
|
||||
betterfoliage.heightMin=Minimum height
|
||||
betterfoliage.heightMin.tooltip=Minimum height of element
|
||||
betterfoliage.heightMax=Maximum height
|
||||
betterfoliage.heightMax.tooltip=Maximum height of element
|
||||
betterfoliage.population=Population
|
||||
betterfoliage.population.tooltip=Chance (N in 64) that an eligible block will have this feature
|
||||
betterfoliage.shaderWind=Shader wind effects
|
||||
betterfoliage.shaderWind.tooltip=Apply wind effects from ShaderMod shaders to this element?
|
||||
betterfoliage.distance=Distance limit
|
||||
betterfoliage.distance.tooltip=Maximum distance from player at which to render this feature
|
||||
|
||||
betterfoliage.rendererror=§a[BetterFoliage]§f Error rendering block %s at position %s
|
||||
|
||||
betterfoliage.blocks=Block Types
|
||||
betterfoliage.blocks.tooltip=Configure lists of block classes that will have specific features applied to them
|
||||
|
||||
betterfoliage.blocks.dirtWhitelist=Dirt Whitelist
|
||||
betterfoliage.blocks.dirtBlacklist=Dirt Blacklist
|
||||
betterfoliage.blocks.dirtWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.dirtBlacklist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.dirtWhitelist.tooltip=Blocks recognized as Dirt. Has an impact on Reeds, Algae, Connected Grass
|
||||
betterfoliage.blocks.dirtBlacklist.tooltip=Blocks never accepted as Dirt. Has an impact on Reeds, Algae, Connected Grass
|
||||
|
||||
betterfoliage.blocks.grassClassesWhitelist=Grass Whitelist
|
||||
betterfoliage.blocks.grassClassesBlacklist=Grass Blacklist
|
||||
betterfoliage.blocks.grassClassesWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.grassClassesBlacklist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.grassModels=Grass Models
|
||||
betterfoliage.blocks.grassModels.arrayEntry=%d entries
|
||||
betterfoliage.blocks.grassWhitelist.tooltip=Blocks recognized as Grass. Has an impact on Short Grass, Connected Grass
|
||||
betterfoliage.blocks.grassBlacklist.tooltip=Blocks never accepted as Grass. Has an impact on Short Grass, Connected Grass
|
||||
betterfoliage.blocks.grassModels.tooltip=Models and textures recognized for grass blocks
|
||||
|
||||
betterfoliage.blocks.leavesClassesWhitelist=Leaves Whitelist
|
||||
betterfoliage.blocks.leavesClassesBlacklist=Leaves Blacklist
|
||||
betterfoliage.blocks.leavesClassesWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.leavesClassesBlacklist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.leavesModels=Leaves Models
|
||||
betterfoliage.blocks.leavesModels.arrayEntry=%d entries
|
||||
betterfoliage.blocks.leavesClassesWhitelist.tooltip=Blocks recognized as Leaves. Has an impact on Extra Leaves, Falling Leaves. Leaves will render with leaves block ID in shader programs
|
||||
betterfoliage.blocks.leavesClassesBlacklist.tooltip=Blocks never accepted as Leaves. Has an impact on Extra Leaves, Falling Leaves. Leaves will render with leaves block ID in shader programs
|
||||
betterfoliage.blocks.leavesModels.tooltip=Models and textures recognized for leaves blocks
|
||||
|
||||
betterfoliage.blocks.cropsWhitelist=Crop Whitelist
|
||||
betterfoliage.blocks.cropsBlacklist=Crop Blacklist
|
||||
betterfoliage.blocks.cropsWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.cropsBlacklist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.cropsWhitelist.tooltip=Blocks recognized as crops. Crops will render with tallgrass block ID in shader programs
|
||||
betterfoliage.blocks.cropsBlacklist.tooltip=Blocks never accepted as crops. Crops will render with tallgrass block ID in shader programs
|
||||
|
||||
betterfoliage.blocks.logClassesWhitelist=Wood Log Whitelist
|
||||
betterfoliage.blocks.logClassesBlacklist=Wood Log Blacklist
|
||||
betterfoliage.blocks.logClassesWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.logClassesBlacklist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.logModels=Wood Log Models
|
||||
betterfoliage.blocks.logModels.arrayEntry=%d entries
|
||||
betterfoliage.blocks.logClassesWhitelist.tooltip=Blocks recognized as wooden logs. Has an impact on Rounded Logs
|
||||
betterfoliage.blocks.logClassesBlacklist.tooltip=Blocks never accepted as wooden logs. Has an impact on Rounded Logs
|
||||
betterfoliage.blocks.logModels.tooltip=Models and textures recognized for wood log blocks
|
||||
|
||||
betterfoliage.blocks.sandWhitelist=Sand Whitelist
|
||||
betterfoliage.blocks.sandBlacklist=Sand Blacklist
|
||||
betterfoliage.blocks.sandWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.sandBlacklist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.sandWhitelist.tooltip=Blocks recognized as Sand. Has an impact on Coral
|
||||
betterfoliage.blocks.sandBlacklist.tooltip=Blocks never accepted Sand. Has an impact on Coral
|
||||
|
||||
betterfoliage.blocks.lilypadWhitelist=Lilypad Whitelist
|
||||
betterfoliage.blocks.lilypadBlacklist=Lilypad Blacklist
|
||||
betterfoliage.blocks.lilypadWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.lilypadBlacklist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.lilypadWhitelist.tooltip=Blocks recognized as Lilypad. Has an impact on Better Lilypad
|
||||
betterfoliage.blocks.lilypadBlacklist.tooltip=Blocks never accepted Lilypad. Has an impact on Better Lilypad
|
||||
|
||||
betterfoliage.blocks.cactusWhitelist=Cactus Whitelist
|
||||
betterfoliage.blocks.cactusBlacklist=Cactus Blacklist
|
||||
betterfoliage.blocks.cactusWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.cactusBlacklist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.cactusWhitelist.tooltip=Blocks recognized as Cactus. Has an impact on Better Cactus
|
||||
betterfoliage.blocks.cactusBlacklist.tooltip=Blocks never accepted Cactus. Has an impact on Better Cactus
|
||||
|
||||
betterfoliage.blocks.myceliumWhitelist=Mycelium Whitelist
|
||||
betterfoliage.blocks.myceliumBlacklist=Mycelium Blacklist
|
||||
betterfoliage.blocks.myceliumWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.myceliumBlacklist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.myceliumWhitelist.tooltip=Blocks recognized as Mycelium. Has an impact on Better Grass
|
||||
betterfoliage.blocks.myceliumBlacklist.tooltip=Blocks never accepted Mycelium. Has an impact on Better Grass
|
||||
|
||||
betterfoliage.blocks.netherrackWhitelist=Netherrack Whitelist
|
||||
betterfoliage.blocks.netherrackBlacklist=Netherrack Blacklist
|
||||
betterfoliage.blocks.netherrackWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.netherrackBlacklist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.netherrackWhitelist.tooltip=Blocks recognized as Netherrack. Has an impact on Netherrack Vines
|
||||
betterfoliage.blocks.netherrackBlacklist.tooltip=Blocks never accepted Netherrack. Has an impact on Netherrack Vines
|
||||
|
||||
betterfoliage.shaders=Shader configuration
|
||||
betterfoliage.shaders.tooltip=Configure integration with shaders
|
||||
betterfoliage.shaders.leavesId=Leaves ID
|
||||
betterfoliage.shaders.leavesId.tooltip=Block ID reported to shader programs for all kinds of leaves. If your shader uses a §6block.properties§e file, you'll probably need to change this to match the shader's mappings.
|
||||
betterfoliage.shaders.grassId=Grass ID
|
||||
betterfoliage.shaders.grassId.tooltip=Block ID reported to shader programs for all grasses and crops. If your shader uses a §6block.properties§e file, you'll probably need to change this to match the shader's mappings.
|
||||
|
||||
betterfoliage.leaves=Extra Leaves
|
||||
betterfoliage.leaves.tooltip=Extra round leaves on leaf blocks
|
||||
betterfoliage.leaves.dense=Dense mode
|
||||
betterfoliage.leaves.dense.tooltip=Dense mode has more round leaves
|
||||
betterfoliage.leaves.snowEnabled=Enable snow
|
||||
betterfoliage.leaves.snowEnabled.tooltip=Enable snow on extra leaves?
|
||||
betterfoliage.leaves.hideInternal=Hide internal leaves
|
||||
betterfoliage.leaves.hideInternal.tooltip=Skip rendering extra leaves if leaf block is completely surrounded by other leaves or solid blocks
|
||||
|
||||
betterfoliage.shortGrass=Short Grass & Mycelium
|
||||
betterfoliage.shortGrass.tooltip=Tufts of grass/mycelium on top of appropriate blocks
|
||||
betterfoliage.shortGrass.useGenerated=Use generated texture for grass
|
||||
betterfoliage.shortGrass.useGenerated.tooltip=Generated texture is made by slicing the tallgrass texture from the active resource pack in half
|
||||
betterfoliage.shortGrass.myceliumEnabled=Enable Mycelium
|
||||
betterfoliage.shortGrass.myceliumEnabled.tooltip=Is this feature enabled for mycelium blocks?
|
||||
betterfoliage.shortGrass.grassEnabled=Enable Grass
|
||||
betterfoliage.shortGrass.grassEnabled.tooltip=Is this feature enabled for grass blocks?
|
||||
betterfoliage.shortGrass.snowEnabled=Enable under snow
|
||||
betterfoliage.shortGrass.snowEnabled.tooltip=Enable on snowed grass blocks?
|
||||
betterfoliage.shortGrass.saturationThreshold=Saturation threshold
|
||||
betterfoliage.shortGrass.saturationThreshold.tooltip=Color saturation cutoff between "colorless" blocks (using biome color) and "colorful" blocks (using their own specific color)
|
||||
|
||||
betterfoliage.hangingGrass=Hanging Grass
|
||||
betterfoliage.hangingGrass.tooltip=Grass tufts hanging down from the top edges of grass blocks
|
||||
betterfoliage.hangingGrass.separation=Separation
|
||||
betterfoliage.hangingGrass.separation.tooltip=How much the hanging grass stands out from the block
|
||||
|
||||
betterfoliage.cactus=Better Cactus
|
||||
betterfoliage.cactus.tooltip=Enhance cactus with extra bits and smooth shading
|
||||
betterfoliage.cactus.sizeVariation=Size variation
|
||||
betterfoliage.cactus.sizeVariation.tooltip=Amount of random variation on cactus size
|
||||
|
||||
betterfoliage.lilypad=Better Lilypad
|
||||
betterfoliage.lilypad.tooltip=Enhance lilypad with roots and occasional flowers
|
||||
betterfoliage.lilypad.flowerChance=Flower chance
|
||||
betterfoliage.lilypad.flowerChance.tooltip=Chance (N in 64) of a lilypad having a flower on it
|
||||
|
||||
betterfoliage.reed=Reeds
|
||||
betterfoliage.reed.tooltip=Reeds on dirt blocks in shallow water
|
||||
betterfoliage.reed.biomes=Biome List
|
||||
betterfoliage.reed.biomes.tooltip=Configure which biomes reeds are allowed to appear in
|
||||
betterfoliage.reed.biomes.tooltip.element=Should reeds appear in the %s biome?
|
||||
|
||||
betterfoliage.algae=Algae
|
||||
betterfoliage.algae.tooltip=Algae on dirt blocks in deep water
|
||||
betterfoliage.algae.biomes=Biome List
|
||||
betterfoliage.algae.biomes.tooltip=Configure which biomes algae is allowed to appear in
|
||||
betterfoliage.algae.biomes.tooltip.element=Should algae appear in the %s biome?
|
||||
|
||||
betterfoliage.coral=Coral
|
||||
betterfoliage.coral.tooltip=Coral on sand blocks in deep water
|
||||
betterfoliage.coral.size=Coral size
|
||||
betterfoliage.coral.size.tooltip=Size of coral bits sticking out
|
||||
betterfoliage.coral.crustSize=Crust size
|
||||
betterfoliage.coral.crustSize.tooltip=Size of the flat coral part
|
||||
betterfoliage.coral.chance=Coral chance
|
||||
betterfoliage.coral.chance.tooltip=Chance (N in 64) of a specific face of the block to show coral
|
||||
betterfoliage.coral.biomes=Biome List
|
||||
betterfoliage.coral.biomes.tooltip=Configure which biomes coral is allowed to appear in
|
||||
betterfoliage.coral.biomes.tooltip.element=Should coral appear in the %s biome?
|
||||
betterfoliage.coral.shallowWater=Shallow water coral
|
||||
betterfoliage.coral.shallowWater.tooltip=Should coral appear in 1 block deep water?
|
||||
|
||||
betterfoliage.netherrack=Netherrack Vines
|
||||
betterfoliage.netherrack.tooltip=Hanging Vines under netherrack
|
||||
|
||||
betterfoliage.fallingLeaves=Falling leaves
|
||||
betterfoliage.fallingLeaves.tooltip=Falling leaf particle FX emitted from the bottom of leaf blocks
|
||||
betterfoliage.fallingLeaves.speed=Particle speed
|
||||
betterfoliage.fallingLeaves.speed.tooltip=Overall particle speed
|
||||
betterfoliage.fallingLeaves.windStrength=Wind strength
|
||||
betterfoliage.fallingLeaves.windStrength.tooltip=Magnitude of wind effects in good weather (spread of normal distribution centered on 0)
|
||||
betterfoliage.fallingLeaves.stormStrength=Storm strength
|
||||
betterfoliage.fallingLeaves.stormStrength.tooltip=Additional magnitude of wind effects in rainy weather (spread of normal distribution centered on 0)
|
||||
betterfoliage.fallingLeaves.size=Particle size
|
||||
betterfoliage.fallingLeaves.chance=Particle chance
|
||||
betterfoliage.fallingLeaves.chance.tooltip=Chance of each random render tick hitting a leaf block to spawn a particle
|
||||
betterfoliage.fallingLeaves.perturb=Perturbation
|
||||
betterfoliage.fallingLeaves.perturb.tooltip=Magnitude of perturbation effect. Adds a corkscrew-like motion to the particle synchronized to its rotation
|
||||
betterfoliage.fallingLeaves.lifetime=Maximum lifetime
|
||||
betterfoliage.fallingLeaves.lifetime.tooltip=Maximum lifetime of particle in seconds. Minimum lifetime is 60%% of this value
|
||||
betterfoliage.fallingLeaves.opacityHack=Opaque particles
|
||||
betterfoliage.fallingLeaves.opacityHack.tooltip=Stop transparent blocks obscuring particles even when particle is in front. WARNING: may cause glitches.
|
||||
|
||||
betterfoliage.risingSoul=Rising souls
|
||||
betterfoliage.risingSoul.tooltip=Rising soul particle FX emitted from the top of soulsand blocks
|
||||
betterfoliage.risingSoul.chance=Particle chance
|
||||
betterfoliage.risingSoul.chance.tooltip=Chance of each random render tick hitting a soulsand block to spawn a particle
|
||||
betterfoliage.risingSoul.speed=Particle speed
|
||||
betterfoliage.risingSoul.speed.tooltip=Vertical speed of soul particles
|
||||
betterfoliage.risingSoul.perturb=Perturbation
|
||||
betterfoliage.risingSoul.perturb.tooltip=Magnitude of perturbation effect. Adds a corkscrew-like motion to the particle
|
||||
betterfoliage.risingSoul.headSize=Soul size
|
||||
betterfoliage.risingSoul.headSize.tooltip=Size of the soul particle
|
||||
betterfoliage.risingSoul.trailSize=Trail size
|
||||
betterfoliage.risingSoul.trailSize.tooltip=Initial size of the particle trail
|
||||
betterfoliage.risingSoul.opacity=Opacity
|
||||
betterfoliage.risingSoul.opacity.tooltip=Opacity of the particle effect
|
||||
betterfoliage.risingSoul.sizeDecay=Size decay
|
||||
betterfoliage.risingSoul.sizeDecay.tooltip=Trail particle size relative to its size in the previous tick
|
||||
betterfoliage.risingSoul.opacityDecay=Opacity decay
|
||||
betterfoliage.risingSoul.opacityDecay.tooltip=Trail particle opacity relative to its opacity in the previous tick
|
||||
betterfoliage.risingSoul.lifetime=Maximum lifetime
|
||||
betterfoliage.risingSoul.lifetime.tooltip=Maximum lifetime of particle effect in seconds. Minimum lifetime is 60%% of this value
|
||||
betterfoliage.risingSoul.trailLength=Trail length
|
||||
betterfoliage.risingSoul.trailLength.tooltip=Number of previous positions the particle remembers in ticks
|
||||
betterfoliage.risingSoul.trailDensity=Trail density
|
||||
betterfoliage.risingSoul.trailDensity.tooltip=Render every Nth previous position in the particle trail
|
||||
|
||||
betterfoliage.connectedGrass=Connected grass textures
|
||||
betterfoliage.connectedGrass.enabled=Enable
|
||||
betterfoliage.connectedGrass.enabled.tooltip=If there is a grass block on top of a dirt block: draw grass top texture on all grass block sides,
|
||||
|
||||
betterfoliage.roundLogs=Round Logs
|
||||
betterfoliage.roundLogs.tooltip=Connect round blocks to solid full blocks?
|
||||
betterfoliage.roundLogs.connectSolids=Connect to solid
|
||||
betterfoliage.roundLogs.connectSolids.tooltip=Connect round blocks to solid full blocks?
|
||||
betterfoliage.roundLogs.connectPerpendicular=Connect to perpendicular logs
|
||||
betterfoliage.roundLogs.connectPerpendicular.tooltip=Connect round logs to perpendicular logs along its axis?
|
||||
betterfoliage.roundLogs.lenientConnect=Lenient rounding
|
||||
betterfoliage.roundLogs.lenientConnect.tooltip=Connect parallel round logs in an L-shape too, not just 2x2
|
||||
betterfoliage.roundLogs.connectGrass=Connect Grass
|
||||
betterfoliage.roundLogs.connectGrass.tooltip=Render grass block under trees instead of dirt if there is grass nearby
|
||||
betterfoliage.roundLogs.radiusSmall=Chamfer radius
|
||||
betterfoliage.roundLogs.radiusSmall.tooltip=How much to chop off from the log corner
|
||||
betterfoliage.roundLogs.radiusLarge=Connected chamfer radius
|
||||
betterfoliage.roundLogs.radiusLarge.tooltip=How much to chop off from the outer corner of connected logs
|
||||
betterfoliage.roundLogs.dimming=Dimming
|
||||
betterfoliage.roundLogs.dimming.tooltip=Amount to darken obscured log faces
|
||||
betterfoliage.roundLogs.zProtection=Z-Protection
|
||||
betterfoliage.roundLogs.zProtection.tooltip=Amount to scale parallel log connection bits to stop Z-fighting (flickering). Try to set it as high as possible without having glitches.
|
||||
betterfoliage.roundLogs.defaultY=Default to vertical
|
||||
betterfoliage.roundLogs.defaultY.tooltip=If true, log blocks where the orientation cannot be determined will be rendered as vertical. Otherwise, they will be rendered as cube blocks.
|
||||
155
src/main/resources/assets/betterfoliage/lang/ko_kr.json
Normal file
155
src/main/resources/assets/betterfoliage/lang/ko_kr.json
Normal file
@@ -0,0 +1,155 @@
|
||||
{
|
||||
"key.betterfoliage.gui": "설정",
|
||||
|
||||
"betterfoliage.global.enabled": "모드 활성화",
|
||||
"betterfoliage.global.enabled.tooltip": "비활성화 할 경우, 환경강화모드 렌더링이 보이지 않습니다.",
|
||||
|
||||
"betterfoliage.enabled": "활성화",
|
||||
"betterfoliage.enabled.tooltip": "이 기능이 활성화 되어 있습니까?",
|
||||
"betterfoliage.hOffset": "수평(가로) 상쇄시키다",
|
||||
"betterfoliage.hOffset.tooltip": "이 성분이 블럭 수평으로 이동된다.",
|
||||
"betterfoliage.vOffset": "수직(세로) 상쇄시키다",
|
||||
"betterfoliage.vOffset.tooltip": "이 성분이 블럭 수직으로 이동된다.",
|
||||
"betterfoliage.size": "사이즈(크기)",
|
||||
"betterfoliage.size.tooltip": "사이즈(크기)의 최소",
|
||||
"betterfoliage.heightMin": "최소한 높이",
|
||||
"betterfoliage.heightMin.tooltip": "높이 최소한의 최소",
|
||||
"betterfoliage.heightMax": "최대한 높이",
|
||||
"betterfoliage.heightMax.tooltip": "높이 최대한의 최소",
|
||||
"betterfoliage.population": "주민",
|
||||
"betterfoliage.population.tooltip": "자격을 갖춘 블럭의 기능 확률(N 분의 64)",
|
||||
"betterfoliage.shaderWind": "쉐이더 바람 효과",
|
||||
"betterfoliage.shaderWind.tooltip": "바람효과를 쉐이더에 적용시키겠습니까?",
|
||||
"betterfoliage.distance": "거리 제한",
|
||||
"betterfoliage.distance.tooltip": "이 기능을 렌더링하는 플레이어의 최대거리",
|
||||
"betterfoliage.saturationThreshold": "채도 임계값",
|
||||
"betterfoliage.saturationThreshold.tooltip": "(특정 색상을 사용하여)\"무채색\"블록과 (바이옴 색을 사용하여)\"화려한\"블록 사이의 채도 차단",
|
||||
|
||||
"betterfoliage.leaves": "잎 추가",
|
||||
"betterfoliage.leaves.tooltip": "둥글게 나뭇잎을 추가시켜줍니다.",
|
||||
"betterfoliage.leaves.dense": "조밀한 모드",
|
||||
"betterfoliage.leaves.dense.tooltip": "조밀한 모드는 둥근 나뭇잎을 더 추가시켜줍니다.",
|
||||
|
||||
"betterfoliage.shortGrass": "이쁜 잔디 & 균사체",
|
||||
"betterfoliage.shortGrass.tooltip": "블록 상단에 잔디 / 균사체",
|
||||
"betterfoliage.shortGrass.useGenerated": "잔디텍스쳐를 활성화 합니다.",
|
||||
"betterfoliage.shortGrass.useGenerated.tooltip": "소스팩의 일부분에 활성화 되어있는 큰잔디 텍스쳐를 생성시킵니다.",
|
||||
"betterfoliage.shortGrass.myceliumEnabled": "균사체 활성화",
|
||||
"betterfoliage.shortGrass.myceliumEnabled.tooltip": "균사체 블록에 있는 기능을 활성화 시키겠습니까?",
|
||||
"betterfoliage.shortGrass.grassEnabled": "잔디 활성화",
|
||||
"betterfoliage.shortGrass.grassEnabled.tooltip": "잔디 블록에 있는 기능을 활성화 시키겠습니까?",
|
||||
"betterfoliage.shortGrass.snowEnabled": "눈 활성화",
|
||||
"betterfoliage.shortGrass.snowEnabled.tooltip": "잔디 블록위에 있는 눈을 활성화 시키겠습니까?",
|
||||
|
||||
"betterfoliage.hangingGrass": "매달려있는 잔디",
|
||||
"betterfoliage.hangingGrass.tooltip": "잔디 블록 상단 가장자리에서 아래로 매달려 있는 잔디 다발",
|
||||
"betterfoliage.hangingGrass.separation": "분리",
|
||||
"betterfoliage.hangingGrass.separation.tooltip": "잔디블럭에 매달려있는 잔디의 양 ",
|
||||
|
||||
"betterfoliage.cactus": "선인장",
|
||||
"betterfoliage.cactus.tooltip": "선인장의 비트 수와 부드러운 그림자를 추가",
|
||||
"betterfoliage.cactus.sizeVariation": "사이즈 변화",
|
||||
"betterfoliage.cactus.sizeVariation.tooltip": "선인장의 사이즈 크기를 무작위 변화 시킵니다.",
|
||||
|
||||
"betterfoliage.lilypad": "연꽃잎",
|
||||
"betterfoliage.lilypad.tooltip": "연꽃의 뿌리와 약간의 꽃 추가",
|
||||
"betterfoliage.lilypad.flowerChance": "꽃 확률",
|
||||
"betterfoliage.lilypad.flowerChance.tooltip": "연꽃 위에 있는 꽃 확률(N 분의 64)",
|
||||
|
||||
"betterfoliage.reed": "갈대",
|
||||
"betterfoliage.reed.tooltip": "물 속에서 흙블럭 위에 있는 갈대",
|
||||
"betterfoliage.reed.biomes": "바이옴 리스트",
|
||||
"betterfoliage.reed.biomes.tooltip": "갈대를 바이옴에 따라 표시",
|
||||
"betterfoliage.reed.biomes.tooltip.element": "갈대를 %s 바이옴에 따라 나타내시겠습니까? ",
|
||||
|
||||
"betterfoliage.algae": "해조류",
|
||||
"betterfoliage.algae.tooltip": "깊은 물 속 흙 블럭 위에 있는 해조류",
|
||||
"betterfoliage.algae.biomes": "바이옴 리스트",
|
||||
"betterfoliage.algae.biomes.tooltip": "해조류를 바이옴에 따라 표시",
|
||||
"betterfoliage.algae.biomes.tooltip.element": "해조류를 %s 바이옴에 따라 나타내시겠습니까? ",
|
||||
|
||||
"betterfoliage.coral": "산호",
|
||||
"betterfoliage.coral.tooltip": "깊은 물 속 모래 블럭 위에있는 산호",
|
||||
"betterfoliage.coral.size": "산호 사이즈(크기)",
|
||||
"betterfoliage.coral.size.tooltip": "산호 이미지만큼 적용",
|
||||
"betterfoliage.coral.crustSize": "껍질 크기",
|
||||
"betterfoliage.coral.crustSize.tooltip": "산호 부분의 크기 ",
|
||||
"betterfoliage.coral.chance": "산호 확률",
|
||||
"betterfoliage.coral.chance.tooltip": "산호를 특정블록에 표시하는 확률(N 분의 64)",
|
||||
"betterfoliage.coral.biomes": "바이옴 리스트",
|
||||
"betterfoliage.coral.biomes.tooltip": "산호를 바이옴에 따라 표시",
|
||||
"betterfoliage.coral.biomes.tooltip.element": "산호를 %s 바이옴에 따라 나타내시겠습니까?",
|
||||
"betterfoliage.coral.shallowWater": "얕은 물 산호",
|
||||
"betterfoliage.coral.shallowWater.tooltip": "산호를 깊은 물에 표시하시겠습니까?",
|
||||
|
||||
"betterfoliage.netherrack": "네더랙 덩굴",
|
||||
"betterfoliage.netherrack.tooltip": "네더랙에 매달려있는 덩굴",
|
||||
|
||||
"betterfoliage.fallingLeaves": "떨어지는 나뭇잎",
|
||||
"betterfoliage.fallingLeaves.tooltip": "잎 블록에서 바닥으로 떨어지는 잎 파티클",
|
||||
"betterfoliage.fallingLeaves.speed": "파티클 속도",
|
||||
"betterfoliage.fallingLeaves.speed.tooltip": "전체 파티클 속도",
|
||||
"betterfoliage.fallingLeaves.windStrength": "바람 세기",
|
||||
"betterfoliage.fallingLeaves.windStrength.tooltip": "날씨 바람 추가효과 (0을 중심으로 정규분포의 확산)",
|
||||
"betterfoliage.fallingLeaves.stormStrength": "폭풍 세기",
|
||||
"betterfoliage.fallingLeaves.stormStrength.tooltip": "비 날씨에 바람 추가효과 (0을 중심으로 정규분포의 확산)",
|
||||
"betterfoliage.fallingLeaves.size": "파티클 크기",
|
||||
"betterfoliage.fallingLeaves.chance": "파티클 확률",
|
||||
"betterfoliage.fallingLeaves.chance.tooltip": "잎 파티클 랜덤 확률 설정",
|
||||
"betterfoliage.fallingLeaves.perturb": "움직임",
|
||||
"betterfoliage.fallingLeaves.perturb.tooltip": "움직임 효과의 크기. 코르크 같은 움직임을 추가합니다.",
|
||||
"betterfoliage.fallingLeaves.lifetime": "파티클 지속시간",
|
||||
"betterfoliage.fallingLeaves.lifetime.tooltip": "최대 파티클 지속시간을 설정합니다. 최소 지속시간은 60%입니다.",
|
||||
"betterfoliage.fallingLeaves.opacityHack": "불투명 파티클",
|
||||
"betterfoliage.fallingLeaves.opacityHack.tooltip": "파티클이 앞에 있어도 파티클을 가리는 투명블럭을 없앱니다. 경고: 오류주의",
|
||||
|
||||
"betterfoliage.risingSoul": "소울 상승",
|
||||
"betterfoliage.risingSoul.tooltip": "소울 블럭에서 올라오는 파티클",
|
||||
"betterfoliage.risingSoul.chance": "파티클 수정",
|
||||
"betterfoliage.risingSoul.chance.tooltip": "소울 파티클 랜덤 확률 설정",
|
||||
"betterfoliage.risingSoul.speed": "파티클 속도",
|
||||
"betterfoliage.risingSoul.speed.tooltip": "파티클 속도",
|
||||
"betterfoliage.risingSoul.perturb": "움직임",
|
||||
"betterfoliage.risingSoul.perturb.tooltip": "움직임 효과의 크기. 코르크 같은 움직임을 추가합니다.",
|
||||
"betterfoliage.risingSoul.headSize": "소울 크기",
|
||||
"betterfoliage.risingSoul.headSize.tooltip": "소울 파티클의 크기",
|
||||
"betterfoliage.risingSoul.trailSize": "자취 사이즈",
|
||||
"betterfoliage.risingSoul.trailSize.tooltip": "자취의 크기",
|
||||
"betterfoliage.risingSoul.opacity": "불투명",
|
||||
"betterfoliage.risingSoul.opacity.tooltip": "파티클의 불투명",
|
||||
"betterfoliage.risingSoul.sizeDecay": "크기 감소",
|
||||
"betterfoliage.risingSoul.sizeDecay.tooltip": "상대적인 자취 파티클 크기",
|
||||
"betterfoliage.risingSoul.opacityDecay": "불투명 감소",
|
||||
"betterfoliage.risingSoul.opacityDecay.tooltip": "상대적인 입자의 파티클 불투명도",
|
||||
"betterfoliage.risingSoul.lifetime": "최대 지속시간",
|
||||
"betterfoliage.risingSoul.lifetime.tooltip": "최대 파티클 지속시간을 설정합니다. 최소 지속시간은 60%입니다.",
|
||||
"betterfoliage.risingSoul.trailLength": "자취의 세기",
|
||||
"betterfoliage.risingSoul.trailLength.tooltip": "이전 파티클 틱으로 자취를 생성합니다.",
|
||||
"betterfoliage.risingSoul.trailDensity": "자취의 밀도",
|
||||
"betterfoliage.risingSoul.trailDensity.tooltip": "파티클 자취를 모두 렌더링 합니다.",
|
||||
|
||||
"betterfoliage.connectedGrass": "잔디 연결 텍스쳐",
|
||||
"betterfoliage.connectedGrass.enabled": "활성화",
|
||||
"betterfoliage.connectedGrass.enabled.tooltip": "잔디블록이 흙블록 위에 있을 경우 잔디블록 윗텍스쳐를 옆텍스쳐에 전부 씌웁니다.",
|
||||
|
||||
"betterfoliage.roundLogs": "둥근 나무",
|
||||
"betterfoliage.roundLogs.tooltip": "둥근부분을 블럭과 연결.",
|
||||
"betterfoliage.roundLogs.connectSolids": "블럭과 연결",
|
||||
"betterfoliage.roundLogs.connectSolids.tooltip": "둥근부분을 블럭과 연결.",
|
||||
"betterfoliage.roundLogs.connectPerpendicular": "나무 세로부분과 연결",
|
||||
"betterfoliage.roundLogs.connectPerpendicular.tooltip": "나무 세로부분을 나무부분끼리 연결",
|
||||
"betterfoliage.roundLogs.lenientConnect": "부드럽게 둥글게 연결",
|
||||
"betterfoliage.roundLogs.lenientConnect.tooltip": "2x2사이즈처럼 나무 평형된 부분끼리 서로 연결합니다.",
|
||||
"betterfoliage.roundLogs.connectGrass": "잔디 연결 텍스쳐",
|
||||
"betterfoliage.roundLogs.connectGrass.tooltip": "잔디가 근처에 있을 경우 나무 아래 잔디 블록을 렌더링",
|
||||
"betterfoliage.roundLogs.radiusSmall": "모서리 깎는 반지름",
|
||||
"betterfoliage.roundLogs.radiusSmall.tooltip": "나무 모서리 깎는 정도",
|
||||
"betterfoliage.roundLogs.radiusLarge": "모서리 깎는 부분 연결",
|
||||
"betterfoliage.roundLogs.radiusLarge.tooltip": "나무 모서리 부분을 연결",
|
||||
"betterfoliage.roundLogs.dimming": "조광",
|
||||
"betterfoliage.roundLogs.dimming.tooltip": "나무 표면부분을 어둡게하는 양",
|
||||
"betterfoliage.roundLogs.zProtection": "Z-Protection",
|
||||
"betterfoliage.roundLogs.zProtection.tooltip": "Amount to scale parallel log connection bits to stop Z-fighting (flickering). Try to set it as high as possible without having glitches.",
|
||||
"betterfoliage.roundLogs.defaultY": "수직선에대한 기본값",
|
||||
"betterfoliage.roundLogs.defaultY.tooltip": "true 일경우, 나무 블럭이 수직선에대한 렌더링을 할수가 없습니다. 그렇지 아니하면, 네모난 블럭으로 렌더링 될것임니다."
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
key.betterfoliage.gui=설정
|
||||
|
||||
betterfoliage.global.enabled=모드 활성화
|
||||
betterfoliage.global.enabled.tooltip=비활성화 할 경우, 환경강화모드 렌더링이 보이지 않습니다.
|
||||
|
||||
betterfoliage.enabled=활성화
|
||||
betterfoliage.enabled.tooltip=이 기능이 활성화 되어 있습니까?
|
||||
betterfoliage.hOffset=수평(가로) 상쇄시키다
|
||||
betterfoliage.hOffset.tooltip=이 성분이 블럭 수평으로 이동된다.
|
||||
betterfoliage.vOffset=수직(세로) 상쇄시키다
|
||||
betterfoliage.vOffset.tooltip=이 성분이 블럭 수직으로 이동된다.
|
||||
betterfoliage.size=사이즈(크기)
|
||||
betterfoliage.size.tooltip=사이즈(크기)의 최소
|
||||
betterfoliage.heightMin=최소한 높이
|
||||
betterfoliage.heightMin.tooltip=높이 최소한의 최소
|
||||
betterfoliage.heightMax=최대한 높이
|
||||
betterfoliage.heightMax.tooltip=높이 최대한의 최소
|
||||
betterfoliage.population=주민
|
||||
betterfoliage.population.tooltip=자격을 갖춘 블럭의 기능 확률(N 분의 64)
|
||||
betterfoliage.shaderWind=쉐이더 바람 효과
|
||||
betterfoliage.shaderWind.tooltip=바람효과를 쉐이더에 적용시키겠습니까?
|
||||
betterfoliage.distance=거리 제한
|
||||
betterfoliage.distance.tooltip=이 기능을 렌더링하는 플레이어의 최대거리
|
||||
|
||||
betterfoliage.blocks=블록 타입
|
||||
betterfoliage.blocks.tooltip=세팅 된 것에 따라 블록이 바뀔 것입니다.
|
||||
|
||||
betterfoliage.blocks.dirtWhitelist=흙 허용목록
|
||||
betterfoliage.blocks.dirtBlacklist=흙 차단목록
|
||||
betterfoliage.blocks.dirtWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.dirtBlacklist.arrayEntry=%d entries
|
||||
|
||||
betterfoliage.blocks.grassWhitelist=잔디 허용목록
|
||||
betterfoliage.blocks.grassBlacklist=잔디 차단목록
|
||||
betterfoliage.blocks.grassWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.grassBlacklist.arrayEntry=%d entries
|
||||
|
||||
betterfoliage.blocks.leavesWhitelist=잎 허용목록
|
||||
betterfoliage.blocks.leavesBlacklist=잎 차단목록
|
||||
betterfoliage.blocks.leavesWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.leavesBlacklist.arrayEntry=%d entries
|
||||
|
||||
betterfoliage.blocks.cropsWhitelist=농작물 허용목록
|
||||
betterfoliage.blocks.cropsBlacklist=농작물 차단목록
|
||||
betterfoliage.blocks.cropsWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.cropsBlacklist.arrayEntry=%d entries
|
||||
|
||||
betterfoliage.blocks.logsWhitelist=나무 허용목록
|
||||
betterfoliage.blocks.logsBlacklist=나무 차단목록
|
||||
betterfoliage.blocks.logsWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.logsBlacklist.arrayEntry=%d entries
|
||||
|
||||
betterfoliage.blocks.sandWhitelist=모래 허용목록
|
||||
betterfoliage.blocks.sandBlacklist=모래 차단목록
|
||||
betterfoliage.blocks.sandWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.sandBlacklist.arrayEntry=%d entries
|
||||
|
||||
betterfoliage.blocks.lilypadWhitelist=연꽃 허용목록
|
||||
betterfoliage.blocks.lilypadBlacklist=연꽃 차단목록
|
||||
betterfoliage.blocks.lilypadWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.lilypadBlacklist.arrayEntry=%d entries
|
||||
|
||||
betterfoliage.blocks.cactusWhitelist=선인장 허용목록
|
||||
betterfoliage.blocks.cactusBlacklist=선인장 차단목록
|
||||
betterfoliage.blocks.cactusWhitelist.arrayEntry=%d entries
|
||||
betterfoliage.blocks.cactusBlacklist.arrayEntry=%d entries
|
||||
|
||||
|
||||
betterfoliage.blocks.dirtWhitelist.tooltip=흙으로 인식됩니다. 갈대, 조류, 잔디 텍스쳐 연결에 영향을 줍니다.
|
||||
betterfoliage.blocks.dirtBlacklist.tooltip=흙으로 인식 되지 않습니다. 갈대, 조류, 잔디 텍스쳐 연결에 영향을 주지 않습니다.
|
||||
betterfoliage.blocks.grassWhitelist.tooltip=잔디로 인식됩니다. 짧은 잔디, 잔디 텍스쳐 연결에 영향을 줍니다.
|
||||
betterfoliage.blocks.grassBlacklist.tooltip=잔디로 인식 되지 않습니다. 짧은 잔디, 잔디 텍스쳐 연결에 영향을 주지 않습니다.
|
||||
betterfoliage.blocks.leavesWhitelist.tooltip=잎으로 인식됩니다. 추가 잎, 떨어지는 잎에 영향을 줍니다.
|
||||
betterfoliage.blocks.leavesBlacklist.tooltip=잎으로 인식 되지 않습니다. 추가 잎, 떨어지는 잎에 영향을 주지 않습니다.
|
||||
betterfoliage.blocks.cropsWhitelist.tooltip=농작물로 인식됩니다. 농작물은 쉐이더 적용하면 큰잔디로 렌더링 됩니다.
|
||||
betterfoliage.blocks.cropsBlacklist.tooltip=농작물로 인식 되지 않습니다. 농작물은 쉐이더 적용하면 큰잔디로 렌더링 되지 않습니다.
|
||||
betterfoliage.blocks.logsWhitelist.tooltip=나무로 인식됩니다. 둥근 나무에 영향을 줍니다.
|
||||
betterfoliage.blocks.logsBlacklist.tooltip=나무로 인식 되지 않습니다. 둥근 나무에 영향을 주지 않습니다.
|
||||
betterfoliage.blocks.sandWhitelist.tooltip=모래로 인식됩니다. 산호에 영향을 줍니다
|
||||
betterfoliage.blocks.sandBlacklist.tooltip=모래로 인식되지 않습니다. 산호에 영향을 주지 않습니다.
|
||||
betterfoliage.blocks.lilypadWhitelist.tooltip=연꽃으로 인식됩니다. 보다 나은 연꽃에 영향을 줍니다.
|
||||
betterfoliage.blocks.lilypadBlacklist.tooltip=연꽃으로 인식되지 않습니다. 보다 나은 연꽃에 영향을 주지 않습니다.
|
||||
betterfoliage.blocks.cactusWhitelist.tooltip=선인장으로 인식됩니다. 보다 나은 선인장에 영향을 줍니다.
|
||||
betterfoliage.blocks.cactusBlacklist.tooltip=선인장으로 인식되지 않습니다. 보다 나은 선인장에 영향을 주지 않습니다.
|
||||
|
||||
betterfoliage.leaves=잎 추가
|
||||
betterfoliage.leaves.tooltip=둥글게 나뭇잎을 추가시켜줍니다.
|
||||
betterfoliage.leaves.dense=조밀한 모드
|
||||
betterfoliage.leaves.dense.tooltip=조밀한 모드는 둥근 나뭇잎을 더 추가시켜줍니다.
|
||||
|
||||
betterfoliage.shortGrass=이쁜 잔디 & 균사체
|
||||
betterfoliage.shortGrass.tooltip=블록 상단에 잔디 / 균사체
|
||||
betterfoliage.shortGrass.useGenerated=잔디텍스쳐를 활성화 합니다.
|
||||
betterfoliage.shortGrass.useGenerated.tooltip=소스팩의 일부분에 활성화 되어있는 큰잔디 텍스쳐를 생성시킵니다.
|
||||
betterfoliage.shortGrass.myceliumEnabled=균사체 활성화
|
||||
betterfoliage.shortGrass.myceliumEnabled.tooltip=균사체 블록에 있는 기능을 활성화 시키겠습니까?
|
||||
betterfoliage.shortGrass.grassEnabled=잔디 활성화
|
||||
betterfoliage.shortGrass.grassEnabled.tooltip=잔디 블록에 있는 기능을 활성화 시키겠습니까?
|
||||
betterfoliage.shortGrass.snowEnabled=눈 활성화
|
||||
betterfoliage.shortGrass.snowEnabled.tooltip=잔디 블록위에 있는 눈을 활성화 시키겠습니까?
|
||||
betterfoliage.shortGrass.saturationThreshold=채도 임계값
|
||||
betterfoliage.shortGrass.saturationThreshold.tooltip=(특정 색상을 사용하여)"무채색"블록과 (바이옴 색을 사용하여)"화려한"블록 사이의 채도 차단
|
||||
|
||||
betterfoliage.hangingGrass=매달려있는 잔디
|
||||
betterfoliage.hangingGrass.tooltip=잔디 블록 상단 가장자리에서 아래로 매달려 있는 잔디 다발
|
||||
betterfoliage.hangingGrass.separation=분리
|
||||
betterfoliage.hangingGrass.separation.tooltip=잔디블럭에 매달려있는 잔디의 양
|
||||
|
||||
betterfoliage.cactus=선인장
|
||||
betterfoliage.cactus.tooltip=선인장의 비트 수와 부드러운 그림자를 추가
|
||||
betterfoliage.cactus.sizeVariation=사이즈 변화
|
||||
betterfoliage.cactus.sizeVariation.tooltip=선인장의 사이즈 크기를 무작위 변화 시킵니다.
|
||||
|
||||
betterfoliage.lilypad=연꽃잎
|
||||
betterfoliage.lilypad.tooltip=연꽃의 뿌리와 약간의 꽃 추가
|
||||
betterfoliage.lilypad.flowerChance=꽃 확률
|
||||
betterfoliage.lilypad.flowerChance.tooltip=연꽃 위에 있는 꽃 확률(N 분의 64)
|
||||
|
||||
betterfoliage.reed=갈대
|
||||
betterfoliage.reed.tooltip=물 속에서 흙블럭 위에 있는 갈대
|
||||
betterfoliage.reed.biomes=바이옴 리스트
|
||||
betterfoliage.reed.biomes.tooltip=갈대를 바이옴에 따라 표시
|
||||
betterfoliage.reed.biomes.tooltip.element=갈대를 %s 바이옴에 따라 나타내시겠습니까?
|
||||
|
||||
betterfoliage.algae=해조류
|
||||
betterfoliage.algae.tooltip=깊은 물 속 흙 블럭 위에 있는 해조류
|
||||
betterfoliage.algae.biomes=바이옴 리스트
|
||||
betterfoliage.algae.biomes.tooltip=해조류를 바이옴에 따라 표시
|
||||
betterfoliage.algae.biomes.tooltip.element=해조류를 %s 바이옴에 따라 나타내시겠습니까?
|
||||
|
||||
betterfoliage.coral=산호
|
||||
betterfoliage.coral.tooltip=깊은 물 속 모래 블럭 위에있는 산호
|
||||
betterfoliage.coral.size=산호 사이즈(크기)
|
||||
betterfoliage.coral.size.tooltip=산호 이미지만큼 적용
|
||||
betterfoliage.coral.crustSize=껍질 크기
|
||||
betterfoliage.coral.crustSize.tooltip=산호 부분의 크기
|
||||
betterfoliage.coral.chance=산호 확률
|
||||
betterfoliage.coral.chance.tooltip=산호를 특정블록에 표시하는 확률(N 분의 64)
|
||||
betterfoliage.coral.biomes=바이옴 리스트
|
||||
betterfoliage.coral.biomes.tooltip=산호를 바이옴에 따라 표시
|
||||
betterfoliage.coral.biomes.tooltip.element=산호를 %s 바이옴에 따라 나타내시겠습니까?
|
||||
betterfoliage.coral.shallowWater=얕은 물 산호
|
||||
betterfoliage.coral.shallowWater.tooltip=산호를 깊은 물에 표시하시겠습니까?
|
||||
|
||||
betterfoliage.netherrack=네더랙 덩굴
|
||||
betterfoliage.netherrack.tooltip=네더랙에 매달려있는 덩굴
|
||||
|
||||
betterfoliage.fallingLeaves=떨어지는 나뭇잎
|
||||
betterfoliage.fallingLeaves.tooltip=잎 블록에서 바닥으로 떨어지는 잎 파티클
|
||||
betterfoliage.fallingLeaves.speed=파티클 속도
|
||||
betterfoliage.fallingLeaves.speed.tooltip=전체 파티클 속도
|
||||
betterfoliage.fallingLeaves.windStrength=바람 세기
|
||||
betterfoliage.fallingLeaves.windStrength.tooltip=날씨 바람 추가효과 (0을 중심으로 정규분포의 확산)
|
||||
betterfoliage.fallingLeaves.stormStrength=폭풍 세기
|
||||
betterfoliage.fallingLeaves.stormStrength.tooltip=비 날씨에 바람 추가효과 (0을 중심으로 정규분포의 확산)
|
||||
betterfoliage.fallingLeaves.size=파티클 크기
|
||||
betterfoliage.fallingLeaves.chance=파티클 확률
|
||||
betterfoliage.fallingLeaves.chance.tooltip=잎 파티클 랜덤 확률 설정
|
||||
betterfoliage.fallingLeaves.perturb=움직임
|
||||
betterfoliage.fallingLeaves.perturb.tooltip=움직임 효과의 크기. 코르크 같은 움직임을 추가합니다.
|
||||
betterfoliage.fallingLeaves.lifetime=파티클 지속시간
|
||||
betterfoliage.fallingLeaves.lifetime.tooltip=최대 파티클 지속시간을 설정합니다. 최소 지속시간은 60%입니다.
|
||||
betterfoliage.fallingLeaves.opacityHack=불투명 파티클
|
||||
betterfoliage.fallingLeaves.opacityHack.tooltip=파티클이 앞에 있어도 파티클을 가리는 투명블럭을 없앱니다. 경고: 오류주의
|
||||
|
||||
betterfoliage.risingSoul=소울 상승
|
||||
betterfoliage.risingSoul.tooltip=소울 블럭에서 올라오는 파티클
|
||||
betterfoliage.risingSoul.chance=파티클 수정
|
||||
betterfoliage.risingSoul.chance.tooltip=소울 파티클 랜덤 확률 설정
|
||||
betterfoliage.risingSoul.speed=파티클 속도
|
||||
betterfoliage.risingSoul.speed.tooltip=파티클 속도
|
||||
betterfoliage.risingSoul.perturb=움직임
|
||||
betterfoliage.risingSoul.perturb.tooltip=움직임 효과의 크기. 코르크 같은 움직임을 추가합니다.
|
||||
betterfoliage.risingSoul.headSize=소울 크기
|
||||
betterfoliage.risingSoul.headSize.tooltip=소울 파티클의 크기
|
||||
betterfoliage.risingSoul.trailSize=자취 사이즈
|
||||
betterfoliage.risingSoul.trailSize.tooltip=자취의 크기
|
||||
betterfoliage.risingSoul.opacity=불투명
|
||||
betterfoliage.risingSoul.opacity.tooltip=파티클의 불투명
|
||||
betterfoliage.risingSoul.sizeDecay=크기 감소
|
||||
betterfoliage.risingSoul.sizeDecay.tooltip=상대적인 자취 파티클 크기
|
||||
betterfoliage.risingSoul.opacityDecay=불투명 감소
|
||||
betterfoliage.risingSoul.opacityDecay.tooltip=상대적인 입자의 파티클 불투명도
|
||||
betterfoliage.risingSoul.lifetime=최대 지속시간
|
||||
betterfoliage.risingSoul.lifetime.tooltip=최대 파티클 지속시간을 설정합니다. 최소 지속시간은 60%입니다.
|
||||
betterfoliage.risingSoul.trailLength=자취의 세기
|
||||
betterfoliage.risingSoul.trailLength.tooltip=이전 파티클 틱으로 자취를 생성합니다.
|
||||
betterfoliage.risingSoul.trailDensity=자취의 밀도
|
||||
betterfoliage.risingSoul.trailDensity.tooltip=파티클 자취를 모두 렌더링 합니다.
|
||||
|
||||
betterfoliage.connectedGrass=잔디 연결 텍스쳐
|
||||
betterfoliage.connectedGrass.enabled=활성화
|
||||
betterfoliage.connectedGrass.enabled.tooltip=잔디블록이 흙블록 위에 있을 경우 잔디블록 윗텍스쳐를 옆텍스쳐에 전부 씌웁니다.
|
||||
|
||||
betterfoliage.roundLogs=둥근 나무
|
||||
betterfoliage.roundLogs.tooltip=둥근부분을 블럭과 연결.
|
||||
betterfoliage.roundLogs.connectSolids=블럭과 연결
|
||||
betterfoliage.roundLogs.connectSolids.tooltip=둥근부분을 블럭과 연결.
|
||||
betterfoliage.roundLogs.connectPerpendicular=나무 세로부분과 연결
|
||||
betterfoliage.roundLogs.connectPerpendicular.tooltip=나무 세로부분을 나무부분끼리 연결
|
||||
betterfoliage.roundLogs.lenientConnect=부드럽게 둥글게 연결
|
||||
betterfoliage.roundLogs.lenientConnect.tooltip=2x2사이즈처럼 나무 평형된 부분끼리 서로 연결합니다.
|
||||
betterfoliage.roundLogs.connectGrass=잔디 연결 텍스쳐
|
||||
betterfoliage.roundLogs.connectGrass.tooltip=잔디가 근처에 있을 경우 나무 아래 잔디 블록을 렌더링
|
||||
betterfoliage.roundLogs.radiusSmall=모서리 깎는 반지름
|
||||
betterfoliage.roundLogs.radiusSmall.tooltip=나무 모서리 깎는 정도
|
||||
betterfoliage.roundLogs.radiusLarge=모서리 깎는 부분 연결
|
||||
betterfoliage.roundLogs.radiusLarge.tooltip=나무 모서리 부분을 연결
|
||||
betterfoliage.roundLogs.dimming=조광
|
||||
betterfoliage.roundLogs.dimming.tooltip=나무 표면부분을 어둡게하는 양
|
||||
betterfoliage.roundLogs.zProtection=Z-Protection
|
||||
betterfoliage.roundLogs.zProtection.tooltip=Amount to scale parallel log connection bits to stop Z-fighting (flickering). Try to set it as high as possible without having glitches.
|
||||
betterfoliage.roundLogs.defaultY=수직선에대한 기본값
|
||||
betterfoliage.roundLogs.defaultY.tooltip=true 일경우, 나무 블럭이 수직선에대한 렌더링을 할수가 없습니다. 그렇지 아니하면, 네모난 블럭으로 렌더링 될것임니다.
|
||||
|
||||
# Translate by IS_Jump for feedback mail acarus22@gmail.com
|
||||
154
src/main/resources/assets/betterfoliage/lang/ru_ru.json
Normal file
154
src/main/resources/assets/betterfoliage/lang/ru_ru.json
Normal file
@@ -0,0 +1,154 @@
|
||||
{
|
||||
"key.betterfoliage.gui": "Открыть настройки",
|
||||
|
||||
"betterfoliage.global.enabled": "Включить мод",
|
||||
"betterfoliage.global.enabled.tooltip": "Если установлено на false, BetterFoliage не будет ничего рендерить",
|
||||
|
||||
"betterfoliage.enabled": "Включить",
|
||||
"betterfoliage.enabled.tooltip": "Включена ли эта функция?",
|
||||
"betterfoliage.hOffset": "Горизонтальное смещение",
|
||||
"betterfoliage.hOffset.tooltip": "Дистанция горизонтального смещения этого элемента в блоках",
|
||||
"betterfoliage.vOffset": "Вертикальное смещение",
|
||||
"betterfoliage.vOffset.tooltip": "Дистанция вертикального смещения этого элемента в блоках",
|
||||
"betterfoliage.size": "Размер",
|
||||
"betterfoliage.size.tooltip": "Размер этого элемента",
|
||||
"betterfoliage.heightMin": "Минимальная высота",
|
||||
"betterfoliage.heightMin.tooltip": "Минимальная высота элемента",
|
||||
"betterfoliage.heightMax": "Максимальная высота",
|
||||
"betterfoliage.heightMax.tooltip": "Максимальная высота этого элемента",
|
||||
"betterfoliage.population": "Популяция",
|
||||
"betterfoliage.population.tooltip": "Шанс (N к 64), что блок будет иметь эту функцию",
|
||||
"betterfoliage.shaderWind": "Шейдерные эффекты ветра",
|
||||
"betterfoliage.shaderWind.tooltip": "Применить эффекты ветра с ShaderMod для этого элемента?",
|
||||
"betterfoliage.distance": "Лимит дистанции",
|
||||
"betterfoliage.distance.tooltip": "Максимальное расстояние от игрока для рендеринга этой функции",
|
||||
"betterfoliage.saturationThreshold": "Порог насыщения",
|
||||
"betterfoliage.saturationThreshold.tooltip": "Насыщенность цвета разделяется на: \"обесцвеченные\" блоки (используя цвет биома) и \"цветные\" блоки (используя их собственный цвет)",
|
||||
|
||||
"betterfoliage.leaves": "Улучшенная листва",
|
||||
"betterfoliage.leaves.tooltip": "Дополнительное округление листьев на блоках листвы.",
|
||||
"betterfoliage.leaves.dense": "Плотный режим",
|
||||
"betterfoliage.leaves.dense.tooltip": "Плотный режим имеет более округлые листья.",
|
||||
|
||||
"betterfoliage.shortGrass": "Низкая трава и мицелий",
|
||||
"betterfoliage.shortGrass.tooltip": "Пучки травы / мицелия на поверхности соответствующих блоков.",
|
||||
"betterfoliage.shortGrass.useGenerated": "Использовать сгенерированные текстуры для травы.",
|
||||
"betterfoliage.shortGrass.useGenerated.tooltip": "Сгенерированная текстура создается путём разрезания текстуры высокой травы с активного ресурс-пака пополам.",
|
||||
"betterfoliage.shortGrass.myceliumEnabled": "Включить мицелий",
|
||||
"betterfoliage.shortGrass.myceliumEnabled.tooltip": "Включить эту особенность для блоков мицелия?",
|
||||
"betterfoliage.shortGrass.grassEnabled": "Включить траву",
|
||||
"betterfoliage.shortGrass.grassEnabled.tooltip": "Включить эту особенность для блоков травы?",
|
||||
"betterfoliage.shortGrass.snowEnabled": "Включить траву под снегом",
|
||||
"betterfoliage.shortGrass.snowEnabled.tooltip": "Включить эту особенность для заснеженных блоков травы?",
|
||||
|
||||
"betterfoliage.hangingGrass": "Висячая трава",
|
||||
"betterfoliage.hangingGrass.tooltip": "Пучки травы свисают вниз с верхних краев блока травы.",
|
||||
"betterfoliage.hangingGrass.separation": "Разделение",
|
||||
"betterfoliage.hangingGrass.separation.tooltip": "Как долго подвесная трава выделяется из блока?",
|
||||
|
||||
"betterfoliage.cactus": "Улучшенные кактусы",
|
||||
"betterfoliage.cactus.tooltip": "Улучшить кактус с дополнительными частицами и плавными тенями.",
|
||||
"betterfoliage.cactus.sizeVariation": "Вариации размера",
|
||||
"betterfoliage.cactus.sizeVariation.tooltip": "Количество случайных изменений в размере кактусов.",
|
||||
|
||||
"betterfoliage.lilypad": "Улучшенные кувшинки",
|
||||
"betterfoliage.lilypad.tooltip": "Добавить кувшинкам корни и цветы.",
|
||||
"betterfoliage.lilypad.flowerChance": "Шанс появления цветов",
|
||||
"betterfoliage.lilypad.flowerChance.tooltip": "Шанс (N к 64) появления цветка на кувшинке.",
|
||||
|
||||
"betterfoliage.reed": "Камыши",
|
||||
"betterfoliage.reed.tooltip": "Мелководные камыши на блоках земли.",
|
||||
"betterfoliage.reed.biomes": "Список биомов",
|
||||
"betterfoliage.reed.biomes.tooltip": "Настройка биомов, в которых камышам разрешено появляться.",
|
||||
"betterfoliage.reed.biomes.tooltip.element": "Должны ли камыши встречаться в %s биоме?",
|
||||
|
||||
"betterfoliage.algae": "Морские водоросли",
|
||||
"betterfoliage.algae.tooltip": "Глубоководные водоросли на блоках земли.",
|
||||
"betterfoliage.algae.biomes": "Список биомов",
|
||||
"betterfoliage.algae.biomes.tooltip": "Настройка биомов, в которых водорослям разрешено появляться.",
|
||||
"betterfoliage.algae.biomes.tooltip.element": "Должны ли водоросли встречаться в %s биоме?",
|
||||
|
||||
"betterfoliage.coral": "Кораллы",
|
||||
"betterfoliage.coral.tooltip": "Кораллы на песчаных блоках в глубокой воде.",
|
||||
"betterfoliage.coral.size": "Размер кораллов",
|
||||
"betterfoliage.coral.size.tooltip": "Размер торчащих частичек кораллов.",
|
||||
"betterfoliage.coral.crustSize": "Размер коры",
|
||||
"betterfoliage.coral.crustSize.tooltip": "Размер плоской части кораллов.",
|
||||
"betterfoliage.coral.chance": "Шанс кораллов",
|
||||
"betterfoliage.coral.chance.tooltip": "Шанс (N in 64) появления кораллов на определенном блоке.",
|
||||
"betterfoliage.coral.biomes": "Список биомов",
|
||||
"betterfoliage.coral.biomes.tooltip": "Настройка биомов, в которых разрешено появляться кораллам.",
|
||||
"betterfoliage.coral.biomes.tooltip.element": "Должны ли кораллы появляться в %s биоме?",
|
||||
"betterfoliage.coral.shallowWater": "Мелководные кораллы",
|
||||
"betterfoliage.coral.shallowWater.tooltip": "Должны ли появляться кораллы в воде, глубиной в 1 блок?",
|
||||
|
||||
"betterfoliage.netherrack": "Адская лоза",
|
||||
"betterfoliage.netherrack.tooltip": "Висячая лоза под адским камнем",
|
||||
|
||||
"betterfoliage.fallingLeaves": "Падающие листья",
|
||||
"betterfoliage.fallingLeaves.tooltip": "Падение FX частиц листвы исходящие из низа блоков листвы",
|
||||
"betterfoliage.fallingLeaves.speed": "Скорость частиц",
|
||||
"betterfoliage.fallingLeaves.speed.tooltip": "Общая скорость частиц",
|
||||
"betterfoliage.fallingLeaves.windStrength": "Сила ветра",
|
||||
"betterfoliage.fallingLeaves.windStrength.tooltip": "Величина воздействия ветра в хорошую погоду (распространение нормального распределения сосредоточено на 0)",
|
||||
"betterfoliage.fallingLeaves.stormStrength": "Сила шторма",
|
||||
"betterfoliage.fallingLeaves.stormStrength.tooltip": "Дополнительная величина воздействия ветра в ненастную погоду (распространение нормального распределения сосредоточено на 0)",
|
||||
"betterfoliage.fallingLeaves.size": "Размер частиц",
|
||||
"betterfoliage.fallingLeaves.chance": "Шанс частиц",
|
||||
"betterfoliage.fallingLeaves.chance.tooltip": "Вероятность каждого случайного рендеринга в такт (1/20 секунды) опадения частицы блока листвы.",
|
||||
"betterfoliage.fallingLeaves.perturb": "Возмущение",
|
||||
"betterfoliage.fallingLeaves.perturb.tooltip": "Величина эффекта возмущений. Добавляет штопорообразное движение к частице синхронизированной с его вращением.",
|
||||
"betterfoliage.fallingLeaves.lifetime": "Максимальное время жизни",
|
||||
"betterfoliage.fallingLeaves.lifetime.tooltip": "Максимальное время жизни частиц. Минимальное время жизни - 60%% от этого значения.",
|
||||
"betterfoliage.fallingLeaves.opacityHack": "Непрозрачные частицы",
|
||||
"betterfoliage.fallingLeaves.opacityHack.tooltip": "Запретить прозрачным блокам затемнять частицы даже тогда, когда частицы впереди. ВНИМАНИЕ: может спровоцировать баги.",
|
||||
|
||||
"betterfoliage.risingSoul": "Адские духи",
|
||||
"betterfoliage.risingSoul.tooltip": "Количество душ-частиц FX, испускаемых из верхней части блоков песка душ.",
|
||||
"betterfoliage.risingSoul.chance": "Шанс частиц",
|
||||
"betterfoliage.risingSoul.chance.tooltip": "Частота генерации частиц на песке душ.",
|
||||
"betterfoliage.risingSoul.speed": "Скорость частиц",
|
||||
"betterfoliage.risingSoul.speed.tooltip": "Вертикальная скорость движения частиц духов.",
|
||||
"betterfoliage.risingSoul.perturb": "Возмущение",
|
||||
"betterfoliage.risingSoul.perturb.tooltip": "Магнитуда эффекта возмущений. Добавляет штопороподобное движение частиц.",
|
||||
"betterfoliage.risingSoul.headSize": "Размер духа",
|
||||
"betterfoliage.risingSoul.headSize.tooltip": "Размер частицы духа",
|
||||
"betterfoliage.risingSoul.trailSize": "Размер следов",
|
||||
"betterfoliage.risingSoul.trailSize.tooltip": "Начальный размер следа частиц",
|
||||
"betterfoliage.risingSoul.opacity": "Прозрачность",
|
||||
"betterfoliage.risingSoul.opacity.tooltip": "Непрозрачность эффекта частиц",
|
||||
"betterfoliage.risingSoul.sizeDecay": "Размер распада",
|
||||
"betterfoliage.risingSoul.sizeDecay.tooltip": "Следующий размер частицы соответствует их же размеру в предыдущем такте (1/20 секунды).",
|
||||
"betterfoliage.risingSoul.opacityDecay": "Непрозрачность распада",
|
||||
"betterfoliage.risingSoul.opacityDecay.tooltip": "Следующий уровень прозрачности частицы соответствует их же уровню прозрачности в предыдущем такте (1/20 секунды).",
|
||||
"betterfoliage.risingSoul.lifetime": "Максимальное время жизни",
|
||||
"betterfoliage.risingSoul.lifetime.tooltip": "Максимальное время жизни эффекта частиц. Минимальное время жизни равно 60%% от этого числа.",
|
||||
"betterfoliage.risingSoul.trailLength": "Длина следов",
|
||||
"betterfoliage.risingSoul.trailLength.tooltip": "Количество предыдущих позиций, которые запомнила частица в тактах (1/20 секунды).",
|
||||
"betterfoliage.risingSoul.trailDensity": "Плотность следов",
|
||||
"betterfoliage.risingSoul.trailDensity.tooltip": "Рендер каждой предыдущий N’ой позиции в следах частиц.",
|
||||
|
||||
|
||||
"betterfoliage.connectedGrass": "Соединенные текстуры травы",
|
||||
"betterfoliage.connectedGrass.enabled": "Включить",
|
||||
"betterfoliage.connectedGrass.enabled.tooltip": "Если блок травы находится над блоком земли: прорисовать верхнюю текстуру травы на всех сторонах блока травы.",
|
||||
|
||||
"betterfoliage.roundLogs": "Цилиндрические брёвна",
|
||||
"betterfoliage.roundLogs.tooltip": "Соединить круглые блоки в сплошные, полные блоки?",
|
||||
"betterfoliage.roundLogs.connectSolids": "Соединение в крупные брёвна",
|
||||
"betterfoliage.roundLogs.connectSolids.tooltip": "Соединить круглые блоки в сплошные, полные блоки?",
|
||||
"betterfoliage.roundLogs.connectPerpendicular": "Соединение в перпендикулярные брёвна",
|
||||
"betterfoliage.roundLogs.connectPerpendicular.tooltip": "Соединить круглые брёвна к перпендикулярным брёвнам относительно их оси?",
|
||||
"betterfoliage.roundLogs.lenientConnect": "Мягкое округление",
|
||||
"betterfoliage.roundLogs.lenientConnect.tooltip": "Соединение в параллельные круглые брёвна L-формы, не только 2х2.",
|
||||
"betterfoliage.roundLogs.connectGrass": "Соединенная трава",
|
||||
"betterfoliage.roundLogs.connectGrass.tooltip": "Заменяет землю под деревьями на траву, если она есть поблизости.",
|
||||
"betterfoliage.roundLogs.radiusSmall": "Радиус фаски",
|
||||
"betterfoliage.roundLogs.radiusSmall.tooltip": "Радиус обрезки углов от бревна.",
|
||||
"betterfoliage.roundLogs.radiusLarge": "Радиус соединенной фаски",
|
||||
"betterfoliage.roundLogs.radiusLarge.tooltip": "Радиус среза внешнего угла соединённых брёвен.",
|
||||
"betterfoliage.roundLogs.dimming": "Затемнение",
|
||||
"betterfoliage.roundLogs.dimming.tooltip": "Затемнить неясные длинные грани.",
|
||||
"betterfoliage.roundLogs.zProtection": "Z-Защита",
|
||||
"betterfoliage.roundLogs.zProtection.tooltip": "Для масштабирования параллельных битов соединения бревен, чтобы остановить Z-бой (мерцание). Попробуйте установить его как можно выше, для устранения мерцания."
|
||||
}
|
||||
@@ -1,213 +0,0 @@
|
||||
key.betterfoliage.gui=Открыть настройки
|
||||
|
||||
betterfoliage.global.enabled=Включить мод
|
||||
betterfoliage.global.enabled.tooltip=Если установлено на false, BetterFoliage не будет ничего рендерить
|
||||
|
||||
betterfoliage.enabled=Включить
|
||||
betterfoliage.enabled.tooltip=Включена ли эта функция?
|
||||
betterfoliage.hOffset=Горизонтальное смещение
|
||||
betterfoliage.hOffset.tooltip=Дистанция горизонтального смещения этого элемента в блоках
|
||||
betterfoliage.vOffset=Вертикальное смещение
|
||||
betterfoliage.vOffset.tooltip=Дистанция вертикального смещения этого элемента в блоках
|
||||
betterfoliage.size=Размер
|
||||
betterfoliage.size.tooltip=Размер этого элемента
|
||||
betterfoliage.heightMin=Минимальная высота
|
||||
betterfoliage.heightMin.tooltip=Минимальная высота элемента
|
||||
betterfoliage.heightMax=Максимальная высота
|
||||
betterfoliage.heightMax.tooltip=Максимальная высота этого элемента
|
||||
betterfoliage.population=Популяция
|
||||
betterfoliage.population.tooltip=Шанс (N к 64), что блок будет иметь эту функцию
|
||||
betterfoliage.shaderWind=Шейдерные эффекты ветра
|
||||
betterfoliage.shaderWind.tooltip=Применить эффекты ветра с ShaderMod для этого элемента?
|
||||
betterfoliage.distance=Лимит дистанции
|
||||
betterfoliage.distance.tooltip=Максимальное расстояние от игрока для рендеринга этой функции
|
||||
|
||||
betterfoliage.blocks=Типы блоков
|
||||
betterfoliage.blocks.tooltip=Настройки списка классов блоков, которые будут иметь примененные к ним функции
|
||||
|
||||
betterfoliage.blocks.dirtWhitelist=Белый список земли
|
||||
betterfoliage.blocks.dirtBlacklist=Черный список земли
|
||||
betterfoliage.blocks.dirtWhitelist.arrayEntry=%d записей
|
||||
betterfoliage.blocks.dirtBlacklist.arrayEntry=%d записей
|
||||
|
||||
betterfoliage.blocks.grassWhitelist=Белый список травы
|
||||
betterfoliage.blocks.grassBlacklist=Черный список травы
|
||||
betterfoliage.blocks.grassWhitelist.arrayEntry=%d записей
|
||||
betterfoliage.blocks.grassBlacklist.arrayEntry=%d записей
|
||||
|
||||
betterfoliage.blocks.leavesWhitelist=Белый список листвы
|
||||
betterfoliage.blocks.leavesBlacklist=Черный список листвы
|
||||
betterfoliage.blocks.leavesWhitelist.arrayEntry=%d записей
|
||||
betterfoliage.blocks.leavesBlacklist.arrayEntry=%d записей
|
||||
|
||||
betterfoliage.blocks.cropsWhitelist=Белый список урожая
|
||||
betterfoliage.blocks.cropsBlacklist=Черный список урожая
|
||||
betterfoliage.blocks.cropsWhitelist.arrayEntry=%d записей
|
||||
betterfoliage.blocks.cropsBlacklist.arrayEntry=%d записей
|
||||
|
||||
betterfoliage.blocks.logsWhitelist=Белый список древесины
|
||||
betterfoliage.blocks.logsBlacklist=Черный список древесины
|
||||
betterfoliage.blocks.logsWhitelist.arrayEntry=%d записей
|
||||
betterfoliage.blocks.logsBlacklist.arrayEntry=%d записей
|
||||
|
||||
betterfoliage.blocks.sandWhitelist=Белый список песка
|
||||
betterfoliage.blocks.sandBlacklist=Черный список песка
|
||||
betterfoliage.blocks.sandWhitelist.arrayEntry=%d записей
|
||||
betterfoliage.blocks.sandBlacklist.arrayEntry=%d записей
|
||||
|
||||
betterfoliage.blocks.lilypadWhitelist=Белый список кувшинок
|
||||
betterfoliage.blocks.lilypadBlacklist=Черный список кувшинок
|
||||
betterfoliage.blocks.lilypadWhitelist.arrayEntry=%d записей
|
||||
betterfoliage.blocks.lilypadBlacklist.arrayEntry=%d записей
|
||||
|
||||
betterfoliage.blocks.cactusWhitelist=Белый список кактусов
|
||||
betterfoliage.blocks.cactusBlacklist=Черный список кактусов
|
||||
betterfoliage.blocks.cactusWhitelist.arrayEntry=%d записей
|
||||
betterfoliage.blocks.cactusBlacklist.arrayEntry=%d записей
|
||||
|
||||
|
||||
betterfoliage.blocks.dirtWhitelist.tooltip=Блоки, которые будут восприниматься в качестве земли. Влияет на камыши, водоросли, соединенную траву.
|
||||
betterfoliage.blocks.dirtBlacklist.tooltip=Блоки, которые не будут восприниматься в качестве земли. Влияет на камыши, водоросли, соединенную траву.
|
||||
betterfoliage.blocks.grassWhitelist.tooltip=Блоки, которые будут восприниматься в качестве травы. Влияет на короткую и соединенную траву.
|
||||
betterfoliage.blocks.grassBlacklist.tooltip=Блоки, которые не будут восприниматься в качестве травы. Влияет на короткую и соединенную траву.
|
||||
betterfoliage.blocks.leavesWhitelist.tooltip=Блоки, которые будут восприниматься в качестве листвы. Влияет на дополнительную листву, падающую листву. Листва будут рендериться с ID листвы в шейдер-программах.
|
||||
betterfoliage.blocks.leavesBlacklist.tooltip=Блоки, которые никогда не будут восприниматься как листва. Влияет на дополнительную листву, падающую листву. Листва будут рендериться с ID листвы в шейдер-программах.
|
||||
betterfoliage.blocks.cropsWhitelist.tooltip=Блоки, которые будут восприниматься как культуры. Культуры будут рендериться с ID высокой травы в шейдер-программах.
|
||||
betterfoliage.blocks.cropsBlacklist.tooltip= Блоки, которые никогда не будут восприниматься как культуры. Культуры будут рендериться с ID высокой травы в шейдер-программах.
|
||||
betterfoliage.blocks.logsWhitelist.tooltip=Блоки, которые будут восприниматься в качестве деревянных брёвен. Влияет на цилиндрические брёвна.
|
||||
betterfoliage.blocks.logsBlacklist.tooltip=Блоки, которые никогда не будут восприниматься в качестве деревянных брёвен. Влияет на цилиндрические брёвна.
|
||||
betterfoliage.blocks.sandWhitelist.tooltip=Блоки, которые будут восприниматься в качестве песка. Влияет на кораллы.
|
||||
betterfoliage.blocks.sandBlacklist.tooltip=Блоки, которые никогда не будут восприниматься в качестве песка. Влияет на кораллы.
|
||||
betterfoliage.blocks.lilypadWhitelist.tooltip=Блоки, которые будут восприниматься в качестве кувшинок. Влияет на улучшенные кувшинки.
|
||||
betterfoliage.blocks.lilypadBlacklist.tooltip=Блоки, которые никогда не будут восприниматься в качестве кувшинок. Влияет на улучшенные кувшинки.
|
||||
betterfoliage.blocks.cactusWhitelist.tooltip=Блоки, которые будут восприниматься в качестве кактусов. Влияет на улучшенные кактусы.
|
||||
betterfoliage.blocks.cactusBlacklist.tooltip=Блоки, которые никогда не будут восприниматься в качестве кувшинок. Влияет на улучшенные кактусы.
|
||||
|
||||
betterfoliage.leaves=Улучшенная листва
|
||||
betterfoliage.leaves.tooltip=Дополнительное округление листьев на блоках листвы.
|
||||
betterfoliage.leaves.dense=Плотный режим
|
||||
betterfoliage.leaves.dense.tooltip=Плотный режим имеет более округлые листья.
|
||||
|
||||
betterfoliage.shortGrass=Низкая трава и мицелий
|
||||
betterfoliage.shortGrass.tooltip=Пучки травы / мицелия на поверхности соответствующих блоков.
|
||||
betterfoliage.shortGrass.useGenerated=Использовать сгенерированные текстуры для травы.
|
||||
betterfoliage.shortGrass.useGenerated.tooltip=Сгенерированная текстура создается путём разрезания текстуры высокой травы с активного ресурс-пака пополам.
|
||||
betterfoliage.shortGrass.myceliumEnabled=Включить мицелий
|
||||
betterfoliage.shortGrass.myceliumEnabled.tooltip=Включить эту особенность для блоков мицелия?
|
||||
betterfoliage.shortGrass.grassEnabled=Включить траву
|
||||
betterfoliage.shortGrass.grassEnabled.tooltip=Включить эту особенность для блоков травы?
|
||||
betterfoliage.shortGrass.snowEnabled=Включить траву под снегом
|
||||
betterfoliage.shortGrass.snowEnabled.tooltip=Включить эту особенность для заснеженных блоков травы?
|
||||
betterfoliage.shortGrass.saturationThreshold=Порог насыщения
|
||||
betterfoliage.shortGrass.saturationThreshold.tooltip=Насыщенность цвета разделяется на: "обесцвеченные" блоки (используя цвет биома) и "цветные" блоки (используя их собственный цвет)
|
||||
|
||||
betterfoliage.hangingGrass=Висячая трава
|
||||
betterfoliage.hangingGrass.tooltip=Пучки травы свисают вниз с верхних краев блока травы.
|
||||
betterfoliage.hangingGrass.separation=Разделение
|
||||
betterfoliage.hangingGrass.separation.tooltip=Как долго подвесная трава выделяется из блока?
|
||||
|
||||
betterfoliage.cactus=Улучшенные кактусы
|
||||
betterfoliage.cactus.tooltip=Улучшить кактус с дополнительными частицами и плавными тенями.
|
||||
betterfoliage.cactus.sizeVariation=Вариации размера
|
||||
betterfoliage.cactus.sizeVariation.tooltip=Количество случайных изменений в размере кактусов.
|
||||
|
||||
betterfoliage.lilypad=Улучшенные кувшинки
|
||||
betterfoliage.lilypad.tooltip=Добавить кувшинкам корни и цветы.
|
||||
betterfoliage.lilypad.flowerChance=Шанс появления цветов
|
||||
betterfoliage.lilypad.flowerChance.tooltip=Шанс (N к 64) появления цветка на кувшинке.
|
||||
|
||||
betterfoliage.reed=Камыши
|
||||
betterfoliage.reed.tooltip=Мелководные камыши на блоках земли.
|
||||
betterfoliage.reed.biomes=Список биомов
|
||||
betterfoliage.reed.biomes.tooltip=Настройка биомов, в которых камышам разрешено появляться.
|
||||
betterfoliage.reed.biomes.tooltip.element=Должны ли камыши встречаться в %s биоме?
|
||||
|
||||
betterfoliage.algae=Морские водоросли
|
||||
betterfoliage.algae.tooltip=Глубоководные водоросли на блоках земли.
|
||||
betterfoliage.algae.biomes=Список биомов
|
||||
betterfoliage.algae.biomes.tooltip=Настройка биомов, в которых водорослям разрешено появляться.
|
||||
betterfoliage.algae.biomes.tooltip.element=Должны ли водоросли встречаться в %s биоме?
|
||||
|
||||
betterfoliage.coral=Кораллы
|
||||
betterfoliage.coral.tooltip=Кораллы на песчаных блоках в глубокой воде.
|
||||
betterfoliage.coral.size=Размер кораллов
|
||||
betterfoliage.coral.size.tooltip=Размер торчащих частичек кораллов.
|
||||
betterfoliage.coral.crustSize=Размер коры
|
||||
betterfoliage.coral.crustSize.tooltip=Размер плоской части кораллов.
|
||||
betterfoliage.coral.chance=Шанс кораллов
|
||||
betterfoliage.coral.chance.tooltip=Шанс (N in 64) появления кораллов на определенном блоке.
|
||||
betterfoliage.coral.biomes=Список биомов
|
||||
betterfoliage.coral.biomes.tooltip=Настройка биомов, в которых разрешено появляться кораллам.
|
||||
betterfoliage.coral.biomes.tooltip.element=Должны ли кораллы появляться в %s биоме?
|
||||
betterfoliage.coral.shallowWater=Мелководные кораллы
|
||||
betterfoliage.coral.shallowWater.tooltip=Должны ли появляться кораллы в воде, глубиной в 1 блок?
|
||||
|
||||
betterfoliage.netherrack=Адская лоза
|
||||
betterfoliage.netherrack.tooltip=Висячая лоза под адским камнем
|
||||
|
||||
betterfoliage.fallingLeaves=Падающие листья
|
||||
betterfoliage.fallingLeaves.tooltip=Падение FX частиц листвы исходящие из низа блоков листвы
|
||||
betterfoliage.fallingLeaves.speed=Скорость частиц
|
||||
betterfoliage.fallingLeaves.speed.tooltip=Общая скорость частиц
|
||||
betterfoliage.fallingLeaves.windStrength=Сила ветра
|
||||
betterfoliage.fallingLeaves.windStrength.tooltip=Величина воздействия ветра в хорошую погоду (распространение нормального распределения сосредоточено на 0)
|
||||
betterfoliage.fallingLeaves.stormStrength=Сила шторма
|
||||
betterfoliage.fallingLeaves.stormStrength.tooltip=Дополнительная величина воздействия ветра в ненастную погоду (распространение нормального распределения сосредоточено на 0)
|
||||
betterfoliage.fallingLeaves.size=Размер частиц
|
||||
betterfoliage.fallingLeaves.chance=Шанс частиц
|
||||
betterfoliage.fallingLeaves.chance.tooltip=Вероятность каждого случайного рендеринга в такт (1/20 секунды) опадения частицы блока листвы.
|
||||
betterfoliage.fallingLeaves.perturb=Возмущение
|
||||
betterfoliage.fallingLeaves.perturb.tooltip=Величина эффекта возмущений. Добавляет штопорообразное движение к частице синхронизированной с его вращением.
|
||||
betterfoliage.fallingLeaves.lifetime=Максимальное время жизни
|
||||
betterfoliage.fallingLeaves.lifetime.tooltip=Максимальное время жизни частиц. Минимальное время жизни - 60%% от этого значения.
|
||||
betterfoliage.fallingLeaves.opacityHack=Непрозрачные частицы
|
||||
betterfoliage.fallingLeaves.opacityHack.tooltip=Запретить прозрачным блокам затемнять частицы даже тогда, когда частицы впереди. ВНИМАНИЕ: может спровоцировать баги.
|
||||
|
||||
betterfoliage.risingSoul=Адские духи
|
||||
betterfoliage.risingSoul.tooltip=Количество душ-частиц FX, испускаемых из верхней части блоков песка душ.
|
||||
betterfoliage.risingSoul.chance=Шанс частиц
|
||||
betterfoliage.risingSoul.chance.tooltip=Частота генерации частиц на песке душ.
|
||||
betterfoliage.risingSoul.speed=Скорость частиц
|
||||
betterfoliage.risingSoul.speed.tooltip=Вертикальная скорость движения частиц духов.
|
||||
betterfoliage.risingSoul.perturb=Возмущение
|
||||
betterfoliage.risingSoul.perturb.tooltip=Магнитуда эффекта возмущений. Добавляет штопороподобное движение частиц.
|
||||
betterfoliage.risingSoul.headSize=Размер духа
|
||||
betterfoliage.risingSoul.headSize.tooltip=Размер частицы духа
|
||||
betterfoliage.risingSoul.trailSize=Размер следов
|
||||
betterfoliage.risingSoul.trailSize.tooltip=Начальный размер следа частиц
|
||||
betterfoliage.risingSoul.opacity=Прозрачность
|
||||
betterfoliage.risingSoul.opacity.tooltip=Непрозрачность эффекта частиц
|
||||
betterfoliage.risingSoul.sizeDecay=Размер распада
|
||||
betterfoliage.risingSoul.sizeDecay.tooltip=Следующий размер частицы соответствует их же размеру в предыдущем такте (1/20 секунды).
|
||||
betterfoliage.risingSoul.opacityDecay=Непрозрачность распада
|
||||
betterfoliage.risingSoul.opacityDecay.tooltip=Следующий уровень прозрачности частицы соответствует их же уровню прозрачности в предыдущем такте (1/20 секунды).
|
||||
betterfoliage.risingSoul.lifetime=Максимальное время жизни
|
||||
betterfoliage.risingSoul.lifetime.tooltip=Максимальное время жизни эффекта частиц. Минимальное время жизни равно 60%% от этого числа.
|
||||
betterfoliage.risingSoul.trailLength=Длина следов
|
||||
betterfoliage.risingSoul.trailLength.tooltip=Количество предыдущих позиций, которые запомнила частица в тактах (1/20 секунды).
|
||||
betterfoliage.risingSoul.trailDensity=Плотность следов
|
||||
betterfoliage.risingSoul.trailDensity.tooltip=Рендер каждой предыдущий N’ой позиции в следах частиц.
|
||||
|
||||
|
||||
betterfoliage.connectedGrass=Соединенные текстуры травы
|
||||
betterfoliage.connectedGrass.enabled=Включить
|
||||
betterfoliage.connectedGrass.enabled.tooltip=Если блок травы находится над блоком земли: прорисовать верхнюю текстуру травы на всех сторонах блока травы.
|
||||
|
||||
betterfoliage.roundLogs=Цилиндрические брёвна
|
||||
betterfoliage.roundLogs.tooltip=Соединить круглые блоки в сплошные, полные блоки?
|
||||
betterfoliage.roundLogs.connectSolids=Соединение в крупные брёвна
|
||||
betterfoliage.roundLogs.connectSolids.tooltip=Соединить круглые блоки в сплошные, полные блоки?
|
||||
betterfoliage.roundLogs.connectPerpendicular=Соединение в перпендикулярные брёвна
|
||||
betterfoliage.roundLogs.connectPerpendicular.tooltip=Соединить круглые брёвна к перпендикулярным брёвнам относительно их оси?
|
||||
betterfoliage.roundLogs.lenientConnect=Мягкое округление
|
||||
betterfoliage.roundLogs.lenientConnect.tooltip=Соединение в параллельные круглые брёвна L-формы, не только 2х2.
|
||||
betterfoliage.roundLogs.connectGrass=Соединенная трава
|
||||
betterfoliage.roundLogs.connectGrass.tooltip=Заменяет землю под деревьями на траву, если она есть поблизости.
|
||||
betterfoliage.roundLogs.radiusSmall=Радиус фаски
|
||||
betterfoliage.roundLogs.radiusSmall.tooltip=Радиус обрезки углов от бревна.
|
||||
betterfoliage.roundLogs.radiusLarge=Радиус соединенной фаски
|
||||
betterfoliage.roundLogs.radiusLarge.tooltip=Радиус среза внешнего угла соединённых брёвен.
|
||||
betterfoliage.roundLogs.dimming=Затемнение
|
||||
betterfoliage.roundLogs.dimming.tooltip=Затемнить неясные длинные грани.
|
||||
betterfoliage.roundLogs.zProtection=Z-Защита
|
||||
betterfoliage.roundLogs.zProtection.tooltip=Для масштабирования параллельных битов соединения бревен, чтобы остановить Z-бой (мерцание). Попробуйте установить его как можно выше, для устранения мерцания.
|
||||
177
src/main/resources/assets/betterfoliage/lang/zh_cn.json
Normal file
177
src/main/resources/assets/betterfoliage/lang/zh_cn.json
Normal file
@@ -0,0 +1,177 @@
|
||||
{
|
||||
"key.betterfoliage.gui": "打开BF设置",
|
||||
|
||||
"betterfoliage.global.enabled": "模组使用",
|
||||
"betterfoliage.global.enabled.tooltip": "如果关闭,BetterFoliage不会呈现任何东西",
|
||||
"betterfoliage.nVidia": "nVidia GPU",
|
||||
"betterfoliage.nVidia.tooltip": "明确你是否有一个nVidia GPU",
|
||||
|
||||
"betterfoliage.enabled": "启用",
|
||||
"betterfoliage.enabled.tooltip": "要启用这个功能吗?",
|
||||
"betterfoliage.hOffset": "水平偏移",
|
||||
"betterfoliage.hOffset.tooltip": "在方块中这个元素是横向距离移动的",
|
||||
"betterfoliage.vOffset": "垂直偏移",
|
||||
"betterfoliage.vOffset.tooltip": "在方块中这个元素是横向距离移动的",
|
||||
"betterfoliage.size": "尺寸",
|
||||
"betterfoliage.size.tooltip": "该元素的尺寸",
|
||||
"betterfoliage.heightMin": "最小高度",
|
||||
"betterfoliage.heightMin.tooltip": "最小元素的高度",
|
||||
"betterfoliage.heightMax": "最大高度",
|
||||
"betterfoliage.heightMax.tooltip": "最大元素的高度",
|
||||
"betterfoliage.population": "物体密度",
|
||||
"betterfoliage.population.tooltip": "生成的概率为64分之1",
|
||||
"betterfoliage.shaderWind": "光影水反中的 风的影响",
|
||||
"betterfoliage.shaderWind.tooltip": "能适用于光影水反中的\"风的影响\" 这一元素?",
|
||||
"betterfoliage.distance": "距离限制",
|
||||
"betterfoliage.distance.tooltip": "离游戏者的最大距离,在这个范围内呈现这个特征",
|
||||
"betterfoliage.saturationThreshold": "饱和度阈值",
|
||||
"betterfoliage.saturationThreshold.tooltip": "色彩饱和度将介于\"无色\"方块(使用生物群系的颜色)和\"有色\"方块(使用材质特定颜色)之间",
|
||||
|
||||
"betterfoliage.rendererror": "§a[BF更好的叶子]§f 错误:渲染方块 %s 此位置 %s",
|
||||
|
||||
"betterfoliage.shaders": "着色器配置",
|
||||
"betterfoliage.shaders.tooltip": "Configure integration with shaders",
|
||||
"betterfoliage.shaders.leavesId": "叶子 ID",
|
||||
"betterfoliage.shaders.leavesId.tooltip": "方块 ID 将作为所有叶片都使用的相同ID提供给光影水反 如果你的光影水反文件使用了一个 §6block.properties§e 文件, 你可能需要修改这个以匹配光影水反的映射",
|
||||
"betterfoliage.shaders.grassId": "草 ID",
|
||||
"betterfoliage.shaders.grassId.tooltip": "方块 ID 将作为所有的草和作物都使用的相同ID提供给光影水反 如果你的光影水反文件使用了一个 §6block.properties§e 文件, 你可能需要修改这个以匹配光影水反的映射",
|
||||
|
||||
"betterfoliage.leaves": "额外的叶片",
|
||||
"betterfoliage.leaves.tooltip": "叶方块上额外的密叶",
|
||||
"betterfoliage.leaves.dense": "浓密模式",
|
||||
"betterfoliage.leaves.dense.tooltip": "浓密的叶子会有更多额外的叶片",
|
||||
"betterfoliage.leaves.snowEnabled": "启用雪覆盖叶片",
|
||||
"betterfoliage.leaves.snowEnabled.tooltip": "是否启用被雪覆盖的额外叶片?",
|
||||
"betterfoliage.leaves.hideInternal": "隐藏内部的叶片",
|
||||
"betterfoliage.leaves.hideInternal.tooltip": "如果该叶方块完全被其他叶方块或者固体方块包围,将不渲染额外的叶片",
|
||||
|
||||
"betterfoliage.shortGrass": "短草和菌丝",
|
||||
"betterfoliage.shortGrass.tooltip": "一簇小草或者一丛菌丝长在合适的方块的顶部",
|
||||
"betterfoliage.shortGrass.useGenerated": "为草使用mod创建的材质",
|
||||
"betterfoliage.shortGrass.useGenerated.tooltip": "mod创建的材质指的是将已选用的资源包中高草的材质切一半来用",
|
||||
"betterfoliage.shortGrass.myceliumEnabled": "使用在菌丝上",
|
||||
"betterfoliage.shortGrass.myceliumEnabled.tooltip": "将这个特性利用到菌丝中吗?",
|
||||
"betterfoliage.shortGrass.grassEnabled": "使用在草方块上",
|
||||
"betterfoliage.shortGrass.grassEnabled.tooltip": "将这个特性利用到草方块中吗?",
|
||||
"betterfoliage.shortGrass.snowEnabled": "使用在雪地里",
|
||||
"betterfoliage.shortGrass.snowEnabled.tooltip": "使用到被雪覆盖的草方块中去?",
|
||||
"betterfoliage.shortGrass.saturationThreshold": "饱和度阈值",
|
||||
"betterfoliage.shortGrass.saturationThreshold.tooltip": "色彩饱和度将介于\"无色\"方块(使用生物群系的颜色)和\"有色\"方块(使用材质特定颜色)之间",
|
||||
|
||||
"betterfoliage.connectedGrass": "草的纹理的连接",
|
||||
"betterfoliage.connectedGrass.tooltip": "使得草方块侧面拥有像顶面的材质",
|
||||
"betterfoliage.connectedGrass.enabled": "启用",
|
||||
"betterfoliage.connectedGrass.enabled.tooltip": "如果泥土上有草方块:所有的草方块的侧面换成草方块顶部的材质,",
|
||||
"betterfoliage.connectedGrass.snowEnabled": "使用在被雪覆盖的草方块上",
|
||||
"betterfoliage.connectedGrass.snowEnabled.tooltip": "是否应用于被雪覆盖的草方块上?",
|
||||
|
||||
"betterfoliage.hangingGrass": "悬挂的草",
|
||||
"betterfoliage.hangingGrass.tooltip": "草会在边缘的草方块上垂下来",
|
||||
"betterfoliage.hangingGrass.separation": "垂下来的距离",
|
||||
"betterfoliage.hangingGrass.separation.tooltip": "有多长的挂草会从草方块上垂下来",
|
||||
|
||||
"betterfoliage.cactus": "更好的仙人掌",
|
||||
"betterfoliage.cactus.tooltip": "用额外的仙人掌刺和圆润的形状来提高仙人掌的真实性",
|
||||
"betterfoliage.cactus.sizeVariation": "尺寸变化",
|
||||
"betterfoliage.cactus.sizeVariation.tooltip": "仙人掌的尺寸随机变化的范围",
|
||||
|
||||
"betterfoliage.lilypad": "更好的莲叶与荷花",
|
||||
"betterfoliage.lilypad.tooltip": "用莲叶的根和随机的莲花以提高莲叶的真实性",
|
||||
"betterfoliage.lilypad.flowerChance": "花的生成概率",
|
||||
"betterfoliage.lilypad.flowerChance.tooltip": "(64个莲叶中 N 个)莲叶具有花了",
|
||||
|
||||
"betterfoliage.reed": "芦苇",
|
||||
"betterfoliage.reed.tooltip": "芦苇会生成在浅水中的泥土块上",
|
||||
"betterfoliage.reed.biomes": "生物群系的列表",
|
||||
"betterfoliage.reed.biomes.tooltip": "配置允许出现芦苇的生物群系",
|
||||
"betterfoliage.reed.biomes.tooltip.element": "芦苇应该出现在%s生物群落?",
|
||||
|
||||
"betterfoliage.algae": "藻类",
|
||||
"betterfoliage.algae.tooltip": "藻类会生成在深水中的泥土块上",
|
||||
"betterfoliage.algae.biomes": "生物群系的列表",
|
||||
"betterfoliage.algae.biomes.tooltip": "配置允许出现藻类的生物群系",
|
||||
"betterfoliage.algae.biomes.tooltip.element": "藻类应该出现在%s生物群落?",
|
||||
|
||||
"betterfoliage.coral": "珊瑚",
|
||||
"betterfoliage.coral.tooltip": "珊瑚会生成在深水中的沙块上",
|
||||
"betterfoliage.coral.size": "珊瑚的大小",
|
||||
"betterfoliage.coral.size.tooltip": "珊瑚伸出的部分的大小",
|
||||
"betterfoliage.coral.crustSize": "外壳尺寸",
|
||||
"betterfoliage.coral.crustSize.tooltip": "珊瑚的平的部分的尺寸",
|
||||
"betterfoliage.coral.chance": "珊瑚的生成概率",
|
||||
"betterfoliage.coral.chance.tooltip": "64个特殊表面的方块中有N个有机会出现珊瑚",
|
||||
"betterfoliage.coral.biomes": "生物群落的列表",
|
||||
"betterfoliage.coral.biomes.tooltip": "配置允许出现珊瑚的生物群系",
|
||||
"betterfoliage.coral.biomes.tooltip.element": "珊瑚应该出现在%s生物群落?",
|
||||
"betterfoliage.coral.shallowWater": "浅海珊瑚",
|
||||
"betterfoliage.coral.shallowWater.tooltip": "珊瑚应该生成在深水1格?",
|
||||
|
||||
"betterfoliage.netherrack": "下界岩下面的藤蔓",
|
||||
"betterfoliage.netherrack.tooltip": "下界岩下面将挂上藤蔓",
|
||||
|
||||
"betterfoliage.fallingLeaves": "落叶",
|
||||
"betterfoliage.fallingLeaves.tooltip": "落叶粒子效果 FX 会从叶方块底部下落",
|
||||
"betterfoliage.fallingLeaves.speed": "粒子速度",
|
||||
"betterfoliage.fallingLeaves.speed.tooltip": "总体的粒子速度",
|
||||
"betterfoliage.fallingLeaves.windStrength": "柔风的强度",
|
||||
"betterfoliage.fallingLeaves.windStrength.tooltip": "在晴天中体现的风的效果(默认以0为中心散播)",
|
||||
"betterfoliage.fallingLeaves.stormStrength": "风暴的强度",
|
||||
"betterfoliage.fallingLeaves.stormStrength.tooltip": "附加在阴天里体现的风的效果(默认以0为中心散播)",
|
||||
"betterfoliage.fallingLeaves.size": "粒子大小",
|
||||
"betterfoliage.fallingLeaves.chance": "粒子生成机率",
|
||||
"betterfoliage.fallingLeaves.chance.tooltip": "随机渲染刻激发叶方块生成粒子的概率",
|
||||
"betterfoliage.fallingLeaves.perturb": "扰动",
|
||||
"betterfoliage.fallingLeaves.perturb.tooltip": "扰动的大小.增加了一个与之旋转同步的螺旋状动量",
|
||||
"betterfoliage.fallingLeaves.lifetime": "最长存在时间",
|
||||
"betterfoliage.fallingLeaves.lifetime.tooltip": "粒子的最长存在时间,仅在几秒内,最短时间为这个值60%%",
|
||||
"betterfoliage.fallingLeaves.opacityHack": "粒子不透明",
|
||||
"betterfoliage.fallingLeaves.opacityHack.tooltip": "阻止透明方块隐藏粒子,即使粒子已经在前面了.警告:可能会导致错误",
|
||||
|
||||
"betterfoliage.risingSoul": "灵魂沙上飘起的魂灵",
|
||||
"betterfoliage.risingSoul.tooltip": "灵魂沙的顶部飘出灵魂粒子 FX",
|
||||
"betterfoliage.risingSoul.chance": "粒子的生成机率",
|
||||
"betterfoliage.risingSoul.chance.tooltip": "随机渲染刻激发灵魂沙生成一个粒子的概率",
|
||||
"betterfoliage.risingSoul.speed": "粒子速度",
|
||||
"betterfoliage.risingSoul.speed.tooltip": "灵颗粒的垂直速度",
|
||||
"betterfoliage.risingSoul.perturb": "扰动",
|
||||
"betterfoliage.risingSoul.perturb.tooltip": "动的大小.增加了一个与之旋转同步的螺旋状动量",
|
||||
"betterfoliage.risingSoul.headSize": "魂灵的大小",
|
||||
"betterfoliage.risingSoul.headSize.tooltip": "灵魂粒子的大小",
|
||||
"betterfoliage.risingSoul.trailSize": "魂灵轨迹的大小",
|
||||
"betterfoliage.risingSoul.trailSize.tooltip": "灵魂粒子的轨迹的初始大小",
|
||||
"betterfoliage.risingSoul.opacity": "不透明度",
|
||||
"betterfoliage.risingSoul.opacity.tooltip": "粒子效果的不透明度",
|
||||
"betterfoliage.risingSoul.sizeDecay": "大小的衰减",
|
||||
"betterfoliage.risingSoul.sizeDecay.tooltip": "灵魂轨迹粒子大小与前一刻他的大小相关",
|
||||
"betterfoliage.risingSoul.opacityDecay": "不透明度的衰减",
|
||||
"betterfoliage.risingSoul.opacityDecay.tooltip": "灵魂轨迹粒子不透明度与前一刻他的不透明度相关",
|
||||
"betterfoliage.risingSoul.lifetime": "最长存在时间",
|
||||
"betterfoliage.risingSoul.lifetime.tooltip": "粒子的最长存在时间,仅在几秒内,最短时间为这个值60%%",
|
||||
"betterfoliage.risingSoul.trailLength": "魂灵轨迹长度",
|
||||
"betterfoliage.risingSoul.trailLength.tooltip": "在游戏刻内粒子记录的轨迹位置的数量",
|
||||
"betterfoliage.risingSoul.trailDensity": "魂灵轨迹密集程度",
|
||||
"betterfoliage.risingSoul.trailDensity.tooltip": "整条轨迹中渲染每第N个轨迹位置",
|
||||
|
||||
"betterfoliage.roundLogs": "圆木",
|
||||
"betterfoliage.roundLogs.tooltip": "使木方块拥有八角形的横截面",
|
||||
"betterfoliage.roundLogs.plantsOnly": "仅仅应用于植物性材料",
|
||||
"betterfoliage.roundLogs.plantsOnly.tooltip": "是否仅仅应用于木质材料和干草堆,而不是所有圆柱方块?",
|
||||
"betterfoliage.roundLogs.connectSolids": "连接到固体方块上",
|
||||
"betterfoliage.roundLogs.connectSolids.tooltip": "要使圆木连接到完整的固体方块上吗?",
|
||||
"betterfoliage.roundLogs.connectPerpendicular": "连接到垂直的圆木上",
|
||||
"betterfoliage.roundLogs.connectPerpendicular.tooltip": "要使圆木根据它的角度连接到垂直圆木上吗?",
|
||||
"betterfoliage.roundLogs.lenientConnect": "巨大的圆木",
|
||||
"betterfoliage.roundLogs.lenientConnect.tooltip": "在L形中也连接成巨大的圆木, 不只是2x2形",
|
||||
"betterfoliage.roundLogs.connectGrass": "连接到草方块上",
|
||||
"betterfoliage.roundLogs.connectGrass.tooltip": "如果树木下的泥土附近有草方块,那么它也会被渲染成草方块",
|
||||
"betterfoliage.roundLogs.radiusSmall": "圆木斜面的半径",
|
||||
"betterfoliage.roundLogs.radiusSmall.tooltip": "从圆木的外角砍掉多大的部分",
|
||||
"betterfoliage.roundLogs.radiusLarge": "连接圆木的斜面半径",
|
||||
"betterfoliage.roundLogs.radiusLarge.tooltip": "从连接着的巨大圆木的外角砍掉多大的部分",
|
||||
"betterfoliage.roundLogs.dimming": "调光变暗",
|
||||
"betterfoliage.roundLogs.dimming.tooltip": "将圆木阴暗面变黑的程度",
|
||||
"betterfoliage.roundLogs.zProtection": "Z-Protection [Z保护]",
|
||||
"betterfoliage.roundLogs.zProtection.tooltip": "用多少倍放大平行圆木连接处的面 去停止 Z-fighting (闪烁)[斑驳,两个多边形共面所出现的效果].在没有发生故障的情况下,试着将这个值设置得尽可能的高[这是Z-fighting出现的原因:多个多面体的面重叠在一起,会一直闪烁]",
|
||||
"betterfoliage.roundLogs.defaultY": "默认垂直",
|
||||
"betterfoliage.roundLogs.defaultY.tooltip": "如果开启, 方向不确定的圆木将会渲染成垂直的.否则, 它们仅仅渲染为cube型方块."
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
// Vanilla
|
||||
net.minecraft.block.LogBlock
|
||||
net.minecraft.block.RotatedPillarBlock
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Vanilla
|
||||
block/column_side,side,end
|
||||
block/cube_column,side,end
|
||||
block/cube_column_horizontal,side,end
|
||||
block/cube_all,all,all
|
||||
|
||||
Reference in New Issue
Block a user