29 Commits

Author SHA1 Message Date
bee3c97270 Merge remote-tracking branch 'origin/HEAD' into TopchetoEU/reprogramming-shaders 2023-03-27 10:14:44 +03:00
triphora
3666b36d09 Fix Modrinth download badge (#20)
v1 of Modrinth's API has been deprecated since January 2022 and is scheduled to begin breaking in February, with a complete breakage being done by March. This pull request has been created as a courtesy to update it to use the dedicated shields.io badge rather than manually constructing the API request.

After merging this PR, please also update any usages on other pages, for example a CurseForge and/or Modrinth project description, and also cherry-pick/copy these changes to any other branches you might have.
2023-03-13 08:56:38 +02:00
00a25c3681 chore: recode animations and eases 2023-01-18 16:08:02 +02:00
54c77dced0 Topcheto eu/sodium compatibility issue (#19)
* chore: clean up codebase, note sodium incompatibility

* fix: some rendering issues due to refactoring
2023-01-15 21:34:48 +02:00
D1p4k
b9357832fb Now works. (#18)
fix: dependency issues
2023-01-15 12:27:11 +02:00
5e95b1547e Merge pull request #17 from RaptaG/patch-1
Upgrade `yarn_mappings` to `1.19.2+build.20`
2022-10-11 01:15:27 +03:00
RaptaG
0deff2fb69 Upgrade yarn_mappings to 1.19.2+build.20 2022-10-10 20:34:02 +03:00
b876173ae2 chore: update gradlew 2022-10-10 19:16:30 +03:00
c565f74e47 fix: enable fog 2022-10-10 19:16:23 +03:00
658915ddb9 Merge pull request #14 from RaptaG/edits
Some patches
2022-09-22 15:25:42 +03:00
RaptaG
d49e797f0e Small changes 2022-09-22 13:58:09 +03:00
6e30715e60 Update README.md 2022-09-22 12:38:06 +03:00
cef53fd3a1 Merge pull request #13 from TopchetoEU/TopchetoEU/Duration-config
chore: Increase version
2022-09-22 12:34:48 +03:00
18097684ba chore: Increase version 2022-09-22 12:32:30 +03:00
dcdc583e18 Merge pull request #12 from TopchetoEU/TopchetoEU/Duration-config
Add duration config
2022-09-22 12:30:39 +03:00
23d289f9f7 chore: Save and load duration from config file 2022-09-22 12:30:02 +03:00
a3d7f9463b chore: Finish duration input and add it to config gui 2022-09-22 12:11:02 +03:00
766a9740d6 feat: Add basic input element 2022-09-22 10:56:17 +03:00
2507e806f3 chore: Change default ease to sine 2022-09-22 10:55:57 +03:00
976e91c837 fix: Offests in GUI now work correctly 2022-09-22 10:55:35 +03:00
7197e75cb4 chore: Add curseforge and modrinth links to README 2022-09-21 23:01:56 +03:00
9266a89dc3 Merge pull request #11 from TopchetoEU/TopchetoEU/1.19.2-testing
fix: Add "breaks" dependencies
2022-09-21 20:50:37 +03:00
b3c608b0eb fix: Add "breaks" dependencies 2022-09-21 20:49:54 +03:00
17efcd379f Merge pull request #10 from TopchetoEU/TopchetoEU/1.19.2-testing
fix: Wrong minecraft, bro
2022-09-21 20:46:17 +03:00
c25bb19cf9 fix: Wrong minecraft, bro 2022-09-21 20:45:05 +03:00
842ed01212 Merge pull request #9 from TopchetoEU/TopchetoEU/1.19.2-testing
fix: Change required versions to be less restrictive
2022-09-21 20:40:45 +03:00
2c2a902280 fix: Change required versions to be less restrictive 2022-09-21 20:39:38 +03:00
33419b9ebc Merge pull request #8 from TopchetoEU/TopchetoEU/1.19.2-testing
Resolves #3
2022-09-21 20:06:06 +03:00
972af6719d chore: Fix all mapping issues 2022-09-21 20:04:37 +03:00
33 changed files with 867 additions and 565 deletions

3
.gitignore vendored
View File

@@ -13,4 +13,5 @@
!gradlew.bat
!LICENSE
!readme.md
!settings.gradle
!settings.gradle
!run/

View File

@@ -1,19 +1,24 @@
<div align="center">
<img src="src/main/resources/assets/smooth-chunks/icon.png" width="100">
<img src="src/main/resources/assets/animated-chunks/icon.png" width="100">
# Smooth Chunks
# Animated Chunks
[![Mod Loader](https://img.shields.io/badge/Mod%20Loader-Fabric-lightyellow?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE4LTEyLTE2VDE2OjU0OjE3LTA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0wNy0yOFQyMToxNzo0OC0wNzowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0wNy0yOFQyMToxNzo0OC0wNzowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowZWRiMWMyYy1mZjhjLWU0NDEtOTMxZi00OTVkNGYxNGM3NjAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MGVkYjFjMmMtZmY4Yy1lNDQxLTkzMWYtNDk1ZDRmMTRjNzYwIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MGVkYjFjMmMtZmY4Yy1lNDQxLTkzMWYtNDk1ZDRmMTRjNzYwIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowZWRiMWMyYy1mZjhjLWU0NDEtOTMxZi00OTVkNGYxNGM3NjAiIHN0RXZ0OndoZW49IjIwMTgtMTItMTZUMTY6NTQ6MTctMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChXaW5kb3dzKSIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4/HiGMAAAAtUlEQVRYw+XXrQqAMBQF4D2P2eBL+QIG8RnEJFaNBjEum+0+zMQLtwwv+wV3ZzhhMDgfJ0wUSinxZUQWgKos1JP/AbD4OneIDyQPwCFniA+EJ4CaXm4TxAXCC0BNHgLhAdAnx9hC8PwGSRtAFVMQjF7cNTWED8B1cgwW20yfJgAvrssAsZ1cB3g/xckAxr6FmCDU5N6f488BrpCQ4rQBJkiMYh4ACmLzwOQF0CExinkCsvw7vgGikl+OotaKRwAAAABJRU5ErkJggg==)](https://fabricmc.net)
![Enviroment](https://img.shields.io/badge/Enviroment-Client-purple)
[![Modrinth](https://img.shields.io/modrinth/dt/animated-chunks?color=00AF5C&label=downloads&logo=modrinth)](https://modrinth.com/mod/animated-chunks)
[![CurseForge](https://cf.way2muchnoise.eu/full_678609_downloads.svg)](https://curseforge.com/minecraft/mc-mods/animated-chunks)
An enhanecd fork of [cadenkriese's mod](https://github.com/cadenkriese/smooth-chunks) for the latest versions of the game, with a completely different code base.
</div>
**NOTE: This mod WILL NOT support Sodium, since Sodium doesn't render separate chunks, but whole regions, hence separate chunk animations are rendered impossible. Anyone interested in making sodium compatibility, be my guest**
## What is this?
Smooth Chunks is a Fabric mod that adds animations of currently loading chunks. This makes chunk loading generally seem much more pleasant than them appearing out of thin air. There are multiple built-in animations and ease types, and if this isnt't enough, there's an API which will allow you to add your own animations and eases (with ease :trollface:)
Animated Chunks is a Fabric mod that adds animations of currently loading chunks. This makes chunk loading generally seem much more pleasant than them appearing out of thin air. There are multiple built-in animations and ease types, and if this isnt't enough, there's an API which will allow you to add your own animations and eases<br/>(with ease :trollface:)
Generally, this is what you'd call an "eye-candy" mod.

View File

@@ -14,6 +14,10 @@ repositories {
maven {
url "https://maven.terraformersmc.com/releases"
}
// maven {
// url "https://jitpack.io/"
// }
mavenLocal()
}
dependencies {
@@ -50,6 +54,7 @@ dependencies {
// include("me.sargunvohra.mcmods:autoconfig1u:${project.autoconfig_version}")
modImplementation("com.terraformersmc:modmenu:${project.modmenu_version}")
// modImplementation("com.github.CaffeineMC:sodium-fabric:${project.sodium_version}")
}

View File

@@ -3,18 +3,16 @@
org.gradle.jvmargs=-Xmx4G
# Fabric Properties
minecraft_version=1.18.2
yarn_mappings=1.18.2+build.1
loader_version=0.13.3
minecraft_version=1.19.2
yarn_mappings=1.19.2+build.28
loader_version=0.14.12
# Mod Properties
mod_version=0.2.0
mod_version=0.3.0
maven_group=me.topchetoeu
archives_base_name=animated-chunks
# Dependencies
fabric_version=0.47.8+1.18.2
autoconfig_version=3.3.1
cloth_version=3.2.24
modmenu_version=3.2.1
fabric_version=0.72.0+1.19.2
modmenu_version=4.1.2
# sodium_version=mc1.19.2-0.4.3

Binary file not shown.

View File

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

269
gradlew vendored
View File

@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,67 +17,101 @@
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
@@ -106,80 +140,95 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

View File

@@ -5,11 +5,10 @@ import java.io.File;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import me.topchetoeu.animatedchunks.Manager.RegisterEvent;
import me.topchetoeu.animatedchunks.animation.Animation;
import me.topchetoeu.animatedchunks.animation.FallAnimation;
import me.topchetoeu.animatedchunks.animation.FlyInAnimation;
import me.topchetoeu.animatedchunks.animation.ProgressManager;
import me.topchetoeu.animatedchunks.animation.Animator;
import me.topchetoeu.animatedchunks.animation.RiseAnimation;
import me.topchetoeu.animatedchunks.animation.ScaleAnimation;
import me.topchetoeu.animatedchunks.easing.Ease;
@@ -20,54 +19,27 @@ import me.topchetoeu.animatedchunks.easing.SineEase;
import me.topchetoeu.animatedchunks.gui.AnimatedChunksScreen;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientChunkEvents;
import net.fabricmc.fabric.api.event.Event;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.math.BlockPos;
public final class AnimatedChunks implements ClientModInitializer, ModMenuApi {
private static AnimatedChunks instance;
/**
* Gets the currently running instance of this mod
*/
public static AnimatedChunks getInstance() {
return instance;
}
/**
* An event, fired once, when eases are being registered
* The animator used by the mod. Used to manage animation progress and animate chunks
*/
public final Event<RegisterEvent<Ease>> EASES_REGISTERING = Manager.createEvent();
public final Animator animator;
/**
* An event, fired once, when animations are being registered
* The config manager used by the mod. Used to save/load config from disk
*/
public final Event<RegisterEvent<Animation>> ANIMATIONS_REGISTERING = Manager.createEvent();
public final ConfigManager config;
private ProgressManager progress;
private ConfigManager config;
private Manager<Ease> ease;
private Manager<Animation> animation;
/**
* Gets the config manager
*/
public ConfigManager getConfigManager() {
return config;
}
/**
* Gets the chunk progress manager
*/
public ProgressManager getProgressManager() {
return progress;
}
/**
* Gets the animation manager
*/
public Manager<Animation> getAnimationManager() {
return animation;
}
/**
* Gets the ease manager
*/
public Manager<Ease> getEaseManager() {
return ease;
}
private static void registerEases(Manager<Ease> manager) {
manager.register(new Descriptor<>(new LinearEase(), "linear")
@@ -91,7 +63,7 @@ public final class AnimatedChunks implements ClientModInitializer, ModMenuApi {
.description("Animation takes off very quickly, overshoots, then undershoots, until it reaches the end.")
);
manager.set("elastic");
manager.set("sine");
}
private static void registerAnimations(Manager<Animation> manager) {
manager.register(new Descriptor<>(new RiseAnimation(), "rise")
@@ -121,34 +93,35 @@ public final class AnimatedChunks implements ClientModInitializer, ModMenuApi {
@Override public void onInitializeClient() {
instance = this;
progress = new ProgressManager();
ease = new Manager<>(x -> 1);
ease.get()
.description("Ends the animation as soon as it has started.")
.displayName("No animation");
animation = new Manager<>((a, b, c, d, e, f, g, h) -> {});
animation.get()
.description("Does nothing.")
.displayName("No animation");
registerEases(ease);
registerAnimations(animation);
config = new ConfigManager(new File("config/animated-chunks.dat"), animation, ease);
EASES_REGISTERING.invoker().register(ease);
ANIMATIONS_REGISTERING.invoker().register(animation);
ClientChunkEvents.CHUNK_UNLOAD.register((world, chunk) -> {
BlockPos pos = chunk.getPos().getStartPos();
progress.unload(pos.getX(), pos.getY(), pos.getZ());
animator.unload(pos.getX(), pos.getY(), pos.getZ());
});
}
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return (Screen parent) -> {
var _this = getInstance();
return new AnimatedChunksScreen(parent, _this.animation, _this.ease, _this.config);
return new AnimatedChunksScreen(parent, _this.config, _this.animator);
};
}
public AnimatedChunks() {
var eases = new Manager<>(new Descriptor<Ease>(() -> "t = 1;", "default")
.author("TopchetoEU")
.description("Ends the animation as soon as it has started.")
.displayName("No animation")
);
var animations = new Manager<>(new Descriptor<Animation>(() -> ";", "default")
.author("TopchetoEU")
.description("Does nothing.")
.displayName("No animation")
);
registerEases(eases);
registerAnimations(animations);
animator = new Animator(animations, eases);
config = new ConfigManager(new File("config/animated-chunks.dat"), animator);
}
}

View File

@@ -1,22 +1,21 @@
package me.topchetoeu.animatedchunks;
import java.io.EOFException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import me.topchetoeu.animatedchunks.animation.Animation;
import me.topchetoeu.animatedchunks.easing.Ease;
import me.topchetoeu.animatedchunks.animation.Animator;
public class ConfigManager {
public final File configFile;
private final Manager<Animation> animation;
private final Manager<Ease> ease;
private final Animator animator;
private String readString(InputStreamReader reader) throws IOException {
private String readString(InputStream reader) throws IOException {
String res = "";
int i;
@@ -27,36 +26,46 @@ public class ConfigManager {
return res;
}
private void writeString(OutputStreamWriter writer, String str) throws IOException {
private void writeString(OutputStream writer, String str) throws IOException {
for (int i = 0; i < str.length(); i++) {
writer.write((char)str.charAt(i));
writer.write((byte)str.charAt(i));
}
writer.write((byte)0);
}
private float readFloat(InputStream reader) throws IOException {
try {
var bytes = reader.readNBytes(4);
return ByteBuffer.wrap(bytes).getFloat();
}
catch (IndexOutOfBoundsException e) {
throw new EOFException();
}
writer.write(0);
}
public void reload() {
try {
var reader = new FileReader(configFile);
var reader = new FileInputStream(configFile);
String animation = readString(reader);
String ease = readString(reader);
float duration = readFloat(reader);
reader.close();
this.animation.set(animation);
this.ease.set(ease);
}
catch (FileNotFoundException e) {
save();
this.animator.ANIMATIONS.set(animation);
this.animator.EASES.set(ease);
this.animator.setDuration(duration);
}
catch (IOException e) {
throw new RuntimeException(e);
save();
}
}
public void save() {
try {
var writer = new FileWriter(configFile);
writeString(writer, animation.get().getName());
writeString(writer, ease.get().getName());
var writer = new FileOutputStream(configFile);
writeString(writer, this.animator.ANIMATIONS.get().getName());
writeString(writer, this.animator.EASES.get().getName());
writer.write(ByteBuffer.allocate(4).putFloat(animator.getDuration()).array());
writer.close();
}
catch (IOException e) {
@@ -64,10 +73,9 @@ public class ConfigManager {
}
}
public ConfigManager(File configFile, Manager<Animation> animation, Manager<Ease> ease) {
public ConfigManager(File configFile, Animator animator) {
this.configFile = configFile;
this.animation = animation;
this.ease = ease;
this.animator = animator;
reload();
}

View File

@@ -7,21 +7,7 @@ import java.util.Map;
import org.apache.commons.lang3.Validate;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
public final class Manager<T> {
public static interface RegisterEvent<T> {
public void register(Manager<T> manager);
}
public static final <T> Event<RegisterEvent<T>> createEvent() {
return EventFactory.createArrayBacked(RegisterEvent.class, (listeners) -> (manager) -> {
for (RegisterEvent<T> listener: listeners) {
listener.register(manager);
}
});
}
private String currName = null;
private Map<String, Descriptor<T>> objects = new Hashtable<>();
@@ -75,8 +61,8 @@ public final class Manager<T> {
return Collections.unmodifiableCollection(objects.values());
}
public Manager(T _default) {
register(new Descriptor<>(_default, "default").displayName("Default").author("TopchetoEU"));
public Manager(Descriptor<T> _default) {
register(_default);
set("default");
}
}

View File

@@ -0,0 +1,26 @@
package me.topchetoeu.animatedchunks;
import java.util.Map;
public interface StatementFactory {
/**
* Returns a GLSL statement, with access to at least the following variables:
* <ul>
* <li>playerPos - vec3, the position of the player</li>
* <li>chunkPos - vec3, the position of the current chunk</li>
* <li>pos - vec3, the position of the current vertex</li>
* <li>x - the raw stage of the animation, from 0 to 1</li>
* <li>t - the eased stage of the animation, from 0 to 1</li>
* <li>tmp0 - tmp7 - temporary float variables</li>
* <li>tmp8 - tmp11 - temporary vec3 variables</li>
* <li>tmp12 - tmp15 - temporary vec4 variables</li>
* </ul>
*/
String statement();
/**
* Returns all uniforms that are used by the statement
*/
public default Map<String, Float> uniforms() {
return Map.of();
}
}

View File

@@ -1,18 +1,5 @@
package me.topchetoeu.animatedchunks.animation;
import net.minecraft.client.util.math.MatrixStack;
import me.topchetoeu.animatedchunks.StatementFactory;
public interface Animation {
/**
* Animations using the currently set ease
* @param progress The point at which the animation currently is (a value between 0 and 1)
* @param matrices The matrix stack used for rendering
* @param chunkX The current chunk's x (in blocks) which is animated
* @param chunkY The current chunk's y (in blocks) which is animated
* @param chunkZ The current chunk's z (in blocks) which is animated
* @param playerX The player's x (in blocks)
* @param playerY The player's y (in blocks)
* @param playerZ The player's z (in blocks)
*/
void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ);
}
public interface Animation extends StatementFactory { }

View File

@@ -1,146 +1,152 @@
package me.topchetoeu.animatedchunks.animation;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
public final class ProgressManager {
public static class ChunkLoc {
public final int x;
public final int y;
public final int z;
@Override
public boolean equals(Object obj) {
return obj instanceof ChunkLoc && ((ChunkLoc)obj).x == x && ((ChunkLoc)obj).y == y && ((ChunkLoc)obj).z == z;
}
@Override
public int hashCode() {
return 137 * x + 149 * y + 163 * z;
}
public ChunkLoc(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
}
private Hashtable<ChunkLoc, Float> chunkToStage = new Hashtable<>();
private HashSet<ChunkLoc> chunks = new HashSet<>();
private float duration = 1;
public ProgressManager() {
}
public float getDuration() {
return duration;
}
public void setDuration(float duration) {
this.duration = duration;
}
/**
* Removes all loaded chunks (called when a world is unloaded and loaded)
*/
public void reset() {
chunkToStage.clear();
chunks.clear();
}
/**
* Advances the animation for all tracked chunks, according to the duration and the specified delta
* @param delta The second delta to advance the animation by
*/
public void tick(float delta) {
for (ChunkLoc loc : new ArrayList<>(chunkToStage.keySet())) {
float val = chunkToStage.get(loc);
val += delta / duration;
if (val > 1f) chunkToStage.remove(loc);
chunkToStage.put(loc, val);
}
}
/**
* Loads a specified chunk (starts tracking its animation)
* @param x The x of the chunk
* @param y The y of the chunk
* @param y The z of the chunk
*/
public void load(int x, int y, int z) {
if (isChunkLoaded(x, y, z)) return;
ChunkLoc loc = new ChunkLoc(x, y, z);
chunks.add(loc);
chunkToStage.put(loc, 0f);
}
/**
* Unloads a specified chunk (stops tracking its animation)
* @param x The x of the chunk
* @param y The y of the chunk
* @param y The z of the chunk
*/
public void unload(int x, int y, int z) {
ChunkLoc loc = new ChunkLoc(x, y, z);
chunkToStage.remove(loc);
chunks.remove(loc);
}
/**
* Unloads all loaded chunks
*/
public void unloadAll() {
chunkToStage.clear();
chunks.clear();
}
/**
* Unloads all the chunks that are outside the render distance specified
* @param viewDistance The view distance (in chunks, radius)
* @param playerChunkX The x coordinate of the chunk in which the player stands
* @param playerChunkY The y coordinate of the chunk in which the player stands
* @param playerChunkZ The z coordinate of the chunk in which the player stands
*/
public void unloadAllFar(int viewDistance, int playerChunkX, int playerChunkY, int playerChunkZ) {
float circleVD = viewDistance + 1.38f;
int squareVD = viewDistance;
for (ChunkLoc loc : new ArrayList<>(chunks)) {
int chunkX = loc.x / 16;
int chunkZ = loc.z / 16;
int diffSquareX = playerChunkX - chunkX ;
int diffSquareZ = playerChunkZ - chunkZ;
int diffCircleX = playerChunkX - chunkX;
int diffCircleZ = playerChunkZ - chunkZ;
int dist = diffCircleX * diffCircleX + diffCircleZ * diffCircleZ;
if (dist > circleVD * circleVD) unload(loc.x, loc.y, loc.z);
if (Math.abs(diffSquareX) > squareVD || Math.abs(diffSquareZ) > squareVD) unload(loc.x, loc.y, loc.z);
}
}
/**
* Checks whether or not a chunk is loaded
* @param x The x of the chunk
* @param y The y of the chunk
* @param y The z of the chunk
* @return A value indicating whether or not the specified chunk is tracked
*/
public boolean isChunkLoaded(int x, int y, int z) {
return chunks.contains(new ChunkLoc(x, y, z));
}
/**
* Gets the animation progress of the specified chunk
* @param x The x of the chunk
* @param y The y of the chunk
* @param y The z of the chunk
* @return A float value from 0 to 1 (0 if the chunk is not tracked), indicating the animation progress of the specified chunk
*/
public float getChunkProgress(int x, int y, int z) {
if (!isChunkLoaded(x, y, z)) return 0f;
if (!chunkToStage.containsKey(new ChunkLoc(x, y, z))) return 1f;
return chunkToStage.get(new ChunkLoc(x, y, z));
}
}
package me.topchetoeu.animatedchunks.animation;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import me.topchetoeu.animatedchunks.Manager;
import me.topchetoeu.animatedchunks.easing.Ease;
public final class Animator {
public static class ChunkLoc {
public final int x;
public final int y;
public final int z;
@Override
public boolean equals(Object obj) {
return obj instanceof ChunkLoc && ((ChunkLoc)obj).x == x && ((ChunkLoc)obj).y == y && ((ChunkLoc)obj).z == z;
}
@Override
public int hashCode() {
return 137 * x + 149 * y + 163 * z;
}
public ChunkLoc(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
}
public final Manager<Animation> ANIMATIONS;
public final Manager<Ease> EASES;
private Hashtable<ChunkLoc, Float> chunkToStage = new Hashtable<>();
private HashSet<ChunkLoc> chunks = new HashSet<>();
private float duration = 1;
public Animator(Manager<Animation> animations, Manager<Ease> eases) {
ANIMATIONS = animations;
EASES = eases;
}
public float getDuration() {
return duration;
}
public void setDuration(float duration) {
this.duration = duration;
}
/**
* Removes all loaded chunks (called when a world is unloaded and loaded)
*/
public void reset() {
chunkToStage.clear();
chunks.clear();
}
/**
* Advances the animation for all tracked chunks, according to the duration and the specified delta
* @param delta The second delta to advance the animation by
*/
public void tick(float delta) {
for (ChunkLoc loc : new ArrayList<>(chunkToStage.keySet())) {
float val = chunkToStage.get(loc);
val += delta / duration;
if (val > 1f) chunkToStage.remove(loc);
chunkToStage.put(loc, val);
}
}
/**
* Loads a specified chunk (starts tracking its animation)
* @param x The x of the chunk
* @param y The y of the chunk
* @param y The z of the chunk
*/
public void load(int x, int y, int z) {
if (isChunkLoaded(x, y, z)) return;
ChunkLoc loc = new ChunkLoc(x, y, z);
chunks.add(loc);
chunkToStage.put(loc, 0f);
}
/**
* Unloads a specified chunk (stops tracking its animation)
* @param x The x of the chunk
* @param y The y of the chunk
* @param y The z of the chunk
*/
public void unload(int x, int y, int z) {
ChunkLoc loc = new ChunkLoc(x, y, z);
chunkToStage.remove(loc);
chunks.remove(loc);
}
/**
* Unloads all loaded chunks
*/
public void unloadAll() {
chunkToStage.clear();
chunks.clear();
}
/**
* Unloads all the chunks that are outside the render distance specified
* @param viewDistance The view distance (in chunks, radius)
* @param playerChunkX The x coordinate of the chunk in which the player stands
* @param playerChunkY The y coordinate of the chunk in which the player stands
* @param playerChunkZ The z coordinate of the chunk in which the player stands
*/
public void unloadAllFar(int viewDistance, int playerChunkX, int playerChunkY, int playerChunkZ) {
float circleVD = viewDistance + 1.38f;
int squareVD = viewDistance;
for (ChunkLoc loc : new ArrayList<>(chunks)) {
int chunkX = loc.x / 16;
int chunkZ = loc.z / 16;
int diffSquareX = playerChunkX - chunkX ;
int diffSquareZ = playerChunkZ - chunkZ;
int diffCircleX = playerChunkX - chunkX;
int diffCircleZ = playerChunkZ - chunkZ;
int dist = diffCircleX * diffCircleX + diffCircleZ * diffCircleZ;
if (dist > circleVD * circleVD) unload(loc.x, loc.y, loc.z);
if (Math.abs(diffSquareX) > squareVD || Math.abs(diffSquareZ) > squareVD) unload(loc.x, loc.y, loc.z);
}
}
/**
* Checks whether or not a chunk is loaded
* @param x The x of the chunk
* @param y The y of the chunk
* @param y The z of the chunk
* @return A value indicating whether or not the specified chunk is tracked
*/
public boolean isChunkLoaded(int x, int y, int z) {
return chunks.contains(new ChunkLoc(x, y, z));
}
/**
* Gets the animation progress of the specified chunk
* @param x The x of the chunk
* @param y The y of the chunk
* @param y The z of the chunk
* @return A float value from 0 to 1 (0 if the chunk is not tracked), indicating the animation progress of the specified chunk
*/
public float getChunkProgress(int x, int y, int z) {
if (!isChunkLoaded(x, y, z)) return 0f;
if (!chunkToStage.containsKey(new ChunkLoc(x, y, z))) return 1f;
return chunkToStage.get(new ChunkLoc(x, y, z));
}
}

View File

@@ -1,6 +1,6 @@
package me.topchetoeu.animatedchunks.animation;
import net.minecraft.client.util.math.MatrixStack;
import java.util.Map;
public class FallAnimation implements Animation {
private float offset;
@@ -12,12 +12,11 @@ public class FallAnimation implements Animation {
this.offset = offset;
}
@Override
public void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ) {
animate(progress, matrices);
public Map<String, Float> uniforms() {
return Map.of("animation_f", offset);
}
public void animate(float progress, MatrixStack matrices) {
matrices.translate(0, offset * (1 - progress), 0);
public String statement() {
return "pos += vec3(0, animation_f * (1 - t));";
}
public FallAnimation(float offset) {

View File

@@ -1,7 +1,6 @@
package me.topchetoeu.animatedchunks.animation;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Vec2f;
import java.util.Map;
public class FlyInAnimation implements Animation {
private float offset;
@@ -13,13 +12,21 @@ public class FlyInAnimation implements Animation {
this.offset = offset;
}
@Override
public void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ) {
Vec2f direction = new Vec2f(playerX, playerZ).add(new Vec2f(-chunkX, -chunkZ)).normalize().multiply(-offset);
matrices.translate(direction.x * (1 - progress), 0, direction.y * (1 - progress));
public Map<String, Float> uniforms() {
return Map.of("animation_f", offset);
}
@Override
public String statement() {
return "tmp8 = normalize(chunkPos.xz - playerPos.xz) * animation_f; tmp8 *= (1 - t); pos += tmp8;";
}
// @Override
// public void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ) {
// Vec2f direction = new Vec2f(playerX, playerZ).add(new Vec2f(-chunkX, -chunkZ)).normalize().multiply(-offset);
// matrices.translate(direction.x * (1 - progress), 0, direction.y * (1 - progress));
// }
public FlyInAnimation() {
offset = 50;

View File

@@ -1,6 +1,6 @@
package me.topchetoeu.animatedchunks.animation;
import net.minecraft.client.util.math.MatrixStack;
import java.util.Map;
public final class RiseAnimation implements Animation {
private float offset;
@@ -12,12 +12,11 @@ public final class RiseAnimation implements Animation {
this.offset = offset;
}
@Override
public void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ) {
animate(progress, matrices);
public Map<String, Float> uniforms() {
return Map.of("animation_f", offset);
}
public void animate(float progress, MatrixStack matrices) {
matrices.translate(0, offset * (progress - 1), 0);
public String statement() {
return "pos += vec3(0, animation_f * (t - 1));";
}
public RiseAnimation(float offset) {

View File

@@ -1,10 +1,11 @@
package me.topchetoeu.animatedchunks.animation;
import net.minecraft.client.util.math.MatrixStack;
import java.util.Map;
public class ScaleAnimation implements Animation {
public static float xOffset = 8, yOffset = 8, zOffset = 8;
private boolean scaleY = true;
private float xOffset = 8, yOffset = 8, zOffset = 8;
public boolean isScalingY() {
return scaleY;
@@ -13,38 +14,31 @@ public class ScaleAnimation implements Animation {
this.scaleY = scaleY;
}
public float getXOffset() {
return xOffset;
}
public void setXOffset(float xOffset) {
this.xOffset = xOffset;
}
public float getYOffset() {
return yOffset;
}
public void setYOffset(float yOffset) {
this.yOffset = yOffset;
}
public float getZOffset() {
return zOffset;
}
public void setZOffset(float zOffset) {
this.zOffset = zOffset;
@Override
public Map<String, Float> uniforms() {
return Map.of("animation_ox", xOffset, "animation_oy", yOffset, "animation_oz", zOffset, "animation_sy", scaleY ? 1f : 0f);
}
@Override
public void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ) {
float scaleX = progress;
float scaleZ = progress;
matrices.translate(xOffset, yOffset, zOffset);
matrices.scale(scaleX, 1, scaleZ);
matrices.translate(-xOffset, -yOffset, -zOffset);
public String statement() {
return
"tmp8 = vec3(animation_ox, animation_oy, animation_oz);" +
"tmp9 = vec3(t);" +
"if (animation_sy < .5f) tmp9.y = 0;" +
"pos += tmp8;" +
"pos *= tmp9;" +
"pos -= tmp8;";
}
public ScaleAnimation() {
// @Override
// public void animate(float progress, MatrixStack matrices, int chunkX, int chunkY, int chunkZ, float playerX, float playerY, float playerZ) {
// float scaleX = progress;
// float scaleZ = progress;
}
// matrices.translate(xOffset, yOffset, zOffset);
// matrices.scale(scaleX, 1, scaleZ);
// matrices.translate(-xOffset, -yOffset, -zOffset);
// }
public ScaleAnimation() { }
}

View File

@@ -1,34 +1,30 @@
package me.topchetoeu.animatedchunks.easing;
public interface Ease {
/**
* Converts the linear progress of an animation to an eased progress
* @param x The progress of the animation being eased
* @return The new, eased progress
*/
float ease(float x);
import me.topchetoeu.animatedchunks.StatementFactory;
public interface Ease extends StatementFactory {
/**
* Converts a function to an ease out version of itself.
* Converts a ease-in statement to an ease-out statement
* Mathematically, the function is being "rotated" 180 degrees
* @param func The function to convert
* @return The ease out version of the function
* @param func The ease statement to convert
*/
public static Ease easeOut(Ease func) {
return x -> 1 - func.ease(1 - x);
return () -> "x = 1 - x; " + func.statement() + "x = 1 - x; t = 1 - t;";
// return x -> 1 - func.ease(1 - x);
}
/**
* Converts a function to an ease in-out version of itself.
* Mathematically, the function is being split into two, where in the interval [0; 0.5], the ease-out function is being used, and in the other interval [0.5; 1], the ease-in function is being used
* @param func The function to convert
* @return The ease in-out version of the function
* Converts a ease statement to an ease in-out statement
* Mathematically, the function is being split into two, where in the interval [0; 0.5), the ease-in function is being used, and in the other interval [0.5; 1], the ease-out function is being used
* @param func The ease statement to convert
* @return The ease in-out statement
*/
public static Ease easeInOut(Ease func) {
return x -> {
float x2 = 2 * x;
return () -> "x *= 2; if (x < 1f) { " + easeOut(func) + "} else { x -= 1; " + func.statement() + " } x /= 2;";
// return x -> {
// float x2 = 2 * x;
if (x < 0.5f) return (1 - func.ease(1 - x2)) / 2;
else return (1 + func.ease(x2 - 1)) / 2;
};
// if (x < 0.5f) return (1 - func.ease(1 - x2)) / 2;
// else return (1 + func.ease(x2 - 1)) / 2;
// };
}
}

View File

@@ -1,5 +1,7 @@
package me.topchetoeu.animatedchunks.easing;
import java.util.Map;
public class ElasticEase implements Ease {
private float steepness = 1;
private int periods = 3;
@@ -19,11 +21,21 @@ public class ElasticEase implements Ease {
}
@Override
public float ease(float x) {
float amplitude = (float)Math.pow(2, -steepness * x) * (1 - x);
float wave = (float)Math.sin(2 * Math.PI * periods * x - Math.PI / 2);
public Map<String, Float> uniforms() {
return Map.of("ease_s", steepness, "ease_p", (float)periods);
}
return amplitude * wave + 1;
@Override
public String statement() {
return
"tmp0 = pow(2, -ease_s * x) * (1 - x);" +
"tmp1 = sin(6.28 * ease_p * x - 1.57);" +
"t = tmp0 * tmp1 + 1;";
// float amplitude = (float)Math.pow(2, -steepness * x) * (1 - x);
// float wave = (float)Math.sin(2 * Math.PI * periods * x - Math.PI / 2);
// return amplitude * wave + 1;
}
}

View File

@@ -1,7 +1,7 @@
package me.topchetoeu.animatedchunks.easing;
public class LinearEase implements Ease {
public float ease(float x) {
return x;
public String statement() {
return "t = x;";
}
}

View File

@@ -1,8 +1,7 @@
package me.topchetoeu.animatedchunks.easing;
public class QuadraticEase implements Ease {
@Override
public float ease(float x) {
return x * x;
public String statement() {
return "t = x * x;";
}
}

View File

@@ -1,8 +1,7 @@
package me.topchetoeu.animatedchunks.easing;
public class SineEase implements Ease {
@Override
public float ease(float x) {
return (float)Math.sin(x * Math.PI / 2);
public String statement() {
return "t = sin(x * 1.57);";
}
}

View File

@@ -4,23 +4,20 @@ import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.ColorHelper.Argb;
import me.topchetoeu.animatedchunks.ConfigManager;
import me.topchetoeu.animatedchunks.Manager;
import me.topchetoeu.animatedchunks.animation.Animation;
import me.topchetoeu.animatedchunks.easing.Ease;
import me.topchetoeu.animatedchunks.animation.Animator;
import me.topchetoeu.animatedchunks.gui.Section.OrderType;
import net.minecraft.client.MinecraftClient;
public class AnimatedChunksScreen extends Screen {
public final Screen parent;
private final HorizontalSection mainSection = new HorizontalSection();
private final Manager<Animation> animation;
private final Manager<Ease> ease;
private final ConfigManager config;
private final Animator animator;
public static void playClick() {
MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0f));
@@ -47,7 +44,6 @@ public class AnimatedChunksScreen extends Screen {
mainSection.order = OrderType.Justified;
mainSection.children.addSelectableChild(selectionsSection());
mainSection.children.addSelectableChild(previewSection());
// setZOffset(parent.getZOffset() + 1);
}
@Override
@@ -65,7 +61,7 @@ public class AnimatedChunksScreen extends Screen {
res.x = res.y = 5;
res.title = Text.of("Preview:");
res.children.addSelectableChild(new ChunkPreview(0, 0, 150, 150));
res.children.addSelectableChild(new ChunkPreview(0, 0, 150, 150, animator));
return res;
}
@@ -82,34 +78,51 @@ public class AnimatedChunksScreen extends Screen {
buttonSection.order = OrderType.Justified;
buttonSection.children.addChild(new Label(
5, 7,
new LiteralText(manager.get().getDisplayName()).formatted(Formatting.BOLD)
Text.of(manager.get().getDisplayName()).copy().formatted(Formatting.BOLD)
));
buttonSection.children.addSelectableChild(new Button(5, 5, Text.of("Select ..."), () -> client.setScreen(selectScreen)));
res.children.addSelectableChild(buttonSection);
res.children.addChild(new Label(
5, 3,
new LiteralText("Author: " + manager.get().getAuthorOrDefault())
Text.of("Author: " + manager.get().getAuthorOrDefault())
).setMaxWidth(width / 2));
res.children.addChild(new Label(
5, 3,
new LiteralText(manager.get().getDescriptionOrDefault()).formatted(Formatting.ITALIC)
Text.of(manager.get().getDescriptionOrDefault()).copy().formatted(Formatting.ITALIC)
).setMaxWidth(width / 2));
return res;
}
private Section durationSection() {
var res = new HorizontalSection();
res.setTargetWidth(width / 2);
var input = new NumberInput(res, 5, 5, animator.getDuration(), (sender, val) -> {
if (val <= 0) sender.invalid = true;
else {
animator.setDuration(val);
sender.invalid = false;
}
});
input.width = (int)res.getTargetWidth();
res.x = res.y = 5;
res.title = Text.of("Duration:");
res.children.addSelectableChild(input);
return res;
}
private Section selectionsSection() {
var res = new HorizontalSection();
res.x = res.y = 5;
res.title = Text.of("Animation config:");
res.children.addSelectableChild(selectionSection(animation, "Animation"));
res.children.addSelectableChild(selectionSection(ease, "Ease"));
res.children.addSelectableChild(selectionSection(animator.ANIMATIONS, "Animation"));
res.children.addSelectableChild(selectionSection(animator.EASES, "Ease"));
res.children.addSelectableChild(durationSection());
return res;
}
public AnimatedChunksScreen(Screen parent, Manager<Animation> animation, Manager<Ease> ease, ConfigManager config) {
public AnimatedChunksScreen(Screen parent, ConfigManager config, Animator animator) {
super(Text.of("Animated Chunks Config"));
config.reload();
this.animation = animation;
this.ease = ease;
this.animator = animator;
this.config = config;
mainSection.x = mainSection.y = 5;

View File

@@ -83,7 +83,7 @@ public class Button extends DrawableHelper implements Drawable, Element, Selecta
matrices.push();
matrices.translate(this.x, this.y, getZOffset());
hovered = isMouseOver(x, y);
hovered = isMouseOver(x - this.x, y - this.y);
if (hovered) {
fill(matrices, 0, 0, (int)getWidth(), (int)getHeight(), Argb.getArgb(32, 255, 255, 255));
@@ -109,9 +109,6 @@ public class Button extends DrawableHelper implements Drawable, Element, Selecta
public boolean isMouseOver(double x, double y) {
if (clicked) return true;
x -= this.x;
y -= this.y;
return x >= 0 && x < getWidth() && y >= 0 && y < getHeight();
}
@@ -136,7 +133,7 @@ public class Button extends DrawableHelper implements Drawable, Element, Selecta
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (button != 0) return false;
if (isMouseOver(mouseX, mouseY)) {
if (isMouseOver(mouseX - this.x, mouseY - this.x)) {
clicked = true;
hovered = true;
}

View File

@@ -5,7 +5,7 @@ import org.lwjgl.opengl.GL11;
import com.mojang.blaze3d.systems.RenderSystem;
import me.topchetoeu.animatedchunks.AnimatedChunks;
import me.topchetoeu.animatedchunks.animation.Animator;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Drawable;
import net.minecraft.client.gui.DrawableHelper;
@@ -31,8 +31,10 @@ public class ChunkPreview extends DrawableHelper implements Drawable, Element, S
void onClick();
}
public ClickAction clickAction;
public final MinecraftClient client;
public final Animator animator;
public ClickAction clickAction;
private boolean clicked = false;
private boolean rotating = false;
private boolean focused = false;
@@ -89,7 +91,7 @@ public class ChunkPreview extends DrawableHelper implements Drawable, Element, S
return z < 3;
}
private static void myFill(MatrixStack matrices, float x1, float y1, float x2, float y2, float a, float r, float g, float b) {
public static void myFill(MatrixStack matrices, float x1, float y1, float x2, float y2, float a, float r, float g, float b) {
if (x1 < x2) {
float tmp = x1;
x1 = x2;
@@ -121,15 +123,13 @@ public class ChunkPreview extends DrawableHelper implements Drawable, Element, S
RenderSystem.enableBlend();
RenderSystem.disableCull();
RenderSystem.disableTexture();
RenderSystem.defaultBlendFunc();
RenderSystem.setShader(GameRenderer::getPositionColorShader);
bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
bufferBuilder.vertex(p1.getX(), p1.getY(), p1.getZ()).color(r, g, b, a).next();
bufferBuilder.vertex(p2.getX(), p2.getY(), p2.getZ()).color(r, g, b, a).next();
bufferBuilder.vertex(p3.getX(), p3.getY(), p3.getZ()).color(r, g, b, a).next();
bufferBuilder.vertex(p4.getX(), p4.getY(), p4.getZ()).color(r, g, b, a).next();
bufferBuilder.end();
BufferRenderer.draw(bufferBuilder);
BufferRenderer.drawWithShader(bufferBuilder.end());
RenderSystem.enableTexture();
RenderSystem.disableBlend();
}
@@ -160,23 +160,30 @@ public class ChunkPreview extends DrawableHelper implements Drawable, Element, S
RenderSystem.enableBlend();
}
private void renderChunk(MatrixStack matrices, int x, int y, int n, float delta) {
duration = animator.getDuration();
float progress = globalProgress / duration - (float)Math.sqrt(x * x + y * y) / (float)n / 2;
if (progress > 1) progress = 1;
if (progress <= 0) return;
matrices.push();
matrices.translate(x * 16 - 8, 0, y * 16 - 8);
// x += n;
// y += n;
float progress = globalProgress / duration - (float)Math.sqrt(x * x + y * y) / (float)n / 2;
if (progress < 0) progress = 0;
if (progress > 1) progress = 1;
if (progress < 0.999) {
float _progress = AnimatedChunks.getInstance().getEaseManager().getValue().ease(progress);
AnimatedChunks.getInstance().getAnimationManager().getValue().animate(
_progress, matrices,
x * 16, 0, y * 16, 0, 0, 0
);
// matrices.translate(0, 0, 16);
}
// animator.animate(matrices, progress, new BlockPos(x * 16, 0, y * 16));
// if (progress < 0) progress = 0;
// if (progress > 1) progress = 1;
// if (progress < 0.999) {
// float _progress = animator.EASES.getValue().ease(progress);
// AnimatedChunks.getInstance().getAnimationManager().getValue().animate(
// _progress, matrices,
// x * 16, 0, y * 16, 0, 0, 0
// );
// // matrices.translate(0, 0, 16);
// }
matrices.translate(0, 0, 16);
matrices.multiply(rotation);
myFill(matrices, 2, 1, 14, 2, progress, 1, 1, 1);
@@ -187,7 +194,6 @@ public class ChunkPreview extends DrawableHelper implements Drawable, Element, S
matrices.pop();
}
private void renderChunks(MatrixStack matrices, float delta, int n) {
duration = AnimatedChunks.getInstance().getProgressManager().getDuration();
// globalProgress += (lastTime - (lastTime = System.nanoTime())) / -1000000000f;
globalProgress += delta * 0.05f;
matrices.push();
@@ -247,9 +253,6 @@ public class ChunkPreview extends DrawableHelper implements Drawable, Element, S
public boolean isMouseOver(double x, double y) {
if (clicked) return true;
x -= this.x;
y -= this.y;
return x >= 0 && x < getWidth() && y >= 0 && y < getHeight();
}
@@ -321,16 +324,18 @@ public class ChunkPreview extends DrawableHelper implements Drawable, Element, S
return false;
}
public ChunkPreview(int x, int y) {
public ChunkPreview(int x, int y, Animator animator) {
this.client = MinecraftClient.getInstance();
this.x = x;
this.y = y;
this.animator = animator;
}
public ChunkPreview(int x, int y, int w, int h) {
public ChunkPreview(int x, int y, int w, int h, Animator animator) {
this.client = MinecraftClient.getInstance();
this.x = x;
this.y = y;
this.width = w;
this.height = h;
this.animator = animator;
}
}

View File

@@ -16,7 +16,7 @@ public final class HorizontalSection extends Section {
private float targetWidth;
public float getTargetWidth(float width) {
public float getTargetWidth() {
return this.targetWidth;
}
public void setTargetWidth(float width) {

View File

@@ -0,0 +1,207 @@
package me.topchetoeu.animatedchunks.gui;
import org.lwjgl.glfw.GLFW;
import com.mojang.blaze3d.platform.GlStateManager.DstFactor;
import com.mojang.blaze3d.platform.GlStateManager.SrcFactor;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Drawable;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.ParentElement;
import net.minecraft.client.gui.Selectable;
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
import net.minecraft.client.gui.screen.narration.NarrationPart;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.ColorHelper.Argb;
public class Input extends DrawableHelper implements Drawable, Element, Selectable, BoundboxProvider {
public interface InputAction {
void onInput(Input sender, String val);
}
public final MinecraftClient client;
private boolean clicked = false;
private boolean hovered = false;
private boolean isFocused() {
return parent.getFocused() == this;
}
private int index = 0;
private final ParentElement parent;
private String content = "";
public int paddingX = 5, paddingY = 2;
private float time = 0;
public int x, y, width = 100;
public boolean invalid = false;
public InputAction action = null;
public String getContent() {
return content;
}
public Input setContent(String val) {
if (index > val.length()) index = val.length();
content = val;
action.onInput(this, val);
return this;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public float getWidth() {
return width;
}
public float getHeight() {
return 1 + paddingY * 2 + client.textRenderer.fontHeight;
}
@Override
public void appendNarrations(NarrationMessageBuilder msgBuilder) {
msgBuilder.put(NarrationPart.HINT, "Input");
}
@Override
public SelectionType getType() {
if (isFocused()) return SelectionType.FOCUSED;
if (hovered) return SelectionType.HOVERED;
return SelectionType.NONE;
}
@Override
public boolean changeFocus(boolean lookForwards) {
if (isFocused()) {
parent.setFocused(null);
return false;
}
else {
parent.setFocused(this);
return true;
}
}
private void renderCursor(MatrixStack matrices, float delta) {
time += delta / 20;
if ((int)(time * 2) % 2 != 0) return;
// RenderSystem.enableBlend();
RenderSystem.setShader(GameRenderer::getPositionColorShader);
RenderSystem.disableCull();
RenderSystem.disableTexture();
RenderSystem.blendFuncSeparate(SrcFactor.ONE_MINUS_DST_COLOR, DstFactor.ONE_MINUS_SRC_COLOR, SrcFactor.ONE, DstFactor.ZERO);
float x1 = paddingX + client.textRenderer.getWidth(content.substring(0, index)) + 1;
float x2 = x1 + 1;
// if (index < content.length()) {
// x2 += client.textRenderer.getWidth("" + content.charAt(index)) - 2;
// }
float y1 = paddingY;
float y2 = y1 + client.textRenderer.fontHeight;
ChunkPreview.myFill(matrices, x1, y1, x2, y2, 1, 1, 1, 1);
}
@Override
public void render(MatrixStack matrices, int x, int y, float delta) {
int white = Argb.getArgb(255, 255, 255, 255);
matrices.push();
matrices.translate(this.x, this.y, getZOffset());
hovered = isMouseOver(x, y);
// if (hovered) {
// fill(matrices, 0, 0, (int)getWidth(), (int)getHeight(), Argb.getArgb(32, 255, 255, 255));
// }
if (clicked) {
fill(matrices, 0, 0, (int)getWidth(), (int)getHeight(), Argb.getArgb(127, 255, 255, 255));
}
client.textRenderer.draw(matrices, content, paddingX + 1, paddingY + 1, white);
if (isFocused()) renderCursor(matrices, delta);
if (invalid) white = 0xFFFF0000;
drawHorizontalLine(matrices, 0, (int)getWidth() - 1, 0, white);
drawVerticalLine(matrices, 0, 0, (int)getHeight() - 1, white);
drawVerticalLine(matrices, (int)getWidth() - 1, 0, (int)getHeight() - 1, white);
drawHorizontalLine(matrices, 0, (int)getWidth() - 1, (int)getHeight() - 1, white);
// if (focused) {
// }
matrices.pop();
}
@Override
public boolean isMouseOver(double x, double y) {
if (clicked) return true;
return x >= 0 && x < getWidth() && y >= 0 && y < getHeight();
}
@Override
public boolean charTyped(char chr, int modifiers) {
content = content.substring(0, index) + chr + content.substring(index);
action.onInput(this, content);
index++;
time = 0;
return true;
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (keyCode == GLFW.GLFW_KEY_BACKSPACE && index > 0) {
content = content.substring(0, index - 1) + content.substring(index);
action.onInput(this, content);
index--;
}
if (keyCode == GLFW.GLFW_KEY_DELETE && index < content.length()) {
time = 0;
content = content.substring(0, index) + content.substring(index + 1);
action.onInput(this, content);
}
if (keyCode == GLFW.GLFW_KEY_RIGHT && index < content.length()) {
index++;
}
if (keyCode == GLFW.GLFW_KEY_LEFT && index > 0) {
index--;
}
time = 0;
return false;
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (button != 0) return false;
if (isMouseOver(mouseX - this.x, mouseY - this.y)) {
clicked = true;
hovered = true;
return true;
}
return false;
// return true;
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
if (button != 0) return false;
if (clicked) {
clicked = false;
return true;
}
return false;
}
public Input(ParentElement parent, int x, int y, InputAction input) {
this.parent = parent;
this.action = input;
this.client = MinecraftClient.getInstance();
this.x = x;
this.y = y;
}
}

View File

@@ -0,0 +1,38 @@
package me.topchetoeu.animatedchunks.gui;
import net.minecraft.client.gui.ParentElement;
public class NumberInput extends Input {
public interface InputAction {
void input(NumberInput sender, float number);
}
private float value;
public InputAction action;
public float getValue() {
return value;
}
public NumberInput setValue(float val) {
value = val;
action.input(this, val);
return this;
}
public NumberInput(ParentElement parent, int x, int y, float value, InputAction action) {
super(parent, x, y, null);
super.action = (sender, val) -> {
try {
invalid = false;
setValue(Float.parseFloat(val.trim()));
}
catch (NumberFormatException e) {
invalid = true;
}
};
this.action = action;
setContent(Float.toString(value));
}
public NumberInput(ParentElement parent, int x, int y, InputAction action) {
this(parent, x, y, 0, action);
}
}

View File

@@ -181,7 +181,7 @@ public abstract class Section extends AbstractParentElement implements Drawable,
@Override
public Optional<Element> hoveredElement(double mouseX, double mouseY) {
for (Selectable element : this.children.selectables) {
var offset = children.getOffsetAndPos(element);
var offset = children.getOffset(element);
if (element.getType() != SelectionType.HOVERED || !((Element)element).isMouseOver(mouseX - offset.x, mouseY - offset.y)) continue;
return Optional.of((Element)element);
}
@@ -191,8 +191,8 @@ public abstract class Section extends AbstractParentElement implements Drawable,
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
for (Element element : this.children()) {
var offset = children.getOffsetAndPos(element);
if (!element.mouseScrolled(mouseX - offset.x, mouseY - offset.y, delta)) continue;
var offset = children.getOffset(element);
if (!element.mouseScrolled(mouseX - offset.x - x, mouseY - offset.y - y, delta)) continue;
return true;
}
return false;
@@ -200,8 +200,8 @@ public abstract class Section extends AbstractParentElement implements Drawable,
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
for (Element element : this.children()) {
var offset = children.getOffsetAndPos(element);
if (!element.mouseClicked(mouseX - offset.x, mouseY - offset.y, button)) continue;
var offset = children.getOffset(element);
if (!element.mouseClicked(mouseX - offset.x - x, mouseY - offset.y - y, button)) continue;
this.setFocused(element);
if (button == 0) {
this.setDragging(true);
@@ -214,8 +214,8 @@ public abstract class Section extends AbstractParentElement implements Drawable,
@Override
public void mouseMoved(double mouseX, double mouseY) {
for (Element element : this.children()) {
var offset = children.getOffsetAndPos(element);
element.mouseMoved(mouseX - offset.x, mouseY - offset.y);
var offset = children.getOffset(element);
element.mouseMoved(mouseX - offset.x - x, mouseY - offset.y - y);
}
}
@@ -224,8 +224,8 @@ public abstract class Section extends AbstractParentElement implements Drawable,
this.setDragging(false);
for (Element element : children.get()) {
var offset = children.getOffsetAndPos(element);
if (element.mouseReleased(mouseX - (int)offset.x, mouseY - (int)offset.y, button)) return true;
var offset = children.getOffset(element);
if (element.mouseReleased(mouseX - (int)offset.x - x, mouseY - (int)offset.y - y, button)) return true;
}
return false;
@@ -234,8 +234,8 @@ public abstract class Section extends AbstractParentElement implements Drawable,
@Override
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
if (this.getFocused() != null && this.isDragging() && button == 0) {
var offset = children.getOffsetAndPos(getFocused());
return this.getFocused().mouseDragged(mouseX - offset.x, mouseY - offset.y, button, deltaX, deltaY);
var offset = children.getOffset(getFocused());
return this.getFocused().mouseDragged(mouseX - offset.x - x, mouseY - offset.y - y, button, deltaX, deltaY);
}
return false;
}

View File

@@ -9,7 +9,6 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.ColorHelper.Argb;
@@ -45,11 +44,11 @@ public class SelectionScreen<T> extends Screen {
float y = 0;
matrices.push();
matrices.translate(20, 5, 0);
textRenderer.draw(matrices, new LiteralText(element.getDisplayNameOrDefault()).formatted(Formatting.BOLD), 0, y, 0xFFFFFFFF);
textRenderer.draw(matrices, Text.of(element.getDisplayNameOrDefault()).copy().formatted(Formatting.BOLD), 0, y, 0xFFFFFFFF);
y += textRenderer.fontHeight + 3;
textRenderer.draw(matrices, new LiteralText("Author: " + element.getAuthorOrDefault()), 0, y, 0xFFFFFFFF);
textRenderer.draw(matrices, Text.of("Author: " + element.getAuthorOrDefault()), 0, y, 0xFFFFFFFF);
y += textRenderer.fontHeight + 2;
y += drawWarpedText(textRenderer, matrices, new LiteralText(element.getDescriptionOrDefault()).formatted(Formatting.ITALIC), 0, (int)y, width - 40);
y += drawWarpedText(textRenderer, matrices, Text.of(element.getDescriptionOrDefault()).copy().formatted(Formatting.ITALIC), 0, (int)y, width - 40);
y += 5;
matrices.pop();

View File

@@ -11,12 +11,12 @@ import net.minecraft.util.math.BlockPos;
// From flogic's mod
@Mixin(ChunkBuilder.BuiltChunk.class)
abstract class BuiltChunkMixin {
public abstract class BuiltChunkMixin {
@Inject(method = "clear", at = @At(value = "TAIL"), cancellable = true)
public void clear(CallbackInfo ci) {
// ci.cancel();
// return;
BlockPos origin = ((ChunkBuilder.BuiltChunk)(Object)this).getOrigin();
AnimatedChunks.getInstance().getProgressManager().unload(origin.getX(), 0, origin.getZ());
AnimatedChunks.getInstance().animator.unload(origin.getX(), 0, origin.getZ());
}
}

View File

@@ -7,8 +7,8 @@ import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.LightmapTextureManager;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.Shader;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.render.WorldRenderer.ChunkInfo;
import net.minecraft.client.render.chunk.ChunkBuilder.BuiltChunk;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Matrix4f;
@@ -22,22 +22,17 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import it.unimi.dsi.fastutil.objects.ObjectListIterator;
import me.topchetoeu.animatedchunks.AnimatedChunks;
import me.topchetoeu.animatedchunks.animation.ProgressManager;
@Mixin(WorldRenderer.class)
abstract class WorldRendererMixin {
public abstract class WorldRendererMixin {
private long lastTime = System.nanoTime();
@Accessor abstract BuiltChunkStorage getChunks();
private ProgressManager getProgressManager() {
return AnimatedChunks.getInstance().getProgressManager();
}
@Inject(method = "render", at = @At(value = "HEAD"))
private void renderStart(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, CallbackInfo ci) {
long currTime = System.nanoTime();
getProgressManager().tick((currTime - lastTime) / 1000000000f);
AnimatedChunks.getInstance().animator.tick((currTime - lastTime) / 1000000000f);
lastTime = currTime;
}
@@ -51,48 +46,44 @@ abstract class WorldRendererMixin {
if (playerY < 0) chunkY--;
if (playerZ < 0) chunkZ--;
getProgressManager().unloadAllFar((int)((WorldRenderer)(Object)this).getViewDistance(), chunkX, chunkY, chunkZ);
AnimatedChunks.getInstance().animator.unloadAllFar((int)((WorldRenderer)(Object)this).getViewDistance(), chunkX, chunkY, chunkZ);
}
@Inject(method = "renderLayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gl/VertexBuffer;drawVertices()V"), locals=LocalCapture.CAPTURE_FAILHARD)
@Inject(method = "renderLayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gl/VertexBuffer;drawElements()V"), locals=LocalCapture.CAPTURE_FAILHARD)
private void renderChunkBefore(RenderLayer renderLayer, MatrixStack matrices, double playerX, double playerY, double playerZ, Matrix4f positionMatrix, CallbackInfo ci,
boolean _1, ObjectListIterator<?> _2, VertexFormat _3, Shader shader, GlUniform _4, boolean _5, WorldRenderer.ChunkInfo _6, BuiltChunk chunk) {
boolean _1, ObjectListIterator<?> _2, Shader shader, GlUniform _4, ChunkInfo _6, BuiltChunk chunk) {
matrices.push();
int x = chunk.getOrigin().getX();
int y = chunk.getOrigin().getY();
int z = chunk.getOrigin().getZ();
// AnimatedChunks.getInstance().animator.animate(matrices, new BlockPos(chunk.getOrigin().getX(), 0, chunk.getOrigin().getZ()), new Vector3d(playerX, playerY, playerZ));
shader.fogStart.set(Float.POSITIVE_INFINITY);
// if (getProgressManager().isChunkLoaded(x, 0, z)) {
// float progress = getProgressManager().getChunkProgress(x, 0, z);
if (getProgressManager().isChunkLoaded(x, 0, z)) {
float progress = getProgressManager().getChunkProgress(x, 0, z);
// if (progress < 0.999) {
// progress = AnimatedChunks.getInstance().getEaseManager().getValue().ease(progress);
if (progress < 0.999) {
progress = AnimatedChunks.getInstance().getEaseManager().getValue().ease(progress);
// float centerX = (float)playerX - x;
// float centerY = (float)playerY - y;
// float centerZ = (float)playerZ - z;
float centerX = (float)playerX - x;
float centerY = (float)playerY - y;
float centerZ = (float)playerZ - z;
matrices.translate(-centerX, -centerY, -centerZ);
AnimatedChunks.getInstance().getAnimationManager().getValue().animate(progress, matrices, x, y, z, (float)playerX, (float)playerY, (float)playerZ);
matrices.translate(centerX, centerY, centerZ);
}
}
else {
matrices.scale(0, 0, 0);
}
// matrices.translate(-centerX, -centerY, -centerZ);
// AnimatedChunks.getInstance().getAnimationManager().getValue().animate(progress, matrices, x, y, z, (float)playerX, (float)playerY, (float)playerZ);
// matrices.translate(centerX, centerY, centerZ);
// }
// }
// else {
// matrices.scale(0, 0, 0);
// }
shader.modelViewMat.set(matrices.peek().getPositionMatrix());
matrices.pop();
shader.bind();
}
@Inject(method = "renderLayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gl/VertexBuffer;drawVertices()V"), locals=LocalCapture.CAPTURE_FAILHARD)
@Inject(method = "renderLayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gl/VertexBuffer;drawElements()V"), locals=LocalCapture.CAPTURE_FAILHARD)
private void renderChunkAfter(RenderLayer renderLayer, MatrixStack matrices, double playerX, double playerY, double playerZ, Matrix4f positionMatrix, CallbackInfo ci,
boolean _1, ObjectListIterator<?> _2, VertexFormat _3, Shader _4, GlUniform _5, boolean _6, WorldRenderer.ChunkInfo _7, BuiltChunk chunk) {
boolean _1, ObjectListIterator<?> _2, Shader shader, GlUniform _4, ChunkInfo _6, BuiltChunk chunk) {
int x = chunk.getOrigin().getX();
int z = chunk.getOrigin().getZ();
getProgressManager().load(x, 0, z);
AnimatedChunks.getInstance().animator.load(x, 0, z);
}
}

View File

@@ -1,9 +1,9 @@
{
"schemaVersion": 1,
"id": "animated-chunks",
"version": "0.2.0",
"version": "0.3.0",
"name": "Animated Chunks",
"description": "animated chunk load animations.",
"description": "Animated chunk load animations.",
"authors": [ "TopchetoEU" ],
"license": "MIT",
"icon": "assets/animated-chunks/icon.png",
@@ -23,7 +23,10 @@
"depends": {
"fabricloader": ">=0.9.3+build.207",
"fabric": "*",
"minecraft": ">=1.18.2",
"modmenu": ">=3.2.1"
"minecraft": "=1.19.2",
"modmenu": ">=4.0.0"
},
"breaks": {
"sodium": "*"
}
}