├── .gitignore ├── .pretty_readme ├── backpack.png ├── banner.png ├── icon.png ├── preview_bass.png ├── preview_blue_shark.png ├── preview_blue_whale.png ├── preview_bread.png ├── preview_gray_shark.png ├── preview_killer_whale.png ├── preview_seal.png ├── preview_sleep_in.png ├── preview_sleep_out.png ├── preview_trans_shark.png ├── preview_trinkets.png ├── recipe_bass.png ├── recipe_blue_shark.png ├── recipe_blue_whale.png ├── recipe_bread.png ├── recipe_killer_whale.png ├── recipe_seal.png ├── trade_gray_shark.png └── trade_trans_shark.png ├── LICENSE ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main ├── java └── mc │ └── recraftors │ └── blahaj │ ├── Blahaj.java │ ├── BooleanProvider.java │ ├── PreLaunchUtils.java │ ├── compat │ ├── BlahajBassAnimator.java │ ├── BooleanConsumer.java │ ├── DataHolder.java │ └── TrinketPlushRenderer.java │ ├── item │ ├── ContainedItemStack.java │ ├── CuddlyContainerTooltipComponent.java │ ├── CuddlyContainerTooltipData.java │ ├── CuddlyItem.java │ ├── HandItemStackProvider.java │ ├── ItemContainerCuddlyItem.java │ ├── ItemStackProvider.java │ └── nbt │ │ ├── ContainedNbtByteArray.java │ │ ├── ContainedNbtCompound.java │ │ ├── ContainedNbtElement.java │ │ ├── ContainedNbtIntArray.java │ │ ├── ContainedNbtList.java │ │ └── ContainedNbtLongArray.java │ └── mixin │ ├── AnvilScreenHandlerMixin.java │ ├── ClientPlayNetworkHandlerMixin.java │ ├── EnchantmentMixin.java │ ├── ForgingScreenHandlerMixin.java │ ├── ItemGroupsMixin.java │ ├── ItemMixin.java │ ├── ItemStackMixin.java │ ├── ItemsMixin.java │ ├── LivingEntityMixin.java │ ├── LootManagerMixin.java │ ├── LootTableMixin.java │ ├── MinecraftServerMixin.java │ ├── RecipeManagerMixin.java │ ├── ServerRecipeBookMixin.java │ ├── compat │ ├── Plugin.java │ ├── andromeda │ │ └── present │ │ │ └── AutoAdvGenerationMixin.java │ ├── immersive_melodies │ │ └── present │ │ │ └── ItemsMixin.java │ ├── notenoughanimations │ │ └── present │ │ │ ├── HeldItemHandlerMixin.java │ │ │ └── SleepAnimationMixin.java │ ├── travelersbackpack │ │ ├── and │ │ │ └── trinkets │ │ │ │ └── TravelersBackpackWearableModelMixin.java │ │ └── present │ │ │ ├── ModBlockEntityTypesMixin.java │ │ │ ├── ModBlocksMixin.java │ │ │ ├── ModItemGroupsMixin.java │ │ │ ├── ModItemsMixin.java │ │ │ └── ResourceUtilsMixin.java │ └── trinkets │ │ └── present │ │ ├── BlahajMixin.java │ │ ├── CapeFeatureRendererMixin.java │ │ ├── CuddlyItemMixin.java │ │ └── PlayerEntityModelMixin.java │ └── render │ ├── AllayEntityMixin.java │ ├── BipedEntityModelMixin.java │ ├── HeldItemRendererMixin.java │ ├── LivingEntityRendererMixin.java │ ├── PlayerEntityRendererMixin.java │ ├── ServerPlayerInteractionManagerMixin.java │ └── TooltipComponentMixin.java └── resources ├── assets └── blahaj │ ├── blockstates │ └── blahaj_backpack.json │ ├── icon.png │ ├── lang │ ├── en_us.json │ └── sv_se.json │ ├── models │ ├── block │ │ └── blahaj_backpack.json │ └── item │ │ ├── blahaj_backpack.json │ │ ├── blahaj_bass.json │ │ ├── blahaj_bass_hand.json │ │ ├── blue_shark.json │ │ ├── blue_whale.json │ │ ├── bread.json │ │ ├── glitch.json │ │ ├── gray_shark.json │ │ ├── killer_whale.json │ │ ├── seal.json │ │ └── trans_shark.json │ ├── sounds.json │ ├── sounds │ └── instruments │ │ ├── blahaj_bass.ogg │ │ └── blahaj_bass │ │ ├── c1.ogg │ │ ├── c2.ogg │ │ ├── c3.ogg │ │ ├── c4.ogg │ │ ├── c5.ogg │ │ ├── c6.ogg │ │ ├── c7.ogg │ │ └── c8.ogg │ └── textures │ ├── item │ ├── beyou_shork.png │ ├── blahaj_bass.png │ ├── blue_whale.png │ ├── bred.png │ ├── glitch.png │ ├── gray_shork.png │ ├── killer_whale.png │ ├── seal.png │ └── shork.png │ └── model │ └── blahaj_backpack.png ├── blahaj.accesswidener ├── blahaj.mixins.json ├── data ├── blahaj │ ├── loot_tables │ │ └── blocks │ │ │ └── blahaj_backpack.json │ ├── recipes │ │ ├── blahaj_backpack.json │ │ ├── blahaj_bass.json │ │ ├── blavingad_orca.json │ │ ├── blue_shark.json │ │ ├── blue_whale.json │ │ ├── bread.json │ │ └── seal.json │ └── tags │ │ └── items │ │ ├── blavingad_usable.json │ │ ├── cuddly_items.json │ │ └── non_containable.json ├── c │ └── tags │ │ └── items │ │ └── hidden_from_recipe_viewers.json ├── travelersbackpack │ └── tags │ │ └── items │ │ └── custom_travelers_backpack.json └── trinkets │ └── tags │ └── items │ ├── chest │ ├── back.json │ ├── cape.json │ ├── necklace.json │ └── shoulder.json │ ├── head │ ├── crown.json │ └── hat.json │ └── legs │ ├── belt.json │ └── thighs.json └── fabric.mod.json /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific stuff 2 | .idea/ 3 | 4 | *.iml 5 | *.ipr 6 | *.iws 7 | 8 | # IntelliJ 9 | out/ 10 | # mpeltonen/sbt-idea plugin 11 | .idea_modules/ 12 | 13 | # JIRA plugin 14 | atlassian-ide-plugin.xml 15 | 16 | # Compiled class file 17 | *.class 18 | 19 | # Log file 20 | *.log 21 | 22 | # BlueJ files 23 | *.ctxt 24 | 25 | # Package Files # 26 | *.jar 27 | *.war 28 | *.nar 29 | *.ear 30 | *.zip 31 | *.tar.gz 32 | *.rar 33 | 34 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 35 | hs_err_pid* 36 | 37 | *~ 38 | 39 | # temporary files which can be created if a process still has a handle open of a deleted file 40 | .fuse_hidden* 41 | 42 | # KDE directory preferences 43 | .directory 44 | 45 | # Linux trash folder which might appear on any partition or disk 46 | .Trash-* 47 | 48 | # .nfs files are created when an open file is removed but is still being accessed 49 | .nfs* 50 | 51 | # General 52 | .DS_Store 53 | .AppleDouble 54 | .LSOverride 55 | 56 | # Icon must end with two \r 57 | Icon 58 | 59 | # Thumbnails 60 | ._* 61 | 62 | # Files that might appear in the root of a volume 63 | .DocumentRevisions-V100 64 | .fseventsd 65 | .Spotlight-V100 66 | .TemporaryItems 67 | .Trashes 68 | .VolumeIcon.icns 69 | .com.apple.timemachine.donotpresent 70 | 71 | # Directories potentially created on remote AFP share 72 | .AppleDB 73 | .AppleDesktop 74 | Network Trash Folder 75 | Temporary Items 76 | .apdisk 77 | 78 | # Windows thumbnail cache files 79 | Thumbs.db 80 | Thumbs.db:encryptable 81 | ehthumbs.db 82 | ehthumbs_vista.db 83 | 84 | # Dump file 85 | *.stackdump 86 | 87 | # Folder config file 88 | [Dd]esktop.ini 89 | 90 | # Recycle Bin used on file shares 91 | $RECYCLE.BIN/ 92 | 93 | # Windows Installer files 94 | *.cab 95 | *.msi 96 | *.msix 97 | *.msm 98 | *.msp 99 | 100 | # Windows shortcuts 101 | *.lnk 102 | 103 | .gradle 104 | build/ 105 | 106 | # Ignore Gradle GUI config 107 | gradle-app.setting 108 | 109 | # Cache of project 110 | .gradletasknamecache 111 | 112 | **/build/ 113 | 114 | # Common working directory 115 | run/ 116 | 117 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 118 | !gradle-wrapper.jar 119 | -------------------------------------------------------------------------------- /.pretty_readme/backpack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/backpack.png -------------------------------------------------------------------------------- /.pretty_readme/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/banner.png -------------------------------------------------------------------------------- /.pretty_readme/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/icon.png -------------------------------------------------------------------------------- /.pretty_readme/preview_bass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/preview_bass.png -------------------------------------------------------------------------------- /.pretty_readme/preview_blue_shark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/preview_blue_shark.png -------------------------------------------------------------------------------- /.pretty_readme/preview_blue_whale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/preview_blue_whale.png -------------------------------------------------------------------------------- /.pretty_readme/preview_bread.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/preview_bread.png -------------------------------------------------------------------------------- /.pretty_readme/preview_gray_shark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/preview_gray_shark.png -------------------------------------------------------------------------------- /.pretty_readme/preview_killer_whale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/preview_killer_whale.png -------------------------------------------------------------------------------- /.pretty_readme/preview_seal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/preview_seal.png -------------------------------------------------------------------------------- /.pretty_readme/preview_sleep_in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/preview_sleep_in.png -------------------------------------------------------------------------------- /.pretty_readme/preview_sleep_out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/preview_sleep_out.png -------------------------------------------------------------------------------- /.pretty_readme/preview_trans_shark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/preview_trans_shark.png -------------------------------------------------------------------------------- /.pretty_readme/preview_trinkets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/preview_trinkets.png -------------------------------------------------------------------------------- /.pretty_readme/recipe_bass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/recipe_bass.png -------------------------------------------------------------------------------- /.pretty_readme/recipe_blue_shark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/recipe_blue_shark.png -------------------------------------------------------------------------------- /.pretty_readme/recipe_blue_whale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/recipe_blue_whale.png -------------------------------------------------------------------------------- /.pretty_readme/recipe_bread.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/recipe_bread.png -------------------------------------------------------------------------------- /.pretty_readme/recipe_killer_whale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/recipe_killer_whale.png -------------------------------------------------------------------------------- /.pretty_readme/recipe_seal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/recipe_seal.png -------------------------------------------------------------------------------- /.pretty_readme/trade_gray_shark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/trade_gray_shark.png -------------------------------------------------------------------------------- /.pretty_readme/trade_trans_shark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/.pretty_readme/trade_trans_shark.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is the RecraftorsMC port of the [BLAHAJ](https://github.com/Hibiii/Blahaj) 2 | mod for [Quilt](https://quiltmc.org) 3 | 4 | # Source migration 5 | 6 | We moved to [Codeberg](https://codeberg.org/RecraftorsMC/blahaj), any new addition will be happening there! 7 | 8 | --- 9 | 10 | # License 11 | 12 | As a great part of this port's code has been rewritten over the course of its evolution, the latter is 13 | now licensed under the [GPL-3.0](LICENSE) license, as a matter of protection over the provided work. 14 | 15 | The original mod is licensed under the [Unlicense](https://github.com/Hibiii/Blahaj/LICENSE). 16 | Feel free to learn from it, and incorporate it in your own projects. 17 | 18 | The icon of this project is the Blobhaj by [Heatherhorns](https://www.weasyl.com/~heatherhorns), 19 | and is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/). 20 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'fabric-loom' version '1.6-SNAPSHOT' 3 | id 'maven-publish' 4 | } 5 | 6 | version = project.mod_version 7 | group = project.maven_group 8 | 9 | repositories { 10 | maven { 11 | name = "TerraformersMC" 12 | url = "https://maven.terraformersmc.com/" 13 | } 14 | maven { 15 | name = "Ladysnake Libs" 16 | url = 'https://maven.ladysnake.org/releases' 17 | } 18 | maven { 19 | name = "Modrinth" 20 | url = "https://api.modrinth.com/maven" 21 | } 22 | } 23 | 24 | dependencies { 25 | minecraft "com.mojang:minecraft:${project.minecraft_version}" 26 | mappings "net.fabricmc:yarn:${project.minecraft_version}+build.${project.yarn_build}" 27 | modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" 28 | 29 | modImplementation(include "maven.modrinth:unruled-api:${project.unruled_version}") 30 | 31 | modCompileOnly "dev.emi:trinkets:${project.trinkets_version}" 32 | modCompileOnly "maven.modrinth:travelersbackpack:${project.travelersbackpack_version}" 33 | modCompileOnly "maven.modrinth:not-enough-animations:${project.notenoughanimations_version}" 34 | modCompileOnly "maven.modrinth:immersive-melodies:${project.immersivemelodies_version}" 35 | modCompileOnly "maven.modrinth:andromeda:${project.andromeda_version}" 36 | 37 | modImplementation "net.fabricmc.fabric-api:fabric-api:0.91.0+1.20.1" 38 | } 39 | 40 | loom { 41 | accessWidenerPath = file("src/main/resources/${project.mod_id}.accesswidener") 42 | } 43 | 44 | processResources { 45 | inputs.property "version", project.version 46 | filteringCharset "UTF-8" 47 | 48 | filesMatching("fabric.mod.json") { 49 | expand "version": project.version 50 | } 51 | } 52 | 53 | def targetJavaVersion = 17 54 | tasks.withType(JavaCompile).configureEach { 55 | it.options.encoding = "UTF-8" 56 | if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) { 57 | it.options.release = targetJavaVersion 58 | } 59 | } 60 | 61 | java { 62 | def javaVersion = JavaVersion.toVersion(targetJavaVersion) 63 | if (JavaVersion.current() < javaVersion) { 64 | toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion) 65 | } 66 | archivesBaseName = project.mod_id + "_" + project.minecraft_version 67 | withSourcesJar() 68 | } 69 | 70 | jar { 71 | from("LICENSE") { 72 | rename { "${it}_${project.archivesBaseName}" } 73 | } 74 | } 75 | 76 | publishing { 77 | publications { 78 | mavenJava(MavenPublication) { 79 | from components.java 80 | } 81 | } 82 | repositories { 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Done to increase the memory available to gradle. 2 | org.gradle.jvmargs=-Xmx1G 3 | # Fabric Properties 4 | minecraft_version=1.20.1 5 | yarn_build=10 6 | loader_version=0.15.7 7 | # Mod Properties 8 | mod_version=0.6.3 9 | maven_group=mc.recraftors 10 | mod_id=blahaj 11 | # Dependencies 12 | unruled_version=0.4-fabric+1.20 13 | trinkets_version=3.7.1 14 | travelersbackpack_version=C78BanYS 15 | notenoughanimations_version=YbSMjtFY 16 | immersivemelodies_version=0.1.0+1.20.1 17 | andromeda_version=1.12.0-1.20.1-build.96 -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit 88 | 89 | # Use the maximum available, or set MAX_FD != -1 to use that value. 90 | MAX_FD=maximum 91 | 92 | warn () { 93 | echo "$*" 94 | } >&2 95 | 96 | die () { 97 | echo 98 | echo "$*" 99 | echo 100 | exit 1 101 | } >&2 102 | 103 | # OS specific support (must be 'true' or 'false'). 104 | cygwin=false 105 | msys=false 106 | darwin=false 107 | nonstop=false 108 | case "$( uname )" in #( 109 | CYGWIN* ) cygwin=true ;; #( 110 | Darwin* ) darwin=true ;; #( 111 | MSYS* | MINGW* ) msys=true ;; #( 112 | NONSTOP* ) nonstop=true ;; 113 | esac 114 | 115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 116 | 117 | 118 | # Determine the Java command to use to start the JVM. 119 | if [ -n "$JAVA_HOME" ] ; then 120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 121 | # IBM's JDK on AIX uses strange locations for the executables 122 | JAVACMD=$JAVA_HOME/jre/sh/java 123 | else 124 | JAVACMD=$JAVA_HOME/bin/java 125 | fi 126 | if [ ! -x "$JAVACMD" ] ; then 127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 128 | 129 | Please set the JAVA_HOME variable in your environment to match the 130 | location of your Java installation." 131 | fi 132 | else 133 | JAVACMD=java 134 | if ! command -v java >/dev/null 2>&1 135 | then 136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | fi 142 | 143 | # Increase the maximum file descriptors if we can. 144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 145 | case $MAX_FD in #( 146 | max*) 147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 148 | # shellcheck disable=SC2039,SC3045 149 | MAX_FD=$( ulimit -H -n ) || 150 | warn "Could not query maximum file descriptor limit" 151 | esac 152 | case $MAX_FD in #( 153 | '' | soft) :;; #( 154 | *) 155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 156 | # shellcheck disable=SC2039,SC3045 157 | ulimit -n "$MAX_FD" || 158 | warn "Could not set maximum file descriptor limit to $MAX_FD" 159 | esac 160 | fi 161 | 162 | # Collect all arguments for the java command, stacking in reverse order: 163 | # * args from the command line 164 | # * the main class name 165 | # * -classpath 166 | # * -D...appname settings 167 | # * --module-path (only if needed) 168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 169 | 170 | # For Cygwin or MSYS, switch paths to Windows format before running java 171 | if "$cygwin" || "$msys" ; then 172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 174 | 175 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 176 | 177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 178 | for arg do 179 | if 180 | case $arg in #( 181 | -*) false ;; # don't mess with options #( 182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 183 | [ -e "$t" ] ;; #( 184 | *) false ;; 185 | esac 186 | then 187 | arg=$( cygpath --path --ignore --mixed "$arg" ) 188 | fi 189 | # Roll the args list around exactly as many times as the number of 190 | # args, so each arg winds up back in the position where it started, but 191 | # possibly modified. 192 | # 193 | # NB: a `for` loop captures its iteration list before it begins, so 194 | # changing the positional parameters here affects neither the number of 195 | # iterations, nor the values presented in `arg`. 196 | shift # remove old arg 197 | set -- "$@" "$arg" # push replacement arg 198 | done 199 | fi 200 | 201 | 202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 204 | 205 | # Collect all arguments for the java command: 206 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 207 | # and any embedded shellness will be escaped. 208 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 209 | # treated as '${Hostname}' itself on the command line. 210 | 211 | set -- \ 212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 213 | -classpath "$CLASSPATH" \ 214 | org.gradle.wrapper.GradleWrapperMain \ 215 | "$@" 216 | 217 | # Stop when "xargs" is not available. 218 | if ! command -v xargs >/dev/null 2>&1 219 | then 220 | die "xargs is not available" 221 | fi 222 | 223 | # Use "xargs" to parse quoted args. 224 | # 225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 226 | # 227 | # In Bash we could simply go: 228 | # 229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 230 | # set -- "${ARGS[@]}" "$@" 231 | # 232 | # but POSIX shell has neither arrays nor command substitution, so instead we 233 | # post-process each arg (as a line of input to sed) to backslash-escape any 234 | # character that might be a shell metacharacter, then use eval to reverse 235 | # that process (while maintaining the separation between arguments), and wrap 236 | # the whole thing up as a single "set" statement. 237 | # 238 | # This will of course break if any of these variables contains a newline or 239 | # an unmatched quote. 240 | # 241 | 242 | eval "set -- $( 243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 244 | xargs -n1 | 245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 246 | tr '\n' ' ' 247 | )" '"$@"' 248 | 249 | exec "$JAVACMD" "$@" 250 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 1>&2 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 48 | echo. 1>&2 49 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 50 | echo location of your Java installation. 1>&2 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 1>&2 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 62 | echo. 1>&2 63 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 64 | echo location of your Java installation. 1>&2 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { 4 | name = 'Fabric' 5 | url = 'https://maven.fabricmc.net/' 6 | } 7 | gradlePluginPortal() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/Blahaj.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj; 2 | 3 | import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; 4 | import mc.recraftors.blahaj.item.CuddlyItem; 5 | import mc.recraftors.unruled_api.UnruledApi; 6 | import net.fabricmc.api.ModInitializer; 7 | import net.minecraft.entity.LivingEntity; 8 | import net.minecraft.item.Item; 9 | import net.minecraft.item.ItemStack; 10 | import net.minecraft.item.Items; 11 | import net.minecraft.registry.*; 12 | import net.minecraft.registry.entry.RegistryEntryList; 13 | import net.minecraft.registry.tag.TagKey; 14 | import net.minecraft.util.Identifier; 15 | import net.minecraft.village.TradeOffer; 16 | import net.minecraft.village.TradeOffers; 17 | import net.minecraft.village.VillagerProfession; 18 | import net.minecraft.world.GameRules; 19 | import org.apache.logging.log4j.LogManager; 20 | import org.apache.logging.log4j.Logger; 21 | import org.jetbrains.annotations.Nullable; 22 | 23 | import java.util.*; 24 | 25 | public class Blahaj implements ModInitializer { 26 | public static final Identifier BLAHAJ_ID; 27 | public static final Identifier KLAPPAR_HAJ_ID; 28 | public static final Identifier BEYOU_BLAHAJ_ID; 29 | public static final Identifier BLAVINGAD_ID; 30 | public static final Identifier ORCA_HAJ_ID; 31 | public static final Identifier BREAD_ID; 32 | public static final Identifier SEAL_ID; 33 | public static final Identifier $k_O$8; 34 | public static final Identifier CUDDLY_ITEM_TAG_ID; 35 | public static final Identifier NON_CONTAINABLE_ITEMS_TAG_ID; 36 | public static final Identifier BLAVINGAD_USABLE_ITEMS_ID; 37 | public static final TagKey CUDDLY_ITEMS; 38 | public static final TagKey NON_CONTAINABLE_ITEMS; 39 | public static final TagKey BLAVINGAD_USABLE_ITEMS; 40 | 41 | public static final GameRules.Key ENABLE_CONTAINER_USE; 42 | 43 | public static final String MOD_ID; 44 | public static final String TOOLTIP_PRE; 45 | private static final Map ITEM_MAP; 46 | private static final Random RANDOM; 47 | 48 | static { 49 | MOD_ID = "blahaj"; 50 | TOOLTIP_PRE = String.format("item.%s.%%s.tooltip",MOD_ID); 51 | BLAHAJ_ID = new Identifier(MOD_ID, "blue_shark"); 52 | KLAPPAR_HAJ_ID = new Identifier(MOD_ID, "gray_shark"); 53 | BEYOU_BLAHAJ_ID = new Identifier(MOD_ID, "trans_shark"); 54 | BLAVINGAD_ID = new Identifier(MOD_ID, "blue_whale"); 55 | ORCA_HAJ_ID = new Identifier(MOD_ID, "killer_whale"); 56 | BREAD_ID = new Identifier(MOD_ID, "bread"); 57 | SEAL_ID = new Identifier(MOD_ID, "seal"); 58 | $k_O$8 = new Identifier(MOD_ID, "glitch"); 59 | CUDDLY_ITEM_TAG_ID = new Identifier(MOD_ID, "cuddly_items"); 60 | NON_CONTAINABLE_ITEMS_TAG_ID = new Identifier(MOD_ID, "not_containable"); 61 | BLAVINGAD_USABLE_ITEMS_ID = new Identifier(MOD_ID, "blavingad_usable"); 62 | CUDDLY_ITEMS = TagKey.of(RegistryKeys.ITEM, CUDDLY_ITEM_TAG_ID); 63 | NON_CONTAINABLE_ITEMS = TagKey.of(RegistryKeys.ITEM, NON_CONTAINABLE_ITEMS_TAG_ID); 64 | BLAVINGAD_USABLE_ITEMS = TagKey.of(RegistryKeys.ITEM, BLAVINGAD_USABLE_ITEMS_ID); 65 | 66 | ENABLE_CONTAINER_USE = UnruledApi.registerBoolean("blahaj.contained.enable_use", GameRules.Category.PLAYER, false); 67 | 68 | ITEM_MAP = new HashMap<>(); 69 | RANDOM = new Random(); 70 | } 71 | 72 | public static final Logger LOGGER = LogManager.getLogger(MOD_ID); 73 | 74 | @Override 75 | public void onInitialize() { 76 | injectTrades(); 77 | } 78 | 79 | public static void storeItem(Identifier id, CuddlyItem item) { 80 | Objects.requireNonNull(id); 81 | Objects.requireNonNull(item); 82 | ITEM_MAP.put(id, item); 83 | } 84 | 85 | public static Collection getItems() { 86 | return ITEM_MAP.values(); 87 | } 88 | 89 | public static Optional itemSupplier(Identifier id) { 90 | return Optional.ofNullable(ITEM_MAP.get(id)); 91 | } 92 | 93 | public static void injectTrades() { 94 | Optional blahajSupplier = itemSupplier(BLAHAJ_ID); 95 | Optional klapparSupplier = itemSupplier(KLAPPAR_HAJ_ID); 96 | Optional beyouSupplier = itemSupplier(BEYOU_BLAHAJ_ID); 97 | klapparSupplier.ifPresent( 98 | klappar -> TradeOffers.PROFESSION_TO_LEVELED_TRADE.computeIfAbsent(VillagerProfession.SHEPHERD, 99 | key -> new Int2ObjectLinkedOpenHashMap<>()).compute(5, (i, v) -> { 100 | if (v == null) { 101 | v = new TradeOffers.Factory[1]; 102 | } else { 103 | v = Arrays.copyOf(v, v.length +1); 104 | } 105 | v[v.length-1] = (entity, random) -> new TradeOffer(new ItemStack(Items.EMERALD, 15), new ItemStack(klappar), 2, 30, 0.1f); 106 | return v; 107 | }) 108 | ); 109 | beyouSupplier.ifPresent(beyou -> { 110 | if (blahajSupplier.isEmpty()) return; 111 | TradeOffers.PROFESSION_TO_LEVELED_TRADE.computeIfAbsent(VillagerProfession.LEATHERWORKER, key -> new Int2ObjectLinkedOpenHashMap<>()).compute(4, (i, v) -> { 112 | if (v == null) { 113 | v = new TradeOffers.Factory[1]; 114 | } else { 115 | v = Arrays.copyOf(v, v.length+1); 116 | } 117 | v[v.length-1] = (entity, random) -> new TradeOffer(new ItemStack(blahajSupplier.get(), 1), new ItemStack(Items.EMERALD, 20), new ItemStack(beyou), 2, 20, 0.1f); 118 | return v; 119 | }); 120 | }); 121 | } 122 | 123 | public static boolean holdsOnlyCuddlyItem(LivingEntity entity) { 124 | return (isCuddly(entity.getMainHandStack()) && entity.getOffHandStack().isEmpty() || 125 | isCuddly(entity.getOffHandStack()) && entity.getMainHandStack().isEmpty()); 126 | } 127 | 128 | public static boolean isCuddly(ItemStack stack) { 129 | return stack.isIn(CUDDLY_ITEMS) || stack.getItem() instanceof CuddlyItem; 130 | } 131 | 132 | public static boolean isHidden(Identifier identifier) { 133 | return identifier.equals($k_O$8); 134 | } 135 | 136 | public static @Nullable Item randomItem(TagKey tag) { 137 | Optional> named = Registries.ITEM.getEntryList(tag); 138 | if (named.isEmpty()) return null; 139 | int i = named.get().size(); 140 | return named.get().get(RANDOM.nextInt(i)).comp_349(); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/BooleanProvider.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj; 2 | 3 | public interface BooleanProvider { 4 | boolean blahaj$getBool(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/PreLaunchUtils.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj; 2 | 3 | import net.fabricmc.loader.api.FabricLoader; 4 | 5 | public final class PreLaunchUtils { 6 | private PreLaunchUtils() {} 7 | 8 | public static boolean isModLoaded(String modId) { 9 | return FabricLoader.getInstance().getAllMods().stream() 10 | .anyMatch(c -> c.getMetadata().getId().toLowerCase().replace('-', '_').equals(modId)); 11 | } 12 | 13 | public static boolean modHasAuthor(String modId, String author) { 14 | return FabricLoader.getInstance().getAllMods().stream() 15 | .filter(c -> c.getMetadata().getId().toLowerCase().replace('-', '_').equals(modId)) 16 | .anyMatch(mod -> mod.getMetadata().getAuthors().stream() 17 | .anyMatch(p -> p.getName().toLowerCase() 18 | .replace(' ', '_').replace('-', '_').equals(author))); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/compat/BlahajBassAnimator.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.compat; 2 | 3 | import immersive_melodies.client.MelodyProgress; 4 | import immersive_melodies.client.animation.animators.Animator; 5 | import net.minecraft.client.model.ModelPart; 6 | import net.minecraft.client.render.entity.model.BipedEntityModel; 7 | import net.minecraft.entity.LivingEntity; 8 | 9 | public class BlahajBassAnimator implements Animator { 10 | @Override 11 | public void setAngles(ModelPart reach, ModelPart hold, BipedEntityModel model, LivingEntity entity, MelodyProgress progress, float v) { 12 | reach.pitch = -1.2F - progress.getCurrent(); 13 | reach.roll = -0.2F; 14 | reach.yaw = progress.getCurrentPitch() - 0.5F; 15 | hold.pitch = -0.75F; 16 | hold.yaw = 0.0F; 17 | hold.roll = hold.roll * 0.25F - 0.2F; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/compat/BooleanConsumer.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.compat; 2 | 3 | public interface BooleanConsumer { 4 | void blahaj$consume(boolean b); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/compat/DataHolder.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.compat; 2 | 3 | import com.google.gson.internal.LinkedTreeMap; 4 | 5 | import java.util.LinkedHashMap; 6 | import java.util.Map; 7 | 8 | public final class DataHolder { 9 | private DataHolder() {} 10 | 11 | public static final Map> compatDataMap = new LinkedTreeMap<>(); 12 | 13 | public static Map modMap(String modId) { 14 | Map modMap = DataHolder.compatDataMap.putIfAbsent(modId, new LinkedHashMap<>()); 15 | if (modMap == null) { 16 | modMap = new LinkedHashMap<>(); 17 | DataHolder.compatDataMap.put(modId, modMap); 18 | } 19 | return modMap; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/compat/TrinketPlushRenderer.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.compat; 2 | 3 | import dev.emi.trinkets.api.SlotReference; 4 | import dev.emi.trinkets.api.TrinketComponent; 5 | import dev.emi.trinkets.api.TrinketInventory; 6 | import dev.emi.trinkets.api.TrinketsApi; 7 | import dev.emi.trinkets.api.client.TrinketRenderer; 8 | import mc.recraftors.blahaj.item.CuddlyItem; 9 | import net.minecraft.client.render.VertexConsumerProvider; 10 | import net.minecraft.client.render.entity.model.BipedEntityModel; 11 | import net.minecraft.client.render.entity.model.EntityModel; 12 | import net.minecraft.client.util.math.MatrixStack; 13 | import net.minecraft.entity.LivingEntity; 14 | import net.minecraft.item.ItemStack; 15 | 16 | import java.util.Map; 17 | import java.util.Optional; 18 | 19 | public interface TrinketPlushRenderer extends TrinketRenderer { 20 | @Override 21 | default void render(ItemStack stack, SlotReference slotReference, EntityModel contextModel, 22 | MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, 23 | LivingEntity entity, float limbAngle, float limbDistance, float tickDelta, 24 | float animationProgress, float headYaw, float headPitch) { 25 | if (! (contextModel instanceof BipedEntityModel model)) return; 26 | //matrices.push(); 27 | switch (slotReference.inventory().getSlotType().getGroup()) { 28 | case "head" -> blahaj$trinkets$renderHead(stack, slotReference, model, matrices, vertexConsumers, light, entity, limbAngle, limbDistance, tickDelta, animationProgress, headYaw, headPitch); 29 | case "chest" -> blahaj$trinkets$renderChest(stack, slotReference, model, matrices, vertexConsumers, light, entity, limbAngle, limbDistance, tickDelta, animationProgress, headYaw, headPitch); 30 | case "legs" -> blahaj$trinkets$renderLegs(stack, slotReference, model, matrices, vertexConsumers, light, entity, limbAngle, limbDistance, tickDelta, animationProgress, headYaw, headPitch); 31 | case "feet" -> blahaj$trinkets$renderFeet(stack, slotReference, model, matrices, vertexConsumers, light, entity, limbAngle, limbDistance, tickDelta, animationProgress, headYaw, headPitch); 32 | case "hand" -> blahak$trinkets$renderHand(stack, slotReference, model, matrices, vertexConsumers, light, entity, limbAngle, limbDistance, tickDelta, animationProgress, headYaw, headPitch); 33 | } 34 | //matrices.pop(); 35 | } 36 | 37 | default void blahaj$trinkets$renderHead(ItemStack stack, SlotReference reference, BipedEntityModel model, 38 | MatrixStack matrix, VertexConsumerProvider provider, int light, LivingEntity entity, 39 | float limbAngle, float limbDistance, float tickDelta, float animationProgress, 40 | float headYaw, float headPitch) {} 41 | 42 | default void blahaj$trinkets$renderChest(ItemStack stack, SlotReference reference, BipedEntityModel model, 43 | MatrixStack matrix, VertexConsumerProvider provider, int light, LivingEntity entity, 44 | float limbAngle, float limbDistance, float tickDelta, float animationProgress, 45 | float headYaw, float headPitch) {} 46 | 47 | default void blahaj$trinkets$renderLegs(ItemStack stack, SlotReference reference, BipedEntityModel model, 48 | MatrixStack matrix, VertexConsumerProvider provider, int light, LivingEntity entity, 49 | float limbAngle, float limbDistance, float tickDelta, float animationProgress, 50 | float headYaw, float headPitch) {} 51 | 52 | default void blahaj$trinkets$renderFeet(ItemStack stack, SlotReference reference, BipedEntityModel model, 53 | MatrixStack matrix, VertexConsumerProvider provider, int light, LivingEntity entity, 54 | float limbAngle, float limbDistance, float tickDelta, float animationProgress, 55 | float headYaw, float headPitch) {} 56 | 57 | default void blahak$trinkets$renderHand(ItemStack stack, SlotReference reference, BipedEntityModel model, 58 | MatrixStack matrix, VertexConsumerProvider provider, int light, LivingEntity entity, 59 | float limbAngle, float limbDistance, float tickDelta, float animationProgress, 60 | float headYaw, float headPitch) {} 61 | 62 | static boolean hasCuddlyInSlot(LivingEntity entity, String group, String... names) { 63 | Optional optionalComponent = TrinketsApi.getTrinketComponent(entity); 64 | if (optionalComponent.isEmpty()) return false; 65 | TrinketComponent component = optionalComponent.get(); 66 | Map groupMap = component.getInventory().get(group); 67 | if (groupMap == null) return false; 68 | Optional optionalInventory = Optional.empty(); 69 | for (String name : names) { 70 | optionalInventory = Optional.ofNullable(groupMap.get(name)); 71 | if (optionalInventory.isPresent()) { 72 | break; 73 | } 74 | } 75 | if (optionalInventory.isEmpty()) return false; 76 | TrinketInventory inventory = optionalInventory.get(); 77 | for (int i = 0; i < inventory.size(); i++) { 78 | if (inventory.getStack(i).getItem() instanceof CuddlyItem) return true; 79 | } 80 | return false; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/item/CuddlyContainerTooltipComponent.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.item; 2 | 3 | import net.fabricmc.api.EnvType; 4 | import net.fabricmc.api.Environment; 5 | import net.minecraft.client.font.TextRenderer; 6 | import net.minecraft.client.gui.DrawContext; 7 | import net.minecraft.client.gui.screen.ingame.HandledScreen; 8 | import net.minecraft.client.gui.tooltip.BundleTooltipComponent; 9 | import net.minecraft.client.gui.tooltip.TooltipComponent; 10 | import net.minecraft.item.ItemStack; 11 | 12 | @Environment(EnvType.CLIENT) 13 | public class CuddlyContainerTooltipComponent implements TooltipComponent { 14 | private final ItemStack stack; 15 | 16 | public CuddlyContainerTooltipComponent(CuddlyContainerTooltipData data) { 17 | this.stack = data.getStoredStack(); 18 | } 19 | 20 | public boolean isHolding() { 21 | return this.stack != null; 22 | } 23 | 24 | @Override 25 | public int getHeight() { 26 | if (!isHolding()) return 0; 27 | return 26; // 20 + 2 + 4 28 | } 29 | 30 | @Override 31 | public int getWidth(TextRenderer textRenderer) { 32 | if (this.isHolding()) return 20; // 18 + 2 33 | return 0; 34 | } 35 | 36 | @Override 37 | public void drawItems(TextRenderer textRenderer, int i, int j, DrawContext drawContext) { 38 | this.drawSlot(i + 1, j + 1, drawContext, textRenderer); 39 | this.drawOutline(i, j, drawContext); 40 | } 41 | 42 | // adapted from BundleItem 43 | protected void drawSlot(int i, int j, DrawContext drawContext, TextRenderer textRenderer) { 44 | if (!this.isHolding()) return; 45 | ItemStack itemStack = this.stack; 46 | this.draw(drawContext, i, j, Sprite.SLOT); 47 | drawContext.drawItem(itemStack, i + 1, j + 1, 0); 48 | drawContext.drawItemInSlot(textRenderer, itemStack, i + 1, j + 1); 49 | HandledScreen.drawSlotHighlight(drawContext, i + 1, j + 1, 0); 50 | } 51 | 52 | // adapted from BundleItem 53 | protected void drawOutline(int i, int j, DrawContext drawContext) { 54 | this.draw(drawContext, i, j, Sprite.BORDER_CORNER_TOP); 55 | this.draw(drawContext, i + 19, j, Sprite.BORDER_CORNER_TOP); 56 | this.draw(drawContext, i + 1, j, Sprite.BORDER_HORIZONTAL_TOP); 57 | this.draw(drawContext, i + 1, j + 20, Sprite.BORDER_HORIZONTAL_BOTTOM); 58 | this.draw(drawContext, i, j + 1, Sprite.BORDER_VERTICAL); 59 | this.draw(drawContext, i + 19, j + 1, Sprite.BORDER_VERTICAL); 60 | this.draw(drawContext, i, j + 20, Sprite.BORDER_CORNER_BOTTOM); 61 | this.draw(drawContext, i + 19, j + 20, Sprite.BORDER_CORNER_BOTTOM); 62 | } 63 | 64 | // adapted from BundleItem 65 | protected void draw(DrawContext drawContext, int i, int j, Sprite sprite) { 66 | drawContext.drawTexture(BundleTooltipComponent.TEXTURE, i, j, 0, sprite.u, sprite.v, sprite.width, sprite.height, 128, 128); 67 | } 68 | 69 | // adapted from BundleItem 70 | @Environment(value = EnvType.CLIENT) 71 | public enum Sprite { 72 | SLOT(0, 0, 18, 20), 73 | BORDER_VERTICAL(0, 18, 1, 20), 74 | BORDER_HORIZONTAL_TOP(0, 20, 18, 1), 75 | BORDER_HORIZONTAL_BOTTOM(0, 60, 18, 1), 76 | BORDER_CORNER_TOP(0, 20, 1, 1), 77 | BORDER_CORNER_BOTTOM(0, 60, 1, 1); 78 | 79 | public final int u; 80 | public final int v; 81 | public final int width; 82 | public final int height; 83 | 84 | Sprite(int j, int k, int l, int m) { 85 | this.u = j; 86 | this.v = k; 87 | this.width = l; 88 | this.height = m; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/item/CuddlyContainerTooltipData.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.item; 2 | 3 | import net.minecraft.client.item.TooltipData; 4 | import net.minecraft.item.ItemStack; 5 | 6 | public class CuddlyContainerTooltipData implements TooltipData { 7 | private final ItemStack storedStack; 8 | 9 | public CuddlyContainerTooltipData(ItemStack stack) { 10 | if (stack == null || stack.isEmpty()) { 11 | this.storedStack = null; 12 | } else { 13 | this.storedStack = stack; 14 | } 15 | } 16 | 17 | public ItemStack getStoredStack() { 18 | return storedStack; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/item/CuddlyItem.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.item; 2 | 3 | import net.minecraft.block.BlockState; 4 | import net.minecraft.client.item.TooltipContext; 5 | import net.minecraft.entity.player.PlayerEntity; 6 | import net.minecraft.item.Item; 7 | import net.minecraft.item.ItemStack; 8 | import net.minecraft.nbt.NbtCompound; 9 | import net.minecraft.nbt.NbtString; 10 | import net.minecraft.text.Text; 11 | import net.minecraft.util.Formatting; 12 | import net.minecraft.world.World; 13 | import org.jetbrains.annotations.Nullable; 14 | 15 | import java.util.List; 16 | 17 | public class CuddlyItem extends Item { 18 | public static final String OWNER_KEY = "owner"; 19 | public static final String TOOL_KEY_RENAME = "tooltip.blahaj.owner.rename"; 20 | public static final String TOOL_KEY_OWNER = "tooltip.blahaj.owner.craft"; 21 | private final Text subtitle; 22 | 23 | public CuddlyItem(Settings settings, String subtitle) { 24 | super(settings); 25 | this.subtitle = subtitle == null ? null : Text.translatable(subtitle).formatted(Formatting.GRAY); 26 | } 27 | 28 | @Override 29 | public void appendTooltip(ItemStack stack, @Nullable World world, List tooltip, TooltipContext context) { 30 | super.appendTooltip(stack, world, tooltip, context); 31 | if (this.subtitle != null) { 32 | tooltip.add(this.subtitle); 33 | } 34 | if (stack.hasNbt()) { 35 | NbtCompound nbt = stack.getNbt(); 36 | String owner = nbt.getString(OWNER_KEY); 37 | if(owner.isEmpty() || owner.isBlank()) { 38 | return; 39 | } 40 | if (stack.hasCustomName()) { 41 | tooltip.add(Text.translatable(TOOL_KEY_RENAME, getName(), Text.of(owner)).formatted(Formatting.GRAY)); 42 | } else { 43 | tooltip.add(Text.translatable(TOOL_KEY_OWNER, Text.of(owner)).formatted(Formatting.GRAY)); 44 | } 45 | } 46 | } 47 | 48 | @Override 49 | public void onCraft(ItemStack stack, World world, PlayerEntity player) { 50 | super.onCraft(stack, world, player); 51 | if (player != null) { 52 | stack.setSubNbt(OWNER_KEY, NbtString.of(player.getName().getString())); 53 | } 54 | super.onCraft(stack, world, player); 55 | } 56 | 57 | @Override 58 | public float getMiningSpeedMultiplier(ItemStack stack, BlockState state) { 59 | return 0.25f; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/item/HandItemStackProvider.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.item; 2 | 3 | import net.minecraft.item.ItemStack; 4 | import net.minecraft.util.Hand; 5 | 6 | @FunctionalInterface 7 | public interface HandItemStackProvider { 8 | ItemStack blahaj$stackInHandFailSafe(Hand hand); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/item/ItemContainerCuddlyItem.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.item; 2 | 3 | import mc.recraftors.blahaj.Blahaj; 4 | import net.minecraft.client.item.TooltipData; 5 | import net.minecraft.entity.Entity; 6 | import net.minecraft.entity.player.PlayerEntity; 7 | import net.minecraft.inventory.StackReference; 8 | import net.minecraft.item.Item; 9 | import net.minecraft.item.ItemStack; 10 | import net.minecraft.nbt.NbtCompound; 11 | import net.minecraft.registry.tag.TagKey; 12 | import net.minecraft.screen.slot.Slot; 13 | import net.minecraft.sound.SoundEvents; 14 | import net.minecraft.util.*; 15 | 16 | import java.util.Optional; 17 | 18 | public class ItemContainerCuddlyItem extends CuddlyItem { 19 | public static final String STORED_ITEM_KEY = "Item"; 20 | 21 | public ItemContainerCuddlyItem(Settings settings, String subtitle) { 22 | super(settings, subtitle); 23 | } 24 | 25 | @Override 26 | public boolean onStackClicked(ItemStack itemStack, Slot slot, ClickType clickType, PlayerEntity playerEntity) { 27 | if (clickType != ClickType.RIGHT) return false; 28 | ItemStack target = slot.getStack(); 29 | NbtCompound nbt = itemStack.getSubNbt(STORED_ITEM_KEY); 30 | if (target.isEmpty()) { 31 | if (nbt == null) return super.onStackClicked(itemStack, slot, clickType, playerEntity); 32 | ItemStack stored = getStoredStack(itemStack); 33 | if (stored == ItemStack.EMPTY || !slot.canInsert(stored)) { 34 | return super.onStackClicked(itemStack, slot, clickType, playerEntity); 35 | } 36 | ItemStack e = slot.insertStack(stored); 37 | storeItemStack(itemStack, e, e.getCount()); 38 | this.playRemoveOneSound(playerEntity); 39 | return true; 40 | } 41 | if (nbt == null) { 42 | if (!canHold(target)) return super.onStackClicked(itemStack, slot, clickType, playerEntity); 43 | storeItemStack(itemStack, target, target.getCount()); 44 | playInsertSound(playerEntity); 45 | return true; 46 | } else { 47 | ItemStack stored = ItemStack.fromNbt(nbt); 48 | if (ItemStack.canCombine(stored, target)) { 49 | mergeStored(itemStack, playerEntity, target, stored); 50 | return true; 51 | } 52 | } 53 | return super.onStackClicked(itemStack, slot, clickType, playerEntity); 54 | } 55 | 56 | @Override 57 | public boolean onClicked(ItemStack itemStack, ItemStack target, Slot slot, ClickType type, PlayerEntity player, StackReference reference) { 58 | if (type != ClickType.RIGHT ||! slot.canTakePartial(player)) { 59 | return super.onClicked(itemStack, target, slot, type, player, reference); 60 | } 61 | NbtCompound nbt = itemStack.getSubNbt(STORED_ITEM_KEY); 62 | if (target.isEmpty()) { 63 | ItemStack stored = getStoredStack(itemStack); 64 | if (nbt == null) return super.onClicked(itemStack, target, slot, type, player, reference); 65 | if (reference.set(stored)) { 66 | storeItemStack(itemStack, null, 0); 67 | playRemoveOneSound(player); 68 | return true; 69 | } 70 | return super.onClicked(itemStack, target, slot, type, player, reference); 71 | } 72 | if (nbt == null) { 73 | if (!canHold(target)) return super.onClicked(itemStack, target, slot, type, player, reference); 74 | int amount = Math.min(target.getCount(), target.getItem().getMaxCount()); 75 | storeItemStack(itemStack, target, amount); 76 | playInsertSound(player); 77 | return true; 78 | } 79 | ItemStack stored = ItemStack.fromNbt(nbt); 80 | if (!ItemStack.canCombine(stored, target)) { 81 | return super.onClicked(itemStack, target, slot, type, player, reference); 82 | } 83 | mergeStored(itemStack, player, target, stored); 84 | return true; 85 | } 86 | 87 | @Override 88 | public Optional getTooltipData(ItemStack itemStack) { 89 | ItemStack stored = getStoredStack(itemStack); 90 | if (stored == ItemStack.EMPTY) { 91 | return Optional.empty(); 92 | } 93 | return Optional.of(new CuddlyContainerTooltipData(stored)); 94 | } 95 | 96 | @Override 97 | public boolean canBeNested() { 98 | return false; 99 | } 100 | 101 | @Override 102 | public boolean hasGlint(ItemStack itemStack) { 103 | return super.hasGlint(((ItemStackProvider) itemStack).blahaj$getStack()); 104 | } 105 | 106 | public ItemStack getContainedStack(ItemStack stack) { 107 | return getStoredStack(stack); 108 | } 109 | 110 | public TagKey usableContainedItemTag() { 111 | return Blahaj.BLAVINGAD_USABLE_ITEMS; 112 | } 113 | 114 | @SuppressWarnings("UnusedReturnValue") 115 | public Optional extract(ItemStack stack) { 116 | stack = ((ItemStackProvider) stack).blahaj$getStack(); 117 | NbtCompound nbt = stack.getNbt(); 118 | if (nbt == null) { 119 | return Optional.empty(); 120 | } 121 | nbt = stack.getSubNbt(STORED_ITEM_KEY); 122 | if (nbt == null) { 123 | return Optional.empty(); 124 | } 125 | stack.removeSubNbt(STORED_ITEM_KEY); 126 | return Optional.ofNullable(ItemStack.fromNbt(nbt)); 127 | } 128 | 129 | @SuppressWarnings("UnusedReturnValue") 130 | public boolean setContent(ItemStack itemStack, ItemStack target) { 131 | storeItemStack(itemStack, target, target.getCount()); 132 | return true; 133 | } 134 | 135 | protected void mergeStored(ItemStack itemStack, PlayerEntity playerEntity, ItemStack target, ItemStack stored) { 136 | int acc = target.getCount(); 137 | int in = stored.getCount(); 138 | int t = acc + in; 139 | int m = stored.getMaxCount(); 140 | if (t >= m) { 141 | storeItemStack(itemStack, stored, m); 142 | target.setCount(acc - (m - in)); 143 | } else { 144 | storeItemStack(itemStack, stored, t); 145 | target.setCount(0); 146 | } 147 | playInsertSound(playerEntity); 148 | } 149 | 150 | public static ItemStack getStoredStack(ItemStack stack) { 151 | stack = ((ItemStackProvider) stack).blahaj$getStack(); 152 | NbtCompound nbt = stack.getSubNbt(STORED_ITEM_KEY); 153 | if (nbt == null) { 154 | return ItemStack.EMPTY; 155 | } 156 | return ItemStack.fromNbt(nbt); 157 | } 158 | 159 | @SuppressWarnings("BooleanMethodIsAlwaysInverted") 160 | public boolean canHold(ItemStack stack) { 161 | stack = ((ItemStackProvider) stack).blahaj$getStack(); 162 | return !stack.isEmpty() && stack.getItem().canBeNested() && !stack.isIn(Blahaj.NON_CONTAINABLE_ITEMS); 163 | } 164 | 165 | public static void storeItemStack(ItemStack container, ItemStack target, int q) { 166 | container = ((ItemStackProvider) container).blahaj$getStack(); 167 | NbtCompound nbt = container.getOrCreateNbt(); 168 | if (target == null || target.isEmpty() || q <= 0) { 169 | nbt.remove(STORED_ITEM_KEY); 170 | } else { 171 | ItemStack e = target.copy(); 172 | e.setCount(q); 173 | nbt.put(STORED_ITEM_KEY, e.writeNbt(new NbtCompound())); 174 | target.setCount(target.getCount()-q); 175 | } 176 | } 177 | 178 | protected void playRemoveOneSound(Entity entity) { 179 | entity.playSound(SoundEvents.ITEM_BUNDLE_REMOVE_ONE, 0.8f, 0.8f + entity.getWorld().getRandom().nextFloat() * 0.4f); 180 | } 181 | 182 | protected void playInsertSound(Entity entity) { 183 | entity.playSound(SoundEvents.ITEM_BUNDLE_INSERT, 0.8f, 0.8f + entity.getWorld().getRandom().nextFloat() * 0.4f); 184 | } 185 | 186 | } 187 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/item/ItemStackProvider.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.item; 2 | 3 | import net.minecraft.item.ItemStack; 4 | 5 | @FunctionalInterface 6 | public interface ItemStackProvider { 7 | ItemStack blahaj$getStack(); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/item/nbt/ContainedNbtByteArray.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.item.nbt; 2 | 3 | import net.minecraft.nbt.NbtByte; 4 | import net.minecraft.nbt.NbtByteArray; 5 | import net.minecraft.nbt.NbtElement; 6 | import net.minecraft.nbt.scanner.NbtScanner; 7 | import net.minecraft.nbt.visitor.NbtElementVisitor; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | import java.util.Arrays; 11 | import java.util.HashSet; 12 | import java.util.Set; 13 | import java.util.function.Consumer; 14 | 15 | public class ContainedNbtByteArray extends NbtByteArray implements ContainedNbtElement { 16 | @NotNull private final NbtByteArray containedArray; 17 | @NotNull private final Set>> dirtyListeners; 18 | private boolean modified; 19 | private boolean busy; 20 | 21 | @SuppressWarnings("UseBulkOperation") 22 | public ContainedNbtByteArray(NbtByteArray nbtByteArray, Consumer>... listeners) { 23 | super(new byte[0]); 24 | this.containedArray = nbtByteArray; 25 | this.dirtyListeners = new HashSet<>(); 26 | this.modified = false; 27 | this.busy = false; 28 | Arrays.stream(listeners).forEach(this.dirtyListeners::add); 29 | } 30 | 31 | @Override 32 | public void dirty() { 33 | this.modified = true; 34 | if (this.busy) return; 35 | this.busy = true; 36 | this.dirtyListeners.forEach(listener -> listener.accept(this)); 37 | this.busy = false; 38 | } 39 | 40 | @Override 41 | public void clean() { 42 | this.modified = false; 43 | } 44 | 45 | @Override 46 | public NbtByteArray getContained() { 47 | return this.containedArray; 48 | } 49 | 50 | @Override 51 | public boolean isDirty() { 52 | return this.modified; 53 | } 54 | 55 | @Override 56 | @SuppressWarnings("unchecked") 57 | public Consumer>[] getListeners() { 58 | return this.dirtyListeners.toArray(Consumer[]::new); 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return this.containedArray.toString(); 64 | } 65 | 66 | @Override 67 | public NbtElement copy() { 68 | return this.containedArray.copy(); 69 | } 70 | 71 | @Override 72 | public boolean equals(Object object) { 73 | return this.containedArray.equals(object); 74 | } 75 | 76 | @Override 77 | public int hashCode() { 78 | return this.containedArray.hashCode(); 79 | } 80 | 81 | @Override 82 | public void accept(NbtElementVisitor nbtElementVisitor) { 83 | this.containedArray.accept(nbtElementVisitor); 84 | } 85 | 86 | @Override 87 | public byte[] getByteArray() { 88 | return this.containedArray.getByteArray(); 89 | } 90 | 91 | @Override 92 | public int size() { 93 | return this.containedArray.size(); 94 | } 95 | 96 | @Override 97 | public NbtByte get(int i) { 98 | return this.containedArray.get(i); 99 | } 100 | 101 | @Override 102 | public NbtByte set(int i, NbtByte nbtByte) { 103 | NbtByte result = this.containedArray.set(i, nbtByte); 104 | this.dirty(); 105 | return result; 106 | } 107 | 108 | @Override 109 | public void method_10531(int i, NbtByte nbtByte) { 110 | this.containedArray.method_10531(i, nbtByte); 111 | this.dirty(); 112 | } 113 | 114 | @Override 115 | public boolean setElement(int i, NbtElement nbtElement) { 116 | boolean result = this.containedArray.setElement(i, nbtElement); 117 | if (result) this.dirty(); 118 | return result; 119 | } 120 | 121 | @Override 122 | public boolean addElement(int i, NbtElement nbtElement) { 123 | boolean result = this.containedArray.addElement(i, nbtElement); 124 | if (result) this.dirty(); 125 | return result; 126 | } 127 | 128 | @Override 129 | public NbtByte method_10536(int i) { 130 | NbtByte result = this.containedArray.method_10536(i); 131 | this.dirty(); 132 | return result; 133 | } 134 | 135 | @Override 136 | public void clear() { 137 | this.containedArray.clear(); 138 | this.dirty(); 139 | } 140 | 141 | @Override 142 | public NbtScanner.Result doAccept(NbtScanner nbtScanner) { 143 | NbtScanner.Result result = this.containedArray.doAccept(nbtScanner); 144 | this.dirty(); 145 | return result; 146 | } 147 | 148 | @Override 149 | public void add(int i, NbtByte nbtElement) { 150 | this.containedArray.add(i, nbtElement); 151 | this.dirty(); 152 | } 153 | 154 | @Override 155 | public NbtByte remove(int i) { 156 | NbtByte result = this.containedArray.remove(i); 157 | this.dirty(); 158 | return result; 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/item/nbt/ContainedNbtCompound.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.item.nbt; 2 | 3 | import net.minecraft.nbt.NbtCompound; 4 | import net.minecraft.nbt.NbtElement; 5 | import net.minecraft.nbt.NbtList; 6 | import net.minecraft.nbt.scanner.NbtScanner; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | import java.util.*; 11 | import java.util.function.Consumer; 12 | 13 | public class ContainedNbtCompound extends NbtCompound implements ContainedNbtElement { 14 | @NotNull private final NbtCompound containedCompound; 15 | @NotNull private final Set>> dirtyListeners; 16 | private boolean modified; 17 | private boolean busy; 18 | 19 | @SuppressWarnings("UseBulkOperation") // lmfao shut up with "Arrays.asList", it is literally useless computation 20 | public ContainedNbtCompound(@NotNull NbtCompound containedNbtCompound, Consumer>... listeners) { 21 | super(); 22 | this.containedCompound = containedNbtCompound; 23 | this.dirtyListeners = new HashSet<>(); 24 | this.modified = false; 25 | this.busy = false; 26 | Arrays.stream(listeners).forEach(this.dirtyListeners::add); 27 | } 28 | 29 | @Override 30 | public final void dirty() { 31 | this.modified = true; 32 | if (this.busy) return; 33 | this.busy = true; 34 | this.dirtyListeners.forEach(listener -> listener.accept(this)); 35 | this.busy = false; 36 | } 37 | 38 | @Override 39 | public void clean() { 40 | this.modified = false; 41 | } 42 | 43 | @Override 44 | public NbtCompound getContained() { 45 | return this.containedCompound; 46 | } 47 | 48 | @Override 49 | public boolean isDirty() { 50 | return this.modified; 51 | } 52 | 53 | @Override 54 | @SuppressWarnings("unchecked") 55 | public Consumer>[] getListeners() { 56 | return this.dirtyListeners.toArray(Consumer[]::new); 57 | } 58 | 59 | @Override 60 | public Set getKeys() { 61 | return this.containedCompound.getKeys(); 62 | } 63 | 64 | @Override 65 | public int getSize() { 66 | return this.containedCompound.getSize(); 67 | } 68 | 69 | @Nullable 70 | @Override 71 | public NbtElement put(String string, NbtElement nbtElement) { 72 | NbtElement result = this.containedCompound.put(string, nbtElement); 73 | this.dirty(); 74 | return result; 75 | } 76 | 77 | @Override 78 | public void putByte(String string, byte b) { 79 | this.containedCompound.putByte(string, b); 80 | this.dirty(); 81 | } 82 | 83 | @Override 84 | public void putShort(String string, short s) { 85 | this.containedCompound.putShort(string, s); 86 | this.dirty(); 87 | } 88 | 89 | @Override 90 | public void putInt(String string, int i) { 91 | this.containedCompound.putInt(string, i); 92 | this.dirty(); 93 | } 94 | 95 | @Override 96 | public void putLong(String string, long l) { 97 | this.containedCompound.putLong(string, l); 98 | this.dirty(); 99 | } 100 | 101 | @Override 102 | public void putUuid(String string, UUID uUID) { 103 | this.containedCompound.putUuid(string, uUID); 104 | this.dirty(); 105 | } 106 | 107 | @Override 108 | public UUID getUuid(String string) { 109 | return this.containedCompound.getUuid(string); 110 | } 111 | 112 | @Override 113 | public boolean containsUuid(String string) { 114 | return this.containedCompound.containsUuid(string); 115 | } 116 | 117 | @Override 118 | public void putFloat(String string, float f) { 119 | this.containedCompound.putFloat(string, f); 120 | this.dirty(); 121 | } 122 | 123 | @Override 124 | public void putDouble(String string, double d) { 125 | this.containedCompound.putDouble(string, d); 126 | this.dirty(); 127 | } 128 | 129 | @Override 130 | public void putString(String string, String string2) { 131 | this.containedCompound.putString(string, string2); 132 | this.dirty(); 133 | } 134 | 135 | @Override 136 | public void putByteArray(String string, byte[] bs) { 137 | this.containedCompound.putByteArray(string, bs); 138 | this.dirty(); 139 | } 140 | 141 | @Override 142 | public void putByteArray(String string, List list) { 143 | this.containedCompound.putByteArray(string, list); 144 | this.dirty(); 145 | } 146 | 147 | @Override 148 | public void putIntArray(String string, int[] is) { 149 | this.containedCompound.putIntArray(string, is); 150 | this.dirty(); 151 | } 152 | 153 | @Override 154 | public void putIntArray(String string, List list) { 155 | this.containedCompound.putIntArray(string, list); 156 | this.dirty(); 157 | } 158 | 159 | @Override 160 | public void putLongArray(String string, long[] ls) { 161 | this.containedCompound.putLongArray(string, ls); 162 | this.dirty(); 163 | } 164 | 165 | @Override 166 | public void putLongArray(String string, List list) { 167 | this.containedCompound.putLongArray(string, list); 168 | this.dirty(); 169 | } 170 | 171 | @Override 172 | public void putBoolean(String string, boolean bl) { 173 | this.containedCompound.putBoolean(string, bl); 174 | this.dirty(); 175 | } 176 | 177 | @Nullable 178 | @Override 179 | public NbtElement get(String string) { 180 | return ContainedNbtElement.getContained(this.containedCompound.get(string), this.getListeners()); 181 | } 182 | 183 | @Override 184 | public byte getType(String string) { 185 | return this.containedCompound.getType(string); 186 | } 187 | 188 | @Override 189 | public boolean contains(String string) { 190 | return this.containedCompound.contains(string); 191 | } 192 | 193 | @Override 194 | public boolean contains(String string, int i) { 195 | return this.containedCompound.contains(string, i); 196 | } 197 | 198 | @Override 199 | public byte getByte(String string) { 200 | return this.containedCompound.getByte(string); 201 | } 202 | 203 | @Override 204 | public short getShort(String string) { 205 | return this.containedCompound.getShort(string); 206 | } 207 | 208 | @Override 209 | public int getInt(String string) { 210 | return this.containedCompound.getInt(string); 211 | } 212 | 213 | @Override 214 | public long getLong(String string) { 215 | return this.containedCompound.getLong(string); 216 | } 217 | 218 | @Override 219 | public float getFloat(String string) { 220 | return this.containedCompound.getFloat(string); 221 | } 222 | 223 | @Override 224 | public double getDouble(String string) { 225 | return this.containedCompound.getDouble(string); 226 | } 227 | 228 | @Override 229 | public String getString(String string) { 230 | return this.containedCompound.getString(string); 231 | } 232 | 233 | @Override 234 | public byte[] getByteArray(String string) { 235 | return this.containedCompound.getByteArray(string); 236 | } 237 | 238 | @Override 239 | public int[] getIntArray(String string) { 240 | return this.containedCompound.getIntArray(string); 241 | } 242 | 243 | @Override 244 | public long[] getLongArray(String string) { 245 | return this.containedCompound.getLongArray(string); 246 | } 247 | 248 | @Override 249 | public NbtCompound getCompound(String string) { 250 | return this.containedCompound.getCompound(string); 251 | } 252 | 253 | @Override 254 | public NbtList getList(String string, int i) { 255 | return new ContainedNbtList(this.containedCompound.getList(string, i), this.getListeners()); 256 | } 257 | 258 | @Override 259 | public boolean getBoolean(String string) { 260 | return this.containedCompound.getBoolean(string); 261 | } 262 | 263 | @Override 264 | public void remove(String string) { 265 | this.containedCompound.remove(string); 266 | this.dirty(); 267 | } 268 | 269 | @Override 270 | public String toString() { 271 | return this.containedCompound.toString(); 272 | } 273 | 274 | @Override 275 | public boolean isEmpty() { 276 | return this.containedCompound.isEmpty(); 277 | } 278 | 279 | @Override 280 | public NbtCompound copy() { 281 | return this.containedCompound.copy(); 282 | } 283 | 284 | @Override 285 | public boolean equals(Object object) { 286 | return this.containedCompound.equals(object); 287 | } 288 | 289 | @Override 290 | public int hashCode() { 291 | return this.containedCompound.hashCode(); 292 | } 293 | 294 | @Override 295 | public NbtCompound copyFrom(NbtCompound nbtCompound) { 296 | this.containedCompound.copyFrom(nbtCompound); 297 | this.dirty(); 298 | return this; 299 | } 300 | 301 | @Override 302 | public void accept(NbtScanner nbtScanner) { 303 | this.containedCompound.accept(nbtScanner); 304 | this.dirty(); 305 | } 306 | 307 | @Override 308 | public NbtScanner.Result doAccept(NbtScanner nbtScanner) { 309 | return this.containedCompound.doAccept(nbtScanner); 310 | } 311 | } 312 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/item/nbt/ContainedNbtElement.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.item.nbt; 2 | 3 | import net.minecraft.nbt.*; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public interface ContainedNbtElement { 8 | void clean(); 9 | void dirty(); 10 | T getContained(); 11 | boolean isDirty(); 12 | Consumer>[] getListeners(); 13 | 14 | @SuppressWarnings("unchecked") 15 | static U getContained(U element, Consumer>... listeners) { 16 | if (element instanceof ContainedNbtElement contained) { 17 | return (U) contained; 18 | } 19 | if (element instanceof NbtByteArray byteArray) { 20 | return (U) new ContainedNbtByteArray(byteArray, listeners); 21 | } 22 | if (element instanceof NbtCompound compound) { 23 | return (U) new ContainedNbtCompound(compound, listeners); 24 | } 25 | if (element instanceof NbtIntArray intArray) { 26 | return (U) new ContainedNbtIntArray(intArray, listeners); 27 | } 28 | if (element instanceof NbtList list) { 29 | return (U) new ContainedNbtList(list, listeners); 30 | } 31 | if (element instanceof NbtLongArray longArray) { 32 | return (U) new ContainedNbtLongArray(longArray, listeners); 33 | } 34 | return element; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/item/nbt/ContainedNbtIntArray.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.item.nbt; 2 | 3 | import net.minecraft.nbt.NbtElement; 4 | import net.minecraft.nbt.NbtInt; 5 | import net.minecraft.nbt.NbtIntArray; 6 | import net.minecraft.nbt.visitor.NbtElementVisitor; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import java.util.Arrays; 10 | import java.util.HashSet; 11 | import java.util.Set; 12 | import java.util.function.Consumer; 13 | 14 | public class ContainedNbtIntArray extends NbtIntArray implements ContainedNbtElement { 15 | @NotNull private final NbtIntArray containedArray; 16 | @NotNull private final Set>> dirtyListeners; 17 | private boolean modified; 18 | private boolean busy; 19 | 20 | @SuppressWarnings("UseBulkOperation") 21 | public ContainedNbtIntArray(NbtIntArray nbtIntArray, Consumer>... listeners) { 22 | super(new int[0]); 23 | this.containedArray = nbtIntArray; 24 | this.dirtyListeners = new HashSet<>(); 25 | this.modified = false; 26 | this.busy = false; 27 | Arrays.stream(listeners).forEach(this.dirtyListeners::add); 28 | } 29 | 30 | @Override 31 | public void dirty() { 32 | this.modified = true; 33 | if (this.busy) return; 34 | this.busy = true; 35 | this.dirtyListeners.forEach(listener -> listener.accept(this)); 36 | this.busy = false; 37 | } 38 | 39 | @Override 40 | public void clean() { 41 | this.modified = false; 42 | } 43 | 44 | @Override 45 | public NbtIntArray getContained() { 46 | return this.containedArray; 47 | } 48 | 49 | @Override 50 | public boolean isDirty() { 51 | return this.modified; 52 | } 53 | 54 | @Override 55 | @SuppressWarnings("unchecked") 56 | public Consumer>[] getListeners() { 57 | return this.dirtyListeners.toArray(Consumer[]::new); 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return this.containedArray.toString(); 63 | } 64 | 65 | @Override 66 | public NbtIntArray copy() { 67 | return this.containedArray.copy(); 68 | } 69 | 70 | @Override 71 | public boolean equals(Object object) { 72 | return this.containedArray.equals(object); 73 | } 74 | 75 | @Override 76 | public int hashCode() { 77 | return this.containedArray.hashCode(); 78 | } 79 | 80 | @Override 81 | public void accept(NbtElementVisitor nbtElementVisitor) { 82 | this.containedArray.accept(nbtElementVisitor); 83 | } 84 | 85 | @Override 86 | public int[] getIntArray() { 87 | return this.containedArray.getIntArray(); 88 | } 89 | 90 | @Override 91 | public int size() { 92 | return this.containedArray.size(); 93 | } 94 | 95 | @Override 96 | public NbtInt get(int i) { 97 | return this.containedArray.get(i); 98 | } 99 | 100 | @Override 101 | public NbtInt set(int i, NbtInt nbtInt) { 102 | NbtInt result = this.containedArray.set(i, nbtInt); 103 | this.dirty(); 104 | return result; 105 | } 106 | 107 | @Override 108 | public void add(int i, NbtInt nbtInt) { 109 | this.containedArray.add(i, nbtInt); 110 | this.dirty(); 111 | } 112 | 113 | @Override 114 | public boolean setElement(int i, NbtElement nbtElement) { 115 | boolean result = this.containedArray.setElement(i, nbtElement); 116 | if (result) this.dirty(); 117 | return result; 118 | } 119 | 120 | @Override 121 | public boolean addElement(int i, NbtElement nbtElement) { 122 | boolean result = this.containedArray.addElement(i, nbtElement); 123 | if (result) this.dirty(); 124 | return result; 125 | } 126 | 127 | @Override 128 | public void clear() { 129 | this.containedArray.clear(); 130 | this.dirty(); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/item/nbt/ContainedNbtList.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.item.nbt; 2 | 3 | import net.minecraft.nbt.NbtCompound; 4 | import net.minecraft.nbt.NbtElement; 5 | import net.minecraft.nbt.NbtList; 6 | import net.minecraft.nbt.scanner.NbtScanner; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import java.util.Arrays; 10 | import java.util.HashSet; 11 | import java.util.Set; 12 | import java.util.function.Consumer; 13 | 14 | public class ContainedNbtList extends NbtList implements ContainedNbtElement { 15 | @NotNull private final NbtList containedList; 16 | @NotNull private final Set>> dirtyListeners; 17 | private boolean modified; 18 | private boolean busy; 19 | 20 | @SuppressWarnings("UseBulkOperation") 21 | public ContainedNbtList(NbtList containedNbtList, Consumer>... listeners) { 22 | super(); 23 | this.containedList = containedNbtList; 24 | this.dirtyListeners = new HashSet<>(); 25 | this.modified = false; 26 | this.busy = false; 27 | Arrays.stream(listeners).forEach(this.dirtyListeners::add); 28 | } 29 | 30 | @Override 31 | public final void dirty() { 32 | this.modified = true; 33 | if (this.busy) return; 34 | this.busy = true; 35 | this.dirtyListeners.forEach(listener -> listener.accept(this)); 36 | this.busy = false; 37 | } 38 | 39 | @Override 40 | public void clean() { 41 | this.modified = false; 42 | } 43 | 44 | @Override 45 | public NbtList getContained() { 46 | return this.containedList; 47 | } 48 | 49 | @Override 50 | public boolean isDirty() { 51 | return this.modified; 52 | } 53 | 54 | @Override 55 | @SuppressWarnings("unchecked") 56 | public Consumer>[] getListeners() { 57 | return this.dirtyListeners.toArray(Consumer[]::new); 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return this.containedList.toString(); 63 | } 64 | 65 | @Override 66 | public NbtElement remove(int i) { 67 | NbtElement result = this.containedList.remove(i); 68 | this.dirty(); 69 | return result; 70 | } 71 | 72 | @Override 73 | public boolean isEmpty() { 74 | return this.containedList.isEmpty(); 75 | } 76 | 77 | @Override 78 | public NbtCompound getCompound(int i) { 79 | return new ContainedNbtCompound(this.containedList.getCompound(i), this.getListeners()); 80 | } 81 | 82 | @Override 83 | public NbtList getList(int i) { 84 | return new ContainedNbtList(this.containedList.getList(i), this.getListeners()); 85 | } 86 | 87 | @Override 88 | public short getShort(int i) { 89 | return this.containedList.getShort(i); 90 | } 91 | 92 | @Override 93 | public int getInt(int i) { 94 | return this.containedList.getInt(i); 95 | } 96 | 97 | @Override 98 | public int[] getIntArray(int i) { 99 | return this.containedList.getIntArray(i); 100 | } 101 | 102 | @Override 103 | public long[] getLongArray(int i) { 104 | return this.containedList.getLongArray(i); 105 | } 106 | 107 | @Override 108 | public double getDouble(int i) { 109 | return this.containedList.getDouble(i); 110 | } 111 | 112 | @Override 113 | public float getFloat(int i) { 114 | return this.containedList.getFloat(i); 115 | } 116 | 117 | @Override 118 | public String getString(int i) { 119 | return this.containedList.getString(i); 120 | } 121 | 122 | @Override 123 | public int size() { 124 | return this.containedList.size(); 125 | } 126 | 127 | @Override 128 | public NbtElement get(int i) { 129 | return ContainedNbtElement.getContained(this.containedList.get(i), this.getListeners()); 130 | } 131 | 132 | @Override 133 | public NbtElement set(int i, NbtElement nbtElement) { 134 | NbtElement result = this.containedList.set(i, nbtElement); 135 | this.dirty(); 136 | return result; 137 | } 138 | 139 | @Override 140 | public void add(int i, NbtElement nbtElement) { 141 | this.containedList.add(i, nbtElement); 142 | this.dirty(); 143 | } 144 | 145 | @Override 146 | public boolean setElement(int i, NbtElement nbtElement) { 147 | boolean result = this.containedList.setElement(i, nbtElement); 148 | if (result) this.dirty(); 149 | return result; 150 | } 151 | 152 | @Override 153 | public boolean addElement(int i, NbtElement nbtElement) { 154 | boolean result = this.containedList.addElement(i, nbtElement); 155 | if (result) this.dirty(); 156 | return result; 157 | } 158 | 159 | @Override 160 | public NbtList copy() { 161 | //TODO watch for potential need to make it contained 162 | return this.containedList.copy(); 163 | } 164 | 165 | @Override 166 | public boolean equals(Object object) { 167 | return this.containedList.equals(object); 168 | } 169 | 170 | @Override 171 | public int hashCode() { 172 | return this.containedList.hashCode(); 173 | } 174 | 175 | @Override 176 | public void accept(NbtScanner nbtScanner) { 177 | this.containedList.accept(nbtScanner); 178 | this.dirty(); 179 | } 180 | 181 | @Override 182 | public void clear() { 183 | this.containedList.clear(); 184 | this.dirty(); 185 | } 186 | 187 | @Override 188 | public NbtScanner.Result doAccept(NbtScanner nbtScanner) { 189 | NbtScanner.Result result = this.containedList.doAccept(nbtScanner); 190 | this.dirty(); 191 | return result; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/item/nbt/ContainedNbtLongArray.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.item.nbt; 2 | 3 | import net.minecraft.nbt.NbtElement; 4 | import net.minecraft.nbt.NbtLong; 5 | import net.minecraft.nbt.NbtLongArray; 6 | import net.minecraft.nbt.scanner.NbtScanner; 7 | import net.minecraft.nbt.visitor.NbtElementVisitor; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | import java.util.Arrays; 11 | import java.util.HashSet; 12 | import java.util.Set; 13 | import java.util.function.Consumer; 14 | 15 | public class ContainedNbtLongArray extends NbtLongArray implements ContainedNbtElement { 16 | @NotNull private final NbtLongArray containedArray; 17 | @NotNull private final Set>> dirtyListeners; 18 | private boolean modified; 19 | private boolean busy; 20 | 21 | @SuppressWarnings("UseBulkOperation") 22 | public ContainedNbtLongArray(NbtLongArray nbtLongArray, Consumer>... listeners) { 23 | super(new long[0]); 24 | this.containedArray = nbtLongArray; 25 | this.dirtyListeners = new HashSet<>(); 26 | this.modified = false; 27 | this.busy = false; 28 | Arrays.stream(listeners).forEach(this.dirtyListeners::add); 29 | } 30 | 31 | @Override 32 | public void dirty() { 33 | this.modified = true; 34 | if (this.busy) return; 35 | this.busy = true; 36 | this.dirtyListeners.forEach(listener -> listener.accept(this)); 37 | this.busy = false; 38 | } 39 | 40 | @Override 41 | public void clean() { 42 | this.modified = false; 43 | } 44 | 45 | @Override 46 | public NbtLongArray getContained() { 47 | return this.containedArray; 48 | } 49 | 50 | @Override 51 | public boolean isDirty() { 52 | return this.modified; 53 | } 54 | 55 | @Override 56 | @SuppressWarnings("unchecked") 57 | public Consumer>[] getListeners() { 58 | return this.dirtyListeners.toArray(Consumer[]::new); 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return this.containedArray.toString(); 64 | } 65 | 66 | @Override 67 | public NbtLongArray copy() { 68 | return this.containedArray.copy(); 69 | } 70 | 71 | @Override 72 | public boolean equals(Object object) { 73 | return this.containedArray.equals(object); 74 | } 75 | 76 | @Override 77 | public int hashCode() { 78 | return this.containedArray.hashCode(); 79 | } 80 | 81 | @Override 82 | public void accept(NbtElementVisitor nbtElementVisitor) { 83 | this.containedArray.accept(nbtElementVisitor); 84 | } 85 | 86 | @Override 87 | public long[] getLongArray() { 88 | return this.containedArray.getLongArray(); 89 | } 90 | 91 | @Override 92 | public int size() { 93 | return this.containedArray.size(); 94 | } 95 | 96 | @Override 97 | public NbtLong get(int i) { 98 | return this.containedArray.get(i); 99 | } 100 | 101 | @Override 102 | public NbtLong method_10606(int i, NbtLong nbtLong) { 103 | NbtLong result = this.containedArray.method_10606(i, nbtLong); 104 | this.dirty(); 105 | return result; 106 | } 107 | 108 | @Override 109 | public void add(int i, NbtLong nbtLong) { 110 | this.containedArray.add(i, nbtLong); 111 | this.dirty(); 112 | } 113 | 114 | @Override 115 | public boolean setElement(int i, NbtElement nbtElement) { 116 | boolean result = this.containedArray.setElement(i, nbtElement); 117 | if (result) this.dirty(); 118 | return result; 119 | } 120 | 121 | @Override 122 | public boolean addElement(int i, NbtElement nbtElement) { 123 | boolean result = this.containedArray.addElement(i, nbtElement); 124 | if (result) this.dirty(); 125 | return result; 126 | } 127 | 128 | @Override 129 | public NbtLong remove(int i) { 130 | NbtLong result = this.containedArray.remove(i); 131 | this.dirty(); 132 | return result; 133 | } 134 | 135 | @Override 136 | public boolean add(NbtLong nbtLong) { 137 | boolean result = this.containedArray.add(nbtLong); 138 | if (result) this.dirty(); 139 | return result; 140 | } 141 | 142 | @Override 143 | public void clear() { 144 | this.containedArray.clear(); 145 | this.dirty(); 146 | } 147 | 148 | @Override 149 | public NbtScanner.Result doAccept(NbtScanner nbtScanner) { 150 | NbtScanner.Result result = this.containedArray.doAccept(nbtScanner); 151 | this.dirty(); 152 | return result; 153 | } 154 | 155 | @Override 156 | public NbtLong set(int i, NbtLong nbtElement) { 157 | NbtLong result = this.containedArray.set(i, nbtElement); 158 | this.dirty(); 159 | return result; 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/AnvilScreenHandlerMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import mc.recraftors.blahaj.item.CuddlyItem; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.nbt.NbtString; 6 | import net.minecraft.screen.AnvilScreenHandler; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | import org.spongepowered.asm.mixin.injection.callback.LocalCapture; 12 | 13 | @Mixin(AnvilScreenHandler.class) 14 | public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandlerMixin { 15 | @Inject( 16 | method = "updateResult", 17 | at = { 18 | @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;removeCustomName()V"), 19 | @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;setCustomName(Lnet/minecraft/text/Text;)Lnet/minecraft/item/ItemStack;") 20 | }, 21 | locals = LocalCapture.CAPTURE_FAILEXCEPTION, 22 | expect = 2, 23 | require = 2 24 | ) 25 | private void setNameInjection(CallbackInfo ci, ItemStack itemStack, int i, int j, int k, 26 | ItemStack itemStack2, ItemStack itemStack3) { 27 | if (itemStack2.getItem() instanceof CuddlyItem) { 28 | itemStack2.setSubNbt(CuddlyItem.OWNER_KEY, NbtString.of(player.getName().getString())); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/ClientPlayNetworkHandlerMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import com.llamalad7.mixinextras.injector.ModifyExpressionValue; 4 | import com.llamalad7.mixinextras.sugar.Local; 5 | import mc.recraftors.blahaj.item.HandItemStackProvider; 6 | import mc.recraftors.blahaj.item.ItemStackProvider; 7 | import net.fabricmc.api.EnvType; 8 | import net.fabricmc.api.Environment; 9 | import net.minecraft.client.network.ClientPlayNetworkHandler; 10 | import net.minecraft.entity.player.PlayerEntity; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.item.Items; 13 | import net.minecraft.util.Hand; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.injection.At; 16 | import org.spongepowered.asm.mixin.injection.Redirect; 17 | 18 | @Environment(EnvType.CLIENT) 19 | @Mixin(ClientPlayNetworkHandler.class) 20 | public abstract class ClientPlayNetworkHandlerMixin { 21 | @Redirect( 22 | method = "getActiveTotemOfUndying", 23 | at = @At( 24 | value = "INVOKE", 25 | target = "Lnet/minecraft/entity/player/PlayerEntity;getStackInHand(Lnet/minecraft/util/Hand;)Lnet/minecraft/item/ItemStack;" 26 | ) 27 | ) 28 | private static ItemStack getPossilbyContainerStackInHend(PlayerEntity player, Hand hand) { 29 | return ((HandItemStackProvider) player).blahaj$stackInHandFailSafe(hand); 30 | } 31 | 32 | @ModifyExpressionValue( 33 | method = "getActiveTotemOfUndying", 34 | at = @At( 35 | value = "INVOKE", 36 | target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" 37 | ) 38 | ) 39 | private static boolean getIsOfOrContainedIsOf(boolean original, @Local ItemStack itemStack) { 40 | return original || ! ((ItemStackProvider)itemStack).blahaj$getStack().isOf(Items.TOTEM_OF_UNDYING); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/EnchantmentMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import net.minecraft.enchantment.Enchantment; 4 | import net.minecraft.entity.EquipmentSlot; 5 | import net.minecraft.entity.LivingEntity; 6 | import net.minecraft.item.ItemStack; 7 | import net.minecraft.util.Hand; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 12 | 13 | import java.util.Map; 14 | 15 | @Mixin(Enchantment.class) 16 | public abstract class EnchantmentMixin { 17 | @Inject(method = "getEquipment", at = @At("RETURN")) 18 | private void handItemsInjector(LivingEntity entity, CallbackInfoReturnable> cir) { 19 | cir.getReturnValue().put(EquipmentSlot.MAINHAND, entity.getStackInHand(Hand.MAIN_HAND)); 20 | cir.getReturnValue().put(EquipmentSlot.OFFHAND, entity.getStackInHand(Hand.OFF_HAND)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/ForgingScreenHandlerMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import net.minecraft.entity.player.PlayerEntity; 4 | import net.minecraft.screen.ForgingScreenHandler; 5 | import org.spongepowered.asm.mixin.Final; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Shadow; 8 | 9 | @Mixin(ForgingScreenHandler.class) 10 | public abstract class ForgingScreenHandlerMixin { 11 | @Shadow 12 | protected @Final PlayerEntity player; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/ItemGroupsMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import mc.recraftors.blahaj.Blahaj; 4 | import net.minecraft.item.ItemGroup; 5 | import net.minecraft.item.ItemGroups; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(ItemGroups.class) 12 | public abstract class ItemGroupsMixin { 13 | @Inject(method = "method_51328", at = @At("RETURN")) 14 | private static void toolsGroupItemInject(ItemGroup.DisplayContext displayContext, ItemGroup.Entries entries, CallbackInfo ci) { 15 | Blahaj.getItems().forEach(entries::add); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/ItemMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import mc.recraftors.blahaj.item.ItemStackProvider; 4 | import net.minecraft.item.Item; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.ModifyArg; 8 | 9 | @Mixin(Item.class) 10 | public abstract class ItemMixin { 11 | @ModifyArg(method = "use", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/TypedActionResult;pass(Ljava/lang/Object;)Lnet/minecraft/util/TypedActionResult;")) 12 | private T containedItemStackFailsafeInjector(T initial) { 13 | return (T) ((ItemStackProvider) initial).blahaj$getStack(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/ItemStackMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import mc.recraftors.blahaj.item.ItemStackProvider; 4 | import net.minecraft.item.ItemStack; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | 7 | @Mixin(ItemStack.class) 8 | public abstract class ItemStackMixin implements ItemStackProvider { 9 | @Override 10 | public ItemStack blahaj$getStack() { 11 | return (ItemStack) ((Object) this); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/ItemsMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import mc.recraftors.blahaj.Blahaj; 4 | import mc.recraftors.blahaj.item.CuddlyItem; 5 | import mc.recraftors.blahaj.item.ItemContainerCuddlyItem; 6 | import net.minecraft.item.Item; 7 | import net.minecraft.item.Items; 8 | import net.minecraft.util.Identifier; 9 | import net.minecraft.util.Rarity; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.Shadow; 12 | import org.spongepowered.asm.mixin.injection.At; 13 | import org.spongepowered.asm.mixin.injection.Inject; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 15 | 16 | import static mc.recraftors.blahaj.Blahaj.*; 17 | 18 | @Mixin(Items.class) 19 | public abstract class ItemsMixin { 20 | @Shadow 21 | public static Item register(Identifier identifier, Item item) { 22 | return null; 23 | } 24 | 25 | @Inject(method = "", at = @At("TAIL")) 26 | private static void clinitTailInjector(CallbackInfo ci) { 27 | Item.Settings settings = new Item.Settings().maxCount(1).rarity(Rarity.RARE); 28 | 29 | Blahaj.storeItem(KLAPPAR_HAJ_ID, (CuddlyItem) register(KLAPPAR_HAJ_ID, new CuddlyItem(settings, String.format(TOOLTIP_PRE, KLAPPAR_HAJ_ID.getPath())))); 30 | Blahaj.storeItem(BLAHAJ_ID, (CuddlyItem) register(BLAHAJ_ID, new CuddlyItem(settings, String.format(TOOLTIP_PRE, BLAHAJ_ID.getPath())))); 31 | Blahaj.storeItem(BEYOU_BLAHAJ_ID, (CuddlyItem) register(BEYOU_BLAHAJ_ID, new CuddlyItem(settings, String.format(TOOLTIP_PRE, BEYOU_BLAHAJ_ID.getPath())))); 32 | Blahaj.storeItem(BLAVINGAD_ID, (CuddlyItem) register(BLAVINGAD_ID, new ItemContainerCuddlyItem(settings, String.format(TOOLTIP_PRE, BLAVINGAD_ID.getPath())))); 33 | Blahaj.storeItem(ORCA_HAJ_ID, (CuddlyItem) register(ORCA_HAJ_ID, new ItemContainerCuddlyItem(settings, String.format(TOOLTIP_PRE, ORCA_HAJ_ID.getPath())))); 34 | Blahaj.storeItem(BREAD_ID, (CuddlyItem) register(BREAD_ID, new CuddlyItem(settings, null))); 35 | Blahaj.storeItem(SEAL_ID, (CuddlyItem) register(SEAL_ID, new CuddlyItem(settings, String.format(TOOLTIP_PRE, SEAL_ID.getPath())))); 36 | register($k_O$8, new CuddlyItem(settings, String.format(TOOLTIP_PRE, $k_O$8.getPath()))); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/LivingEntityMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import mc.recraftors.blahaj.Blahaj; 4 | import mc.recraftors.blahaj.item.ContainedItemStack; 5 | import mc.recraftors.blahaj.item.HandItemStackProvider; 6 | import mc.recraftors.blahaj.item.ItemContainerCuddlyItem; 7 | import net.minecraft.advancement.criterion.Criteria; 8 | import net.minecraft.entity.Entity; 9 | import net.minecraft.entity.EntityType; 10 | import net.minecraft.entity.EquipmentSlot; 11 | import net.minecraft.entity.LivingEntity; 12 | import net.minecraft.entity.damage.DamageSource; 13 | import net.minecraft.entity.effect.StatusEffectInstance; 14 | import net.minecraft.entity.effect.StatusEffects; 15 | import net.minecraft.entity.player.PlayerEntity; 16 | import net.minecraft.item.ItemStack; 17 | import net.minecraft.item.Items; 18 | import net.minecraft.server.network.ServerPlayerEntity; 19 | import net.minecraft.stat.Stats; 20 | import net.minecraft.util.Hand; 21 | import net.minecraft.world.World; 22 | import org.spongepowered.asm.mixin.Mixin; 23 | import org.spongepowered.asm.mixin.Shadow; 24 | import org.spongepowered.asm.mixin.Unique; 25 | import org.spongepowered.asm.mixin.injection.At; 26 | import org.spongepowered.asm.mixin.injection.Inject; 27 | import org.spongepowered.asm.mixin.injection.Redirect; 28 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 29 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 30 | 31 | @Mixin(LivingEntity.class) 32 | public abstract class LivingEntityMixin extends Entity implements HandItemStackProvider { 33 | LivingEntityMixin(EntityType entityType, World world) { 34 | super(entityType, world); 35 | } 36 | 37 | @Shadow public abstract void setHealth(float f); 38 | 39 | @Shadow public abstract boolean clearStatusEffects(); 40 | 41 | @Shadow public abstract boolean addStatusEffect(StatusEffectInstance statusEffectInstance); 42 | 43 | @Shadow public abstract ItemStack getEquippedStack(EquipmentSlot var1); 44 | 45 | @Shadow public abstract ItemStack getStackInHand(Hand hand); 46 | 47 | @Override 48 | public ItemStack blahaj$stackInHandFailSafe(Hand hand) { 49 | if (hand == Hand.MAIN_HAND) { 50 | return this.getEquippedStack(EquipmentSlot.MAINHAND); 51 | } 52 | if (hand == Hand.OFF_HAND) { 53 | return this.getEquippedStack(EquipmentSlot.OFFHAND); 54 | } 55 | throw new IllegalArgumentException("Invalid hand " + hand); 56 | } 57 | 58 | @Inject(method = "getStackInHand", at = @At("RETURN"), cancellable = true) 59 | private void onGetStackInHandReturnInjector(Hand hand, CallbackInfoReturnable cir) { 60 | if (!this.getWorld().getGameRules().getBoolean(Blahaj.ENABLE_CONTAINER_USE)) return; 61 | ItemStack stack = cir.getReturnValue(); 62 | if (stack.getItem() instanceof ItemContainerCuddlyItem cuddly) { 63 | ItemStack content = cuddly.getContainedStack(stack); 64 | if (content.isIn(cuddly.usableContainedItemTag())) { 65 | cir.setReturnValue(new ContainedItemStack(stack, content)); 66 | } 67 | } 68 | } 69 | 70 | @Inject(method = "setStackInHand", at = @At("HEAD"), cancellable = true) 71 | private void onSetStackInHandHeadInjector(Hand hand, ItemStack itemStack, CallbackInfo ci) { 72 | ItemStack stack = getStackInHand(hand); 73 | if (stack instanceof ContainedItemStack containedStack) { 74 | ci.cancel(); 75 | blahaj$idkSetStackInHand(this, containedStack, itemStack); 76 | } 77 | } 78 | 79 | @Unique 80 | private static void blahaj$idkSetStackInHand(Entity entity, ContainedItemStack stack1, ItemStack stack2) { 81 | if (!(entity instanceof PlayerEntity player)) return; 82 | if (player.isCreative()) return; 83 | stack1.tryInsertOrDrop(player, stack2); 84 | } 85 | 86 | @Redirect(method = "swapHandStacks", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;getEquippedStack(Lnet/minecraft/entity/EquipmentSlot;)Lnet/minecraft/item/ItemStack;")) 87 | private ItemStack handSwapStackGetRedirector(LivingEntity instance, EquipmentSlot equipmentSlot) { 88 | return switch (equipmentSlot) { 89 | case MAINHAND -> blahaj$stackInHandFailSafe(Hand.MAIN_HAND); 90 | case OFFHAND -> blahaj$stackInHandFailSafe(Hand.OFF_HAND); 91 | default -> ItemStack.EMPTY; 92 | }; 93 | } 94 | 95 | @SuppressWarnings("ConstantValue") 96 | @Inject(method = "tryUseTotem", at = @At("TAIL"), cancellable = true) 97 | private void tryUseTotemTryUseContainedTotemInjector(DamageSource damageSource, CallbackInfoReturnable cir) { 98 | if (cir.getReturnValueZ()) return; 99 | ItemStack stack = null; 100 | ItemStack stack2 = null; 101 | for (Hand hand : Hand.values()) { 102 | ItemStack handStack = blahaj$stackInHandFailSafe(hand); 103 | if (!(handStack.getItem() instanceof ItemContainerCuddlyItem cuddly)) continue; 104 | ItemStack contained = cuddly.getContainedStack(handStack); 105 | if (contained.isOf(Items.TOTEM_OF_UNDYING)) { 106 | stack = handStack; 107 | stack2 = contained; 108 | if (!(((Object)this) instanceof PlayerEntity player && player.isCreative())) { 109 | cuddly.extract(handStack); 110 | } 111 | break; 112 | } 113 | } 114 | if (stack == null) return; 115 | Object o = this; 116 | if (o instanceof ServerPlayerEntity player) { 117 | player.incrementStat(Stats.USED.getOrCreateStat(Items.TOTEM_OF_UNDYING)); 118 | Criteria.USED_TOTEM.trigger(player, stack2); 119 | } 120 | this.setHealth(1f); 121 | this.clearStatusEffects(); 122 | this.addStatusEffect(new StatusEffectInstance(StatusEffects.REGENERATION, 700, 0)); 123 | this.addStatusEffect(new StatusEffectInstance(StatusEffects.ABSORPTION, 100, 0)); 124 | this.addStatusEffect(new StatusEffectInstance(StatusEffects.FIRE_RESISTANCE, 500, 0)); 125 | this.getWorld().sendEntityStatus(this, (byte) 35); 126 | cir.setReturnValue(true); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/LootManagerMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import mc.recraftors.blahaj.Blahaj; 4 | import mc.recraftors.blahaj.item.CuddlyItem; 5 | import net.minecraft.item.Item; 6 | import net.minecraft.item.Items; 7 | import net.minecraft.loot.*; 8 | import net.minecraft.loot.entry.ItemEntry; 9 | import net.minecraft.util.Identifier; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.Shadow; 12 | import org.spongepowered.asm.mixin.Unique; 13 | import org.spongepowered.asm.mixin.injection.At; 14 | import org.spongepowered.asm.mixin.injection.Inject; 15 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 16 | 17 | import java.util.Map; 18 | import java.util.Optional; 19 | import java.util.function.Consumer; 20 | 21 | @Mixin(LootManager.class) 22 | public abstract class LootManagerMixin { 23 | @Shadow private Map, ?> keyToValue; 24 | 25 | @Inject(method = "validate(Ljava/util/Map;)V", at = @At("RETURN")) 26 | private void applyReturnInjector(Map, Map> map, CallbackInfo ci) { 27 | Optional klapparSupplier = Blahaj.itemSupplier(Blahaj.KLAPPAR_HAJ_ID); 28 | Optional blahajSupplier = Blahaj.itemSupplier(Blahaj.BLAHAJ_ID); 29 | this.keyToValue.forEach((key, o) -> { 30 | if (!(o instanceof LootTable table)) return; 31 | if (key.id().equals(LootTables.STRONGHOLD_CROSSING_CHEST) || key.id().equals(LootTables.STRONGHOLD_CORRIDOR_CHEST)) { 32 | klapparSupplier.ifPresent(klappar -> blahaj$tableInsert(table, klappar, 5, 100)); 33 | } else if (key.id().equals(LootTables.VILLAGE_PLAINS_CHEST)) { 34 | klapparSupplier.ifPresent(klappar -> blahaj$tableInsert(table, klappar, 1, 45)); 35 | } else if (key.id().equals(LootTables.VILLAGE_TAIGA_HOUSE_CHEST)) { 36 | klapparSupplier.ifPresent(klappar -> blahaj$tableInsert(table, klappar, 5, 60)); 37 | } else if (key.id().equals(LootTables.VILLAGE_SNOWY_HOUSE_CHEST)) { 38 | blahajSupplier.ifPresent(blahaj -> blahaj$tableInsert(table, blahaj, 5, 60)); 39 | } 40 | }); 41 | } 42 | 43 | @SuppressWarnings("unchecked") 44 | @Unique 45 | private static void blahaj$tableInsert(LootTable table, Item item, int weight, int total) { 46 | int i = table.pools.length; 47 | LootPool[] pools = new LootPool[i+1]; 48 | System.arraycopy(table.pools, 0, pools, 0, i); 49 | pools[i] = LootPool.builder().with(ItemEntry.builder(item).weight(weight)).with(ItemEntry.builder(Items.AIR).weight(total-weight)).build(); 50 | ((Consumer) table).accept(pools); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/LootTableMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import net.minecraft.loot.LootPool; 4 | import net.minecraft.loot.LootTable; 5 | import org.spongepowered.asm.mixin.Final; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Mutable; 8 | import org.spongepowered.asm.mixin.Shadow; 9 | 10 | import java.util.function.Consumer; 11 | 12 | @Mixin(LootTable.class) 13 | public abstract class LootTableMixin implements Consumer { 14 | @Mutable 15 | @Shadow @Final public LootPool[] pools; 16 | 17 | @Override 18 | public void accept(LootPool[] lootPools) { 19 | this.pools = lootPools; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/MinecraftServerMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import mc.recraftors.blahaj.Blahaj; 4 | import net.minecraft.server.MinecraftServer; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.Inject; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 9 | 10 | import java.util.Collection; 11 | import java.util.concurrent.CompletableFuture; 12 | 13 | @Mixin(MinecraftServer.class) 14 | public class MinecraftServerMixin { 15 | @Inject(method = "reloadResources", at = @At("TAIL")) 16 | private void reloadResourcesTailInjector(Collection dataPacks, CallbackInfoReturnable> cir) { 17 | Blahaj.injectTrades(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/RecipeManagerMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import com.google.gson.JsonArray; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonObject; 6 | import mc.recraftors.blahaj.Blahaj; 7 | import net.minecraft.item.Item; 8 | import net.minecraft.recipe.Recipe; 9 | import net.minecraft.recipe.RecipeManager; 10 | import net.minecraft.recipe.RecipeType; 11 | import net.minecraft.registry.Registries; 12 | import net.minecraft.registry.tag.ItemTags; 13 | import net.minecraft.resource.ResourceManager; 14 | import net.minecraft.util.Identifier; 15 | import net.minecraft.util.profiler.Profiler; 16 | import org.spongepowered.asm.mixin.Mixin; 17 | import org.spongepowered.asm.mixin.Shadow; 18 | import org.spongepowered.asm.mixin.Unique; 19 | import org.spongepowered.asm.mixin.injection.At; 20 | import org.spongepowered.asm.mixin.injection.Inject; 21 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 22 | 23 | import java.util.HashMap; 24 | import java.util.HashSet; 25 | import java.util.Map; 26 | import java.util.Set; 27 | 28 | @Mixin(RecipeManager.class) 29 | public class RecipeManagerMixin { 30 | @Shadow private Map, Map>> recipes; 31 | 32 | @Unique private static Set WOOL = new HashSet<>(); 33 | 34 | @Unique private static JsonObject randomBlahajGlitchRecipe() { 35 | JsonObject main = new JsonObject(); 36 | Identifier type = Registries.RECIPE_TYPE.getId(RecipeType.CRAFTING); 37 | if (type == null) { 38 | return null; 39 | } 40 | main.addProperty("type", type +"_shaped"); 41 | JsonArray pattern = new JsonArray(); 42 | pattern.add(" A "); 43 | pattern.add("B#C"); 44 | pattern.add("DE "); 45 | main.add("pattern", pattern); 46 | Map map = new HashMap<>(); 47 | for (int i = 'A'; i < 'F'; i++) { 48 | String key = Character.toString(i); 49 | boolean b = true; 50 | while (b) { 51 | Item item = Blahaj.randomItem(ItemTags.WOOL); 52 | if (item == null) { 53 | return null; 54 | } 55 | b = map.containsValue(item); 56 | if (b) continue; 57 | map.put(key, item); 58 | } 59 | } 60 | JsonObject key = new JsonObject(); 61 | map.forEach((k, i) -> { 62 | JsonObject o = new JsonObject(); 63 | Identifier id = Registries.ITEM.getId(i); 64 | Blahaj.LOGGER.warn("## {} -> {}", k, id); 65 | o.addProperty("item", id.toString()); 66 | key.add(k, o); 67 | }); 68 | JsonObject k = new JsonObject(); 69 | k.addProperty("item", Blahaj.BLAHAJ_ID.toString()); 70 | key.add("#", k); 71 | main.add("key", key); 72 | JsonObject result = new JsonObject(); 73 | result.addProperty("item", Blahaj.$k_O$8.toString()); 74 | main.add("result", result); 75 | return main; 76 | } 77 | 78 | @Inject( 79 | method = "apply(Ljava/util/Map;Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/util/profiler/Profiler;)V", 80 | at = @At("HEAD") 81 | ) 82 | private void postRecipeParseAddSpecial(Map map, ResourceManager resourceManager, 83 | Profiler profiler, CallbackInfo ci) { 84 | if (!map.containsKey(Blahaj.$k_O$8)) { 85 | JsonObject object = randomBlahajGlitchRecipe(); 86 | if (object == null) { 87 | return; 88 | } 89 | map.put(Blahaj.$k_O$8, object); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/ServerRecipeBookMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin; 2 | 3 | import mc.recraftors.blahaj.Blahaj; 4 | import net.minecraft.recipe.Recipe; 5 | import net.minecraft.server.network.ServerRecipeBook; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Collection; 12 | 13 | @Mixin(ServerRecipeBook.class) 14 | public class ServerRecipeBookMixin { 15 | @ModifyVariable(method = "unlockRecipes", argsOnly = true, at = @At("HEAD")) 16 | private Collection> glitchNoUnlock(Collection> collection) { 17 | collection = new ArrayList<>(collection); 18 | collection.removeIf(r -> Blahaj.isHidden(r.getId())); 19 | return collection; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/Plugin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat; 2 | 3 | import mc.recraftors.blahaj.PreLaunchUtils; 4 | import org.objectweb.asm.tree.ClassNode; 5 | import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; 6 | import org.spongepowered.asm.mixin.extensibility.IMixinInfo; 7 | 8 | import java.util.List; 9 | import java.util.Set; 10 | 11 | public final class Plugin implements IMixinConfigPlugin { 12 | private static final String COMPAT_PACKAGE_ROOT; 13 | private static final int COMPAT_PACKAGE_LENGTH; 14 | private static final String COMPAT_PRESENT_KEY = "present"; 15 | private static final String COMPAT_ABSENT_KEY = "absent"; 16 | private static final String COMPAT_ANY_KEY = "any"; 17 | private static final String COMPAT_AND_KEY = "and"; 18 | private static final String COMPAT_BUT_KEY = "and_not"; 19 | private static final String COMPAT_NOR_KEY = "nor"; 20 | private static final String COMPAT_OR_KEY = "or"; 21 | private static final String COMPAT_XOR_KEY = "xor"; 22 | private static final String AUTHOR_KEY = "author"; 23 | 24 | static { 25 | // Shorthand getting the plugin package to ensure not making trouble with other mixins 26 | COMPAT_PACKAGE_ROOT = Plugin.class.getPackageName(); 27 | String[] compatRoot = COMPAT_PACKAGE_ROOT.split("\\."); 28 | COMPAT_PACKAGE_LENGTH = compatRoot.length; 29 | } 30 | 31 | @Override 32 | public void onLoad(String mixinPackage) { 33 | } 34 | 35 | @Override 36 | public String getRefMapperConfig() { 37 | return null; 38 | } 39 | 40 | @Override 41 | public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { 42 | if (!mixinClassName.startsWith(COMPAT_PACKAGE_ROOT)) { 43 | return true; 44 | } 45 | String[] mixinPath = mixinClassName.split("\\."); 46 | int i = COMPAT_PACKAGE_LENGTH; 47 | // the id of the target mod 48 | String compatModId = mixinPath[i++]; 49 | if (mixinPath[i].equals(AUTHOR_KEY)) { 50 | if (!PreLaunchUtils.modHasAuthor(compatModId, mixinPath[++i])) return false; 51 | i++; 52 | } 53 | // Apply accordingly of the mod's presence, absence, etc 54 | String s; 55 | return switch (s = mixinPath[i++]) { 56 | case COMPAT_PRESENT_KEY -> PreLaunchUtils.isModLoaded(compatModId); 57 | case COMPAT_ABSENT_KEY -> !PreLaunchUtils.isModLoaded(compatModId); 58 | case COMPAT_AND_KEY -> PreLaunchUtils.isModLoaded(compatModId) && PreLaunchUtils.isModLoaded(mixinPath[i]); 59 | case COMPAT_BUT_KEY -> PreLaunchUtils.isModLoaded(compatModId) && !PreLaunchUtils.isModLoaded(mixinPath[i]); 60 | case COMPAT_NOR_KEY -> !PreLaunchUtils.isModLoaded(compatModId) && !PreLaunchUtils.isModLoaded(mixinPath[i]); 61 | case COMPAT_OR_KEY -> PreLaunchUtils.isModLoaded(compatModId) || PreLaunchUtils.isModLoaded(mixinPath[i]); 62 | case COMPAT_XOR_KEY -> PreLaunchUtils.isModLoaded(compatModId) ^ PreLaunchUtils.isModLoaded(mixinPath[i]); 63 | default -> s.equals(COMPAT_ANY_KEY); 64 | }; 65 | } 66 | 67 | @Override 68 | public void acceptTargets(Set myTargets, Set otherTargets) { 69 | } 70 | 71 | @Override 72 | public List getMixins() { 73 | return null; 74 | } 75 | 76 | @Override 77 | public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { 78 | } 79 | 80 | @Override 81 | public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/andromeda/present/AutoAdvGenerationMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.andromeda.present; 2 | 3 | import com.llamalad7.mixinextras.sugar.Local; 4 | import mc.recraftors.blahaj.Blahaj; 5 | import me.melontini.andromeda.modules.misc.recipe_advancements_generation.AdvancementGeneration; 6 | import me.melontini.andromeda.modules.misc.recipe_advancements_generation.Main; 7 | import net.minecraft.advancement.Advancement; 8 | import net.minecraft.recipe.Recipe; 9 | import net.minecraft.util.Identifier; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | 15 | import java.util.List; 16 | import java.util.Map; 17 | import java.util.concurrent.atomic.AtomicInteger; 18 | 19 | @Mixin(value = Main.class, remap = false) 20 | public class AutoAdvGenerationMixin { 21 | @Inject( 22 | method = "lambda$generateRecipeAdvancements$2", 23 | at = @At( 24 | value = "INVOKE", 25 | target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 26 | shift = At.Shift.AFTER 27 | ) 28 | ) 29 | private void undoPutDefaultGlitchRecipe( 30 | List> list, AdvancementGeneration.Config config, AtomicInteger count, Map advancementBuilders, CallbackInfo ci, @Local Recipe recipe) { 32 | if (Blahaj.isHidden(recipe.getId())) { 33 | advancementBuilders.remove(recipe.getId()); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/immersive_melodies/present/ItemsMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.immersive_melodies.present; 2 | 3 | import immersive_melodies.Items; 4 | import mc.recraftors.blahaj.Blahaj; 5 | import mc.recraftors.blahaj.compat.BlahajBassAnimator; 6 | import org.joml.Vector3f; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | @Mixin(Items.class) 13 | public interface ItemsMixin { 14 | @Inject(method = "", at = @At("TAIL")) 15 | private static void blahajClinitInjector(CallbackInfo ci) { 16 | Items.register(Blahaj.MOD_ID, "blahaj_bass", new BlahajBassAnimator(), 200L, new Vector3f(0, .1f, .5f)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/notenoughanimations/present/HeldItemHandlerMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.notenoughanimations.present; 2 | 3 | import dev.tr7zw.notenoughanimations.logic.HeldItemHandler; 4 | import mc.recraftors.blahaj.Blahaj; 5 | import net.fabricmc.api.EnvType; 6 | import net.fabricmc.api.Environment; 7 | import net.minecraft.client.render.VertexConsumerProvider; 8 | import net.minecraft.client.render.entity.model.EntityModel; 9 | import net.minecraft.client.util.math.MatrixStack; 10 | import net.minecraft.entity.LivingEntity; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.util.Arm; 13 | import org.spongepowered.asm.mixin.Mixin; 14 | import org.spongepowered.asm.mixin.injection.At; 15 | import org.spongepowered.asm.mixin.injection.Inject; 16 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 17 | 18 | @Environment(EnvType.CLIENT) 19 | @Mixin(HeldItemHandler.class) 20 | public abstract class HeldItemHandlerMixin { 21 | @Inject( 22 | method = "onRenderItem", 23 | at = @At( 24 | value = "INVOKE", 25 | target = "Lnet/minecraft/entity/LivingEntity;isSleeping()Z", 26 | shift = At.Shift.AFTER) 27 | , 28 | cancellable = true) 29 | private void renderSleepingPlushyPredicate(LivingEntity entity, EntityModel model, ItemStack itemStack, Arm arm, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo info, CallbackInfo ci) { 30 | if (entity.isSleeping() && Blahaj.holdsOnlyCuddlyItem(entity)) { 31 | ci.cancel(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/notenoughanimations/present/SleepAnimationMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.notenoughanimations.present; 2 | 3 | import dev.tr7zw.notenoughanimations.access.PlayerData; 4 | import dev.tr7zw.notenoughanimations.animations.vanilla.SleepAnimation; 5 | import mc.recraftors.blahaj.Blahaj; 6 | import net.fabricmc.api.EnvType; 7 | import net.fabricmc.api.Environment; 8 | import net.minecraft.client.network.AbstractClientPlayerEntity; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 13 | 14 | @Environment(EnvType.CLIENT) 15 | @Mixin(SleepAnimation.class) 16 | public abstract class SleepAnimationMixin { 17 | @Inject(method = "isValid", at = @At("HEAD"), cancellable = true) 18 | private void isValidSleepPlushieInjector(AbstractClientPlayerEntity entity, PlayerData data, 19 | CallbackInfoReturnable cir) { 20 | if (Blahaj.holdsOnlyCuddlyItem(entity)) cir.setReturnValue(false); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/travelersbackpack/and/trinkets/TravelersBackpackWearableModelMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.travelersbackpack.and.trinkets; 2 | 3 | import com.tiviacz.travelersbackpack.client.model.TravelersBackpackWearableModel; 4 | import mc.recraftors.blahaj.compat.TrinketPlushRenderer; 5 | import net.fabricmc.api.EnvType; 6 | import net.fabricmc.api.Environment; 7 | import net.minecraft.client.render.VertexConsumer; 8 | import net.minecraft.client.util.math.MatrixStack; 9 | import net.minecraft.entity.LivingEntity; 10 | import org.spongepowered.asm.mixin.Final; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | import org.spongepowered.asm.mixin.Shadow; 13 | import org.spongepowered.asm.mixin.injection.At; 14 | import org.spongepowered.asm.mixin.injection.Inject; 15 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 16 | 17 | @Environment(EnvType.CLIENT) 18 | @Mixin(TravelersBackpackWearableModel.class) 19 | public class TravelersBackpackWearableModelMixin { 20 | @Shadow @Final private LivingEntity livingEntity; 21 | 22 | @Inject(method = "render", at = @At("HEAD"), cancellable = true) 23 | private void onRenderHeadInjector(MatrixStack matrices, VertexConsumer vertices, int light, int overlay, 24 | float red, float green, float blue, float alpha, CallbackInfo ci) { 25 | if (TrinketPlushRenderer.hasCuddlyInSlot(this.livingEntity, "chest", "back", "cape")) ci.cancel(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/travelersbackpack/present/ModBlockEntityTypesMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.travelersbackpack.present; 2 | 3 | import com.tiviacz.travelersbackpack.TravelersBackpack; 4 | import com.tiviacz.travelersbackpack.init.ModBlockEntityTypes; 5 | import mc.recraftors.blahaj.compat.DataHolder; 6 | import net.minecraft.block.Block; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.ModifyArgs; 10 | import org.spongepowered.asm.mixin.injection.invoke.arg.Args; 11 | 12 | import java.util.Arrays; 13 | 14 | @Mixin(ModBlockEntityTypes.class) 15 | public abstract class ModBlockEntityTypesMixin { 16 | @ModifyArgs(method = "init", at = @At(value = "INVOKE", target = "Lnet/fabricmc/fabric/api/object/builder/v1/block/entity/FabricBlockEntityTypeBuilder;create(Lnet/fabricmc/fabric/api/object/builder/v1/block/entity/FabricBlockEntityTypeBuilder$Factory;[Lnet/minecraft/block/Block;)Lnet/fabricmc/fabric/api/object/builder/v1/block/entity/FabricBlockEntityTypeBuilder;")) 17 | private static void initEntityTypeBuilderCreateArgsModifier(Args args) { 18 | Block[] blocks = args.get(1); 19 | blocks = Arrays.copyOf(blocks, blocks.length+1); 20 | blocks[blocks.length-1] = (Block) DataHolder.modMap(TravelersBackpack.MODID).get("block"); 21 | args.set(1, blocks); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/travelersbackpack/present/ModBlocksMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.travelersbackpack.present; 2 | 3 | import com.tiviacz.travelersbackpack.TravelersBackpack; 4 | import com.tiviacz.travelersbackpack.blocks.TravelersBackpackBlock; 5 | import com.tiviacz.travelersbackpack.init.ModBlocks; 6 | import mc.recraftors.blahaj.Blahaj; 7 | import mc.recraftors.blahaj.compat.DataHolder; 8 | import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; 9 | import net.minecraft.block.MapColor; 10 | import net.minecraft.registry.Registries; 11 | import net.minecraft.sound.BlockSoundGroup; 12 | import net.minecraft.util.Identifier; 13 | import net.minecraft.registry.Registry; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.injection.At; 16 | import org.spongepowered.asm.mixin.injection.Inject; 17 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 18 | 19 | import java.util.Map; 20 | 21 | @Mixin(value = ModBlocks.class, remap = false) 22 | public abstract class ModBlocksMixin { 23 | @Inject(method = "init", at = @At("TAIL")) 24 | private static void initInjector(CallbackInfo ci) { 25 | Map modMap = DataHolder.modMap(TravelersBackpack.MODID); 26 | modMap.put("block", Registry.register(Registries.BLOCK, new Identifier(Blahaj.MOD_ID, "blahaj_backpack"), new TravelersBackpackBlock(FabricBlockSettings.create().mapColor(MapColor.BLUE).sounds(BlockSoundGroup.WOOL)))); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/travelersbackpack/present/ModItemGroupsMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.travelersbackpack.present; 2 | 3 | import com.tiviacz.travelersbackpack.init.ModItemGroups; 4 | import mc.recraftors.blahaj.Blahaj; 5 | import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroupEntries; 6 | import net.minecraft.registry.Registries; 7 | import net.minecraft.util.Identifier; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | 13 | @Mixin(ModItemGroups.class) 14 | public abstract class ModItemGroupsMixin { 15 | @Inject(method = "lambda$addItemGroup$0", at = @At(value = "INVOKE", target = "Lnet/fabricmc/fabric/api/itemgroup/v1/FabricItemGroupEntries;add(Lnet/minecraft/item/ItemConvertible;)V", ordinal = 51, shift = At.Shift.AFTER)) 16 | private static void registerEntriesInjector(FabricItemGroupEntries entries, CallbackInfo ci) { 17 | entries.add(Registries.ITEM.get(new Identifier(Blahaj.MOD_ID, "blahaj_backpack"))); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/travelersbackpack/present/ModItemsMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.travelersbackpack.present; 2 | 3 | import com.tiviacz.travelersbackpack.TravelersBackpack; 4 | import com.tiviacz.travelersbackpack.init.ModItems; 5 | import com.tiviacz.travelersbackpack.items.TravelersBackpackItem; 6 | import mc.recraftors.blahaj.Blahaj; 7 | import mc.recraftors.blahaj.compat.DataHolder; 8 | import net.minecraft.block.Block; 9 | import net.minecraft.item.Item; 10 | import net.minecraft.registry.Registries; 11 | import net.minecraft.registry.Registry; 12 | import net.minecraft.util.Identifier; 13 | import org.spongepowered.asm.mixin.Mixin; 14 | import org.spongepowered.asm.mixin.Unique; 15 | import org.spongepowered.asm.mixin.injection.At; 16 | import org.spongepowered.asm.mixin.injection.Inject; 17 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 18 | 19 | import java.util.Map; 20 | 21 | @Mixin(value = ModItems.class, remap = false) 22 | public abstract class ModItemsMixin { 23 | @Unique 24 | private static TravelersBackpackItem blahajBackpack; 25 | 26 | @Inject(method = "init", at = @At("TAIL")) 27 | private static void initTailInjector(CallbackInfo ci) { 28 | Map modMap = DataHolder.modMap(TravelersBackpack.MODID); 29 | blahajBackpack = new TravelersBackpackItem((Block) modMap.get("block")); 30 | Registry.register(Registries.ITEM, new Identifier(Blahaj.MOD_ID, "blahaj_backpack"), (Item) blahajBackpack); 31 | modMap.put("item", blahajBackpack); 32 | } 33 | 34 | @Inject(method = "addBackpacksToList", at = @At("TAIL")) 35 | private static void addBackpacksToListTailInjector(CallbackInfo ci) { 36 | ModItems.BACKPACKS.add(blahajBackpack); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/travelersbackpack/present/ResourceUtilsMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.travelersbackpack.present; 2 | 3 | import com.tiviacz.travelersbackpack.util.ResourceUtils; 4 | import mc.recraftors.blahaj.Blahaj; 5 | import net.minecraft.util.Identifier; 6 | import org.spongepowered.asm.mixin.Final; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.Shadow; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | 13 | import java.util.List; 14 | 15 | @Mixin(value = ResourceUtils.class, remap = false) 16 | public abstract class ResourceUtilsMixin { 17 | @Shadow @Final public static List TEXTURE_IDENTIFIERS; 18 | 19 | @Inject(method = "createTextureLocations", at = @At("TAIL")) 20 | private static void createTextureLocationsTailInjector(CallbackInfo ci) { 21 | TEXTURE_IDENTIFIERS.add(new Identifier(Blahaj.MOD_ID, "textures/model/blahaj_backpack.png")); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/trinkets/present/BlahajMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.trinkets.present; 2 | 3 | import dev.emi.trinkets.api.client.TrinketRenderer; 4 | import dev.emi.trinkets.api.client.TrinketRendererRegistry; 5 | import mc.recraftors.blahaj.Blahaj; 6 | import mc.recraftors.blahaj.item.CuddlyItem; 7 | import net.fabricmc.api.EnvType; 8 | import net.fabricmc.api.Environment; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.Shadow; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | 15 | import java.util.Collection; 16 | 17 | @Mixin(value = Blahaj.class, remap = false) 18 | @Environment(EnvType.CLIENT) 19 | public class BlahajMixin { 20 | @Shadow 21 | public static Collection getItems() { 22 | return null; 23 | } 24 | 25 | @Inject(method = "onInitialize", at = @At("TAIL")) 26 | private void onInitializeTrinketCompatInjector(CallbackInfo callbackInfo) { 27 | getItems().forEach(item -> TrinketRendererRegistry.registerRenderer(item, (TrinketRenderer) item)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/trinkets/present/CapeFeatureRendererMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.trinkets.present; 2 | 3 | import dev.emi.trinkets.api.SlotGroup; 4 | import dev.emi.trinkets.api.SlotType; 5 | import dev.emi.trinkets.api.TrinketsApi; 6 | import mc.recraftors.blahaj.compat.BooleanConsumer; 7 | import mc.recraftors.blahaj.compat.TrinketPlushRenderer; 8 | import net.fabricmc.api.EnvType; 9 | import net.fabricmc.api.Environment; 10 | import net.minecraft.client.network.AbstractClientPlayerEntity; 11 | import net.minecraft.client.render.VertexConsumerProvider; 12 | import net.minecraft.client.render.entity.feature.CapeFeatureRenderer; 13 | import net.minecraft.client.render.entity.feature.FeatureRenderer; 14 | import net.minecraft.client.render.entity.feature.FeatureRendererContext; 15 | import net.minecraft.client.render.entity.model.PlayerEntityModel; 16 | import net.minecraft.client.util.math.MatrixStack; 17 | import org.spongepowered.asm.mixin.Mixin; 18 | import org.spongepowered.asm.mixin.injection.At; 19 | import org.spongepowered.asm.mixin.injection.Inject; 20 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 21 | 22 | /** 23 | * Hides unsolicited cape if a cuddly item is in a back slot. 24 | * Works with {@link PlayerEntityModelMixin} 25 | */ 26 | @Environment(EnvType.CLIENT) 27 | @Mixin(CapeFeatureRenderer.class) 28 | public abstract class CapeFeatureRendererMixin extends FeatureRenderer> { 29 | CapeFeatureRendererMixin(FeatureRendererContext> featureRendererContext) { 30 | super(featureRendererContext); 31 | } 32 | 33 | @Inject( 34 | method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/network/AbstractClientPlayerEntity;FFFFFF)V", 35 | at = @At( 36 | value = "INVOKE", 37 | target = "Lnet/minecraft/client/util/math/MatrixStack;push()V", 38 | shift = At.Shift.BEFORE 39 | ), 40 | cancellable = true 41 | ) 42 | private void blahaj$trinket$onRenderCapeUpdate(MatrixStack stack, VertexConsumerProvider provider, int i, 43 | AbstractClientPlayerEntity player, float f, float g, float h, 44 | float j, float k, float l, CallbackInfo ci) { 45 | SlotGroup group = TrinketsApi.getPlayerSlots(player).get("chest"); 46 | if (group == null) { 47 | return; 48 | } 49 | SlotType type = group.getSlots().get("back"); 50 | if (type == null) { 51 | return; 52 | } 53 | boolean b = TrinketPlushRenderer.hasCuddlyInSlot(player, "chest", "back", "cape"); 54 | ((BooleanConsumer) this.getContextModel()).blahaj$consume(b); 55 | if (b) { 56 | ci.cancel(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/trinkets/present/CuddlyItemMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.trinkets.present; 2 | 3 | import dev.emi.trinkets.api.SlotReference; 4 | import mc.recraftors.blahaj.item.CuddlyItem; 5 | import mc.recraftors.blahaj.compat.TrinketPlushRenderer; 6 | import net.fabricmc.api.EnvType; 7 | import net.fabricmc.api.Environment; 8 | import net.minecraft.client.MinecraftClient; 9 | import net.minecraft.client.render.OverlayTexture; 10 | import net.minecraft.client.render.VertexConsumerProvider; 11 | import net.minecraft.client.render.entity.model.BipedEntityModel; 12 | import net.minecraft.client.render.item.ItemRenderer; 13 | import net.minecraft.client.render.model.json.ModelTransformationMode; 14 | import net.minecraft.client.util.math.MatrixStack; 15 | import net.minecraft.entity.LivingEntity; 16 | import net.minecraft.entity.player.PlayerEntity; 17 | import net.minecraft.item.ItemStack; 18 | import net.minecraft.nbt.NbtCompound; 19 | import net.minecraft.util.Arm; 20 | import net.minecraft.util.math.RotationAxis; 21 | import org.spongepowered.asm.mixin.Mixin; 22 | import org.spongepowered.asm.mixin.Unique; 23 | 24 | import java.util.Objects; 25 | 26 | @Environment(EnvType.CLIENT) 27 | @Mixin(CuddlyItem.class) 28 | public abstract class CuddlyItemMixin implements TrinketPlushRenderer { 29 | 30 | @Unique 31 | public void blahaj$trinkets$renderHead(ItemStack stack, SlotReference reference, BipedEntityModel model, 32 | MatrixStack matrix, VertexConsumerProvider provider, int light, LivingEntity entity, 33 | float limbAngle, float limbDistance, float tickDelta, float animationProgress, 34 | float headYaw, float headPitch) { 35 | Objects.requireNonNull(reference); 36 | String s = reference.inventory().getSlotType().getName(); 37 | if (!"hat".equalsIgnoreCase(s) && !"crown".equalsIgnoreCase(s)) return; 38 | ItemRenderer renderer = MinecraftClient.getInstance().getItemRenderer(); 39 | float xFactor = (entity.isInSwimmingPose() || entity.isFallFlying()) ? -45 : headPitch; 40 | matrix.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(model.head.roll)); 41 | matrix.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(headYaw)); 42 | matrix.multiply(RotationAxis.POSITIVE_X.rotationDegrees(xFactor)); 43 | if (!entity.isInSneakingPose()) { 44 | matrix.translate(0f, -.25f, 0f); 45 | } 46 | matrix.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(180)); 47 | matrix.scale(.75f, .75f, .75f); 48 | renderer.renderItem(entity, stack, ModelTransformationMode.HEAD, false, matrix, provider, entity.getWorld(), light, OverlayTexture.DEFAULT_UV, 0); 49 | } 50 | 51 | @Unique 52 | public void blahaj$trinkets$renderChest(ItemStack stack, SlotReference reference, BipedEntityModel model, 53 | MatrixStack matrix, VertexConsumerProvider provider, int light, LivingEntity entity, 54 | float limbAngle, float limbDistance, float tickDelta, float animationProgress, 55 | float headYaw, float headPitch) { 56 | Objects.requireNonNull(reference); 57 | String s = reference.inventory().getSlotType().getName(); 58 | switch (s) { 59 | case "back", "backpack", "cape" -> blahaj$trinkets$renderChest$back(stack, matrix, provider, light, entity); 60 | case "shoulder", "necklace" -> blahaj$trinkets$renderChest$shoulder(stack, matrix, provider, light, entity); 61 | } 62 | } 63 | 64 | @Unique 65 | private void blahaj$trinkets$renderChest$back(ItemStack stack, MatrixStack matrix, VertexConsumerProvider provider, 66 | int light, LivingEntity entity) { 67 | Objects.requireNonNull(matrix); 68 | ItemRenderer renderer = MinecraftClient.getInstance().getItemRenderer(); 69 | matrix.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90)); 70 | matrix.multiply(RotationAxis.NEGATIVE_Y.rotationDegrees(90)); 71 | matrix.scale(1.25f, 1.25f, 1.25f); 72 | // x (vertical, + = up), y (depth, + = back), z (sideways, + = right) 73 | matrix.translate(-0.25f, 0.3f, .175f); 74 | renderer.renderItem(entity, stack, ModelTransformationMode.FIXED, false, matrix, provider, entity.getWorld(), light, OverlayTexture.DEFAULT_UV, 0); 75 | } 76 | 77 | @Unique 78 | private void blahaj$trinkets$renderChest$shoulder(ItemStack stack, MatrixStack matrix, 79 | VertexConsumerProvider provider, int light, LivingEntity entity) { 80 | Objects.requireNonNull(matrix); 81 | ItemRenderer renderer = MinecraftClient.getInstance().getItemRenderer(); 82 | boolean b = false; // false = render on left shoulder 83 | if (entity instanceof PlayerEntity player) { 84 | NbtCompound left = player.getShoulderEntityLeft(); 85 | NbtCompound right = player.getShoulderEntityRight(); 86 | if (!left.isEmpty() && !right.isEmpty()) return; 87 | if (player.getMainArm() == Arm.LEFT) b = right.isEmpty(); 88 | else b = !left.isEmpty(); 89 | } 90 | matrix.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180)); 91 | matrix.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-90)); 92 | float side = b ? .465f : -.275f; 93 | // x (depth, + = front), y (vertical, + = up), z (side, + = right) 94 | matrix.translate(0f, 0.115f, side); 95 | matrix.scale(0.5f, 0.5f, 0.5f); 96 | if (entity.isInSneakingPose()) { 97 | matrix.translate(0f, -0.25f, 0f); 98 | matrix.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(35)); 99 | } 100 | renderer.renderItem(entity, stack, ModelTransformationMode.FIXED, false, matrix, provider, entity.getWorld(), light, OverlayTexture.DEFAULT_UV, 0); 101 | } 102 | 103 | @Unique 104 | public void blahaj$trinkets$renderLegs(ItemStack stack, SlotReference reference, BipedEntityModel model, 105 | MatrixStack matrix, VertexConsumerProvider provider, int light, LivingEntity entity, 106 | float limbAngle, float limbDistance, float tickDelta, float animationProgress, 107 | float headYaw, float headPitch) { 108 | Objects.requireNonNull(reference); 109 | String s = reference.inventory().getSlotType().getName(); 110 | if ("belt".equals(s)) { 111 | blahaj$trinkets$renderLegs$belt(stack, matrix, provider, light, entity); 112 | } else if ("thighs".equals(s)) { 113 | blahaj$trinkets$renderLegs$thighs(stack, matrix, provider, light, entity); 114 | } 115 | } 116 | 117 | @Unique 118 | private void blahaj$trinkets$renderLegs$belt(ItemStack stack, MatrixStack matrix, VertexConsumerProvider provider, 119 | int light, LivingEntity entity) { 120 | Objects.requireNonNull(matrix); 121 | ItemRenderer renderer = MinecraftClient.getInstance().getItemRenderer(); 122 | boolean b = blahaj$trinkets$getMainHand(entity, false); 123 | float side = b ? .355f : -.355f; 124 | float r = b ? 90 : -90; 125 | matrix.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180)); 126 | matrix.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-90)); 127 | // x (depth, + = front), y (vertical, + = up), z (side, + = right) 128 | matrix.translate(0f, -0.75f, side); 129 | matrix.multiply(RotationAxis.POSITIVE_X.rotationDegrees(r)); 130 | matrix.scale(0.5f, 0.5f, 0.5f); 131 | renderer.renderItem(entity, stack, ModelTransformationMode.FIXED, false, matrix, provider, entity.getWorld(), light, OverlayTexture.DEFAULT_UV, 0); 132 | } 133 | 134 | @Unique 135 | private void blahaj$trinkets$renderLegs$thighs(ItemStack stack, MatrixStack matrix, VertexConsumerProvider provider, 136 | int light, LivingEntity entity) { 137 | Objects.requireNonNull(matrix); 138 | ItemRenderer renderer = MinecraftClient.getInstance().getItemRenderer(); 139 | boolean b = blahaj$trinkets$getMainHand(entity, false); 140 | if (TrinketPlushRenderer.hasCuddlyInSlot(entity, "legs", "belt")) b = !b; 141 | float side = b ? -.355f : .355f; 142 | float r = b ? -90 : 90; 143 | matrix.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180)); 144 | matrix.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-90)); 145 | matrix.translate(0f, -0.75f, side); 146 | matrix.multiply(RotationAxis.POSITIVE_X.rotationDegrees(r)); 147 | matrix.scale(0.5f, 0.5f, 0.5f); 148 | renderer.renderItem(entity, stack, ModelTransformationMode.FIXED, false, matrix, provider, entity.getWorld(), light, OverlayTexture.DEFAULT_UV, 0); 149 | } 150 | 151 | @Unique 152 | public void blahaj$trinkets$renderFeet(ItemStack stack, SlotReference reference, BipedEntityModel model, 153 | MatrixStack matrix, VertexConsumerProvider provider, int light, LivingEntity entity, 154 | float limbAngle, float limbDistance, float tickDelta, float animationProgress, 155 | float headYaw, float headPitch) { 156 | Objects.requireNonNull(reference); 157 | String s = reference.inventory().getSlotType().getName(); 158 | if (!"shoes".equalsIgnoreCase(s)) return; 159 | ItemRenderer renderer = MinecraftClient.getInstance().getItemRenderer(); 160 | //TODO feet models 161 | } 162 | 163 | @Unique 164 | public void blahak$trinkets$renderHand(ItemStack stack, SlotReference reference, BipedEntityModel model, 165 | MatrixStack matrix, VertexConsumerProvider provider, int light, LivingEntity entity, 166 | float limbAngle, float limbDistance, float tickDelta, float animationProgress, 167 | float headYaw, float headPitch) {} 168 | 169 | /** 170 | * Gets the main hand/arm as a boolean. False for right. 171 | * @param entity the entity to get the main hand/arm for 172 | * @param fallback the fallback if none could be acquired 173 | * @return {@code true} if left hand/arm, {@code false} if right hand/arm, 174 | * {@code fallback} if none could be acquired. 175 | */ 176 | @Unique 177 | private static boolean blahaj$trinkets$getMainHand(LivingEntity entity, boolean fallback) { 178 | if (entity instanceof PlayerEntity player) { 179 | return player.getMainArm() == Arm.LEFT; 180 | } 181 | return fallback; 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/compat/trinkets/present/PlayerEntityModelMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.compat.trinkets.present; 2 | 3 | import mc.recraftors.blahaj.BooleanProvider; 4 | import mc.recraftors.blahaj.compat.BooleanConsumer; 5 | import net.fabricmc.api.EnvType; 6 | import net.fabricmc.api.Environment; 7 | import net.minecraft.client.model.ModelPart; 8 | import net.minecraft.client.render.RenderLayer; 9 | import net.minecraft.client.render.VertexConsumer; 10 | import net.minecraft.client.render.entity.model.BipedEntityModel; 11 | import net.minecraft.client.render.entity.model.PlayerEntityModel; 12 | import net.minecraft.client.util.math.MatrixStack; 13 | import net.minecraft.entity.LivingEntity; 14 | import net.minecraft.util.Identifier; 15 | import org.spongepowered.asm.mixin.Mixin; 16 | import org.spongepowered.asm.mixin.Unique; 17 | import org.spongepowered.asm.mixin.injection.At; 18 | import org.spongepowered.asm.mixin.injection.Inject; 19 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 20 | 21 | import java.util.function.Function; 22 | 23 | /** 24 | * Hides unsolicited cape if a cuddly item is in a back slot. 25 | * Works with {@link CapeFeatureRendererMixin} 26 | */ 27 | @Environment(EnvType.CLIENT) 28 | @Mixin(PlayerEntityModel.class) 29 | public abstract class PlayerEntityModelMixin extends BipedEntityModel implements BooleanConsumer, BooleanProvider { 30 | @Unique 31 | private boolean cloackLock = false; 32 | 33 | PlayerEntityModelMixin(ModelPart modelPart, Function function) { 34 | super(modelPart, function); 35 | } 36 | 37 | @Override 38 | public void blahaj$consume(boolean b) { 39 | this.cloackLock = b; 40 | } 41 | 42 | @Override 43 | public boolean blahaj$getBool() { 44 | return this.cloackLock; 45 | } 46 | 47 | @Inject(method = "renderCape", at = @At("HEAD"), cancellable = true) 48 | private void blahaj$trinket$cloackIsHiddenByPlush(MatrixStack matrixStack, VertexConsumer vertexConsumer, int i, int j, CallbackInfo ci) { 49 | if (this.cloackLock) ci.cancel(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/render/AllayEntityMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.render; 2 | 3 | import mc.recraftors.blahaj.item.CuddlyItem; 4 | import net.fabricmc.api.EnvType; 5 | import net.fabricmc.api.Environment; 6 | import net.minecraft.entity.passive.AllayEntity; 7 | import net.minecraft.entity.player.PlayerEntity; 8 | import net.minecraft.util.ActionResult; 9 | import net.minecraft.util.Hand; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 14 | 15 | @Environment(EnvType.CLIENT) 16 | @Mixin(AllayEntity.class) 17 | public abstract class AllayEntityMixin { 18 | 19 | @Inject( 20 | method = "interactMob", 21 | at = @At("HEAD"), 22 | cancellable = true 23 | ) 24 | private void interactWithPlushInjector(PlayerEntity player, Hand hand, 25 | CallbackInfoReturnable cir) { 26 | if (player.getStackInHand(hand).getItem() instanceof CuddlyItem) { 27 | cir.setReturnValue(ActionResult.PASS); 28 | cir.cancel(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/render/BipedEntityModelMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.render; 2 | 3 | import mc.recraftors.blahaj.Blahaj; 4 | import mc.recraftors.blahaj.item.CuddlyItem; 5 | import net.fabricmc.api.EnvType; 6 | import net.fabricmc.api.Environment; 7 | import net.minecraft.client.model.ModelPart; 8 | import net.minecraft.client.render.entity.model.BipedEntityModel; 9 | import net.minecraft.entity.LivingEntity; 10 | import org.joml.Vector3f; 11 | import org.spongepowered.asm.mixin.Final; 12 | import org.spongepowered.asm.mixin.Mixin; 13 | import org.spongepowered.asm.mixin.Shadow; 14 | import org.spongepowered.asm.mixin.Unique; 15 | import org.spongepowered.asm.mixin.injection.At; 16 | import org.spongepowered.asm.mixin.injection.Inject; 17 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 18 | 19 | @Environment(EnvType.CLIENT) 20 | @Mixin(BipedEntityModel.class) 21 | public abstract class BipedEntityModelMixin { 22 | @Shadow @Final public ModelPart rightArm; 23 | 24 | @Shadow @Final public ModelPart leftArm; 25 | 26 | @Inject( 27 | method = {"positionRightArm", "positionLeftArm"}, 28 | at = @At( 29 | value = "INVOKE", 30 | target = "Lnet/minecraft/client/render/entity/model/CrossbowPosing;hold(Lnet/minecraft/client/model/ModelPart;Lnet/minecraft/client/model/ModelPart;Lnet/minecraft/client/model/ModelPart;Z)V", 31 | shift = At.Shift.AFTER 32 | ), 33 | cancellable = true 34 | ) 35 | private void positionArmsInjector(LivingEntity entity, CallbackInfo ci) { 36 | boolean b1 = entity.getMainHandStack().getItem() instanceof CuddlyItem && entity.getOffHandStack().isEmpty(); 37 | boolean b2 = entity.getMainHandStack().isEmpty() && entity.getOffHandStack().getItem() instanceof CuddlyItem; 38 | if (b1 || b2) { 39 | this.rightArm.pitch = -0.95F; 40 | this.rightArm.yaw = (float) (-Math.PI / 8); 41 | this.leftArm.pitch = -0.90F; 42 | this.leftArm.yaw = (float) (Math.PI / 8); 43 | ci.cancel(); 44 | } 45 | } 46 | 47 | @Inject(method = "setAngles(Lnet/minecraft/entity/LivingEntity;FFFFF)V", at = @At("RETURN")) 48 | private void sleepCuddleAngleInjector(T livingEntity, float f, float g, float h, float i, float j, CallbackInfo ci) { 49 | if (!livingEntity.isSleeping()) return; 50 | blahaj$setCuddleArmsPos(livingEntity); 51 | } 52 | 53 | @Unique 54 | private void blahaj$setCuddleArmsPos(T entity) { 55 | if (!Blahaj.holdsOnlyCuddlyItem(entity)) { 56 | return; 57 | } 58 | Vector3f right = new Vector3f(-.1f, -.02f, 0); 59 | Vector3f left = new Vector3f(-.1f, -.08f, 0); 60 | this.rightArm.rotate(right); 61 | this.leftArm.rotate(left); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/render/HeldItemRendererMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.render; 2 | 3 | import com.llamalad7.mixinextras.injector.ModifyExpressionValue; 4 | import com.llamalad7.mixinextras.sugar.Local; 5 | import mc.recraftors.blahaj.Blahaj; 6 | import net.fabricmc.api.EnvType; 7 | import net.fabricmc.api.Environment; 8 | import net.minecraft.client.network.AbstractClientPlayerEntity; 9 | import net.minecraft.client.render.item.HeldItemRenderer; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | 13 | @Environment(EnvType.CLIENT) 14 | @Mixin(HeldItemRenderer.class) 15 | public abstract class HeldItemRendererMixin { 16 | @ModifyExpressionValue(method = "renderFirstPersonItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;isInvisible()Z")) 17 | private boolean dontRenderEmptyMainHandWhenCuddle(boolean original, @Local(argsOnly = true) AbstractClientPlayerEntity abstractClientPlayerEntity) { 18 | return original || Blahaj.holdsOnlyCuddlyItem(abstractClientPlayerEntity); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/render/LivingEntityRendererMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.render; 2 | 3 | import mc.recraftors.blahaj.Blahaj; 4 | import net.fabricmc.api.EnvType; 5 | import net.fabricmc.api.Environment; 6 | import net.minecraft.client.render.VertexConsumerProvider; 7 | import net.minecraft.client.render.entity.LivingEntityRenderer; 8 | import net.minecraft.client.render.entity.model.BipedEntityModel; 9 | import net.minecraft.client.render.entity.model.EntityModel; 10 | import net.minecraft.client.util.math.MatrixStack; 11 | import net.minecraft.entity.LivingEntity; 12 | import org.joml.Vector3f; 13 | import org.spongepowered.asm.mixin.Mixin; 14 | import org.spongepowered.asm.mixin.Shadow; 15 | import org.spongepowered.asm.mixin.Unique; 16 | import org.spongepowered.asm.mixin.injection.At; 17 | import org.spongepowered.asm.mixin.injection.Inject; 18 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 19 | 20 | @Environment(EnvType.CLIENT) 21 | @Mixin(LivingEntityRenderer.class) 22 | public abstract class LivingEntityRendererMixin > { 23 | @Shadow public abstract M getModel(); 24 | 25 | @Inject( 26 | method = "render(Lnet/minecraft/entity/LivingEntity;FFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", 27 | at = @At( 28 | value = "INVOKE", 29 | target = "Lnet/minecraft/client/util/math/MatrixStack;translate(FFF)V", 30 | ordinal = 0 31 | ) 32 | ) 33 | private void renderBipedSleepingCuddlingArms( 34 | T livingEntity, float f, float g, MatrixStack matrixStack, 35 | VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo ci) { 36 | blahaj$setArmsPos(livingEntity); 37 | } 38 | 39 | @Inject( 40 | method = "setupTransforms", 41 | at = @At( 42 | value = "INVOKE", 43 | target = "Lnet/minecraft/entity/LivingEntity;getSleepingDirection()Lnet/minecraft/util/math/Direction;", 44 | shift = At.Shift.BEFORE 45 | ) 46 | ) 47 | private void transformBipedSleepingCuddlingArms(T livingEntity, MatrixStack matrixStack, float f, 48 | float g, float h, CallbackInfo ci) { 49 | blahaj$setArmsPos(livingEntity); 50 | } 51 | 52 | @Unique 53 | private void blahaj$setArmsPos(T entity) { 54 | if (!(this.getModel() instanceof BipedEntityModel model) || !Blahaj.holdsOnlyCuddlyItem(entity)) { 55 | return; 56 | } 57 | Vector3f right = new Vector3f(-30f, -15f, 0); 58 | Vector3f left = new Vector3f(30f, -15f, 0); 59 | model.rightArm.rotate(right); 60 | model.leftArm.rotate(left); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/render/PlayerEntityRendererMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.render; 2 | 3 | import mc.recraftors.blahaj.Blahaj; 4 | import net.fabricmc.api.EnvType; 5 | import net.fabricmc.api.Environment; 6 | import net.minecraft.client.network.AbstractClientPlayerEntity; 7 | import net.minecraft.client.render.entity.EntityRendererFactory; 8 | import net.minecraft.client.render.entity.LivingEntityRenderer; 9 | import net.minecraft.client.render.entity.PlayerEntityRenderer; 10 | import net.minecraft.client.render.entity.model.BipedEntityModel; 11 | import net.minecraft.client.render.entity.model.PlayerEntityModel; 12 | import net.minecraft.util.Hand; 13 | import org.spongepowered.asm.mixin.Mixin; 14 | import org.spongepowered.asm.mixin.injection.At; 15 | import org.spongepowered.asm.mixin.injection.Inject; 16 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 17 | 18 | @Environment(EnvType.CLIENT) 19 | @Mixin(PlayerEntityRenderer.class) 20 | public abstract class PlayerEntityRendererMixin extends 21 | LivingEntityRenderer> { 22 | PlayerEntityRendererMixin(EntityRendererFactory.Context context, 23 | PlayerEntityModel entityModel, float f) { 24 | super(context, entityModel, f); 25 | } 26 | 27 | @Inject( 28 | method = "getArmPose", 29 | at = @At("TAIL"), 30 | cancellable = true 31 | ) 32 | private static void getCuddlePoseInjector(AbstractClientPlayerEntity player, Hand hand, 33 | CallbackInfoReturnable cir) { 34 | if (Blahaj.holdsOnlyCuddlyItem(player)) { 35 | cir.setReturnValue(BipedEntityModel.ArmPose.CROSSBOW_HOLD); 36 | cir.cancel(); 37 | } 38 | } 39 | 40 | @Inject(method = "getArmPose", at = @At("RETURN"), cancellable = true) 41 | private static void getCuddlySleepArmPose(AbstractClientPlayerEntity player, Hand hand, 42 | CallbackInfoReturnable cir) { 43 | if (Blahaj.holdsOnlyCuddlyItem(player)) cir.setReturnValue(BipedEntityModel.ArmPose.CROSSBOW_HOLD); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/render/ServerPlayerInteractionManagerMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.render; 2 | 3 | import mc.recraftors.blahaj.item.ItemContainerCuddlyItem; 4 | import mc.recraftors.blahaj.item.ItemStackProvider; 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraft.server.network.ServerPlayerInteractionManager; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 10 | 11 | @Mixin(ServerPlayerInteractionManager.class) 12 | public abstract class ServerPlayerInteractionManagerMixin { 13 | @ModifyVariable( 14 | method = "interactItem", 15 | name = "itemStack2", 16 | at = @At( 17 | value = "INVOKE", 18 | shift = At.Shift.AFTER, 19 | target = "Lnet/minecraft/server/network/ServerPlayerEntity;setStackInHand(Lnet/minecraft/util/Hand;Lnet/minecraft/item/ItemStack;)V" 20 | ) 21 | ) 22 | private ItemStack onInteractItemSetItemInHand(ItemStack value) { 23 | if (((ItemStackProvider)value).blahaj$getStack().getItem() instanceof ItemContainerCuddlyItem cuddly) { 24 | return cuddly.getContainedStack(value); 25 | } 26 | return value; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/mc/recraftors/blahaj/mixin/render/TooltipComponentMixin.java: -------------------------------------------------------------------------------- 1 | package mc.recraftors.blahaj.mixin.render; 2 | 3 | import mc.recraftors.blahaj.item.CuddlyContainerTooltipComponent; 4 | import mc.recraftors.blahaj.item.CuddlyContainerTooltipData; 5 | import net.fabricmc.api.EnvType; 6 | import net.fabricmc.api.Environment; 7 | import net.minecraft.client.gui.tooltip.TooltipComponent; 8 | import net.minecraft.client.item.TooltipData; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 13 | 14 | @Environment(EnvType.CLIENT) 15 | @Mixin(TooltipComponent.class) 16 | public interface TooltipComponentMixin { 17 | @Inject(method = "of(Lnet/minecraft/client/item/TooltipData;)Lnet/minecraft/client/gui/tooltip/TooltipComponent;", at = @At("HEAD"), cancellable = true) 18 | private static void ofComponentHeadInjector(TooltipData tooltipData, CallbackInfoReturnable cir) { 19 | if (tooltipData instanceof CuddlyContainerTooltipData data) { 20 | cir.setReturnValue(new CuddlyContainerTooltipComponent(data)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/blockstates/blahaj_backpack.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "facing=south": { "model": "blahaj:block/blahaj_backpack" }, 4 | "facing=east": { "model": "blahaj:block/blahaj_backpack","y":270 }, 5 | "facing=west": { "model": "blahaj:block/blahaj_backpack","y":90 }, 6 | "facing=north": { "model": "blahaj:block/blahaj_backpack","y":180 } 7 | } 8 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/icon.png -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "item.blahaj.blue_shark": "Soft Toy Shark", 3 | "item.blahaj.blue_shark.tooltip": "a.k.a. Blahaj", 4 | "item.blahaj.gray_shark": "Gray Toy Shark", 5 | "item.blahaj.gray_shark.tooltip": "a.k.a. Klappar Haj", 6 | "item.blahaj.trans_shark": "Pink Toy Shark", 7 | "item.blahaj.trans_shark.tooltip": "a.k.a. Beyou Blahaj", 8 | "item.blahaj.blue_whale": "Soft Toy Blue Whale", 9 | "item.blahaj.blue_whale.tooltip": "a.k.a. Blavingad. Holds a stack of items.", 10 | "item.blahaj.killer_whale": "Soft Toy Killer Whale", 11 | "item.blahaj.killer_whale.tooltip": "a.k.a. Blavingad. Holds a stack of items.", 12 | "item.blahaj.seal": "Seal plushie", 13 | "item.blahaj.seal.tooltip": "a.k.a. Sorensen", 14 | "item.blahaj.bread": "Bread Pillow", 15 | "item.blahaj.glitch": "§kGlitch Shark", 16 | "item.blahaj.glitch.tooltip": "a.k.a Glitched Blahaj. §kNo Signal", 17 | 18 | "tooltip.blahaj.owner.craft": "Crafted by %s", 19 | "tooltip.blahaj.owner.rename": "%s of %s", 20 | 21 | "block.blahaj.blahaj_backpack": "Blahaj Traveler's Backpack", 22 | 23 | "item.blahaj.blahaj_bass": "Blahaj Bass", 24 | 25 | "gamerule.blahaj.contained.enable_use": "Enable using contained items", 26 | "gamerule.blahaj.contained.enable_use.description": "§6⚠ Experimental§r and likely broken, use at your own risks. Relies on the blahaj:blavingad_usable item tag" 27 | } 28 | -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/lang/sv_se.json: -------------------------------------------------------------------------------- 1 | { 2 | "item.blahaj.blue_shark": "Mjukleksak Haj", 3 | "item.blahaj.blue_shark.tooltip": "alias Blåhaj", 4 | "item.blahaj.gray_shark": "Mjukleksak Gråhaj", 5 | "item.blahaj.gray_shark.tooltip": "alias Klappar Haj", 6 | "item.blahaj.trans_shark": "Mjukleksak Rosahaj", 7 | "item.blahaj.trans_shark.tooltip": "alias Beyou Blåhaj", 8 | "item.blahaj.blue_whale": "Mjukleksak Blåval", 9 | "item.blahaj.blue_whale.tooltip": "alias Blåvingad. Kan innehålla en hög med föremål", 10 | "item.blahaj.bread": "Brödkudde", 11 | "tooltip.blahaj.owner.craft": "Skapad av %s", 12 | "tooltip.blahaj.owner.rename": "%s av %s" 13 | } 14 | -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/models/block/blahaj_backpack.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "block/cube_all", 3 | "textures": { 4 | "all": "minecraft:block/blue_wool" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/models/item/blahaj_backpack.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "travelersbackpack:item/travelers_backpack" 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/models/item/blahaj_bass.json: -------------------------------------------------------------------------------- 1 | { 2 | "texture_size": [32, 32], 3 | "textures": { 4 | "1": "blahaj:item/blahaj_bass" 5 | }, 6 | "elements": [ 7 | { 8 | "name": "body_main", 9 | "from": [6, 0, 7], 10 | "to": [10, 10, 9], 11 | "faces": { 12 | "north": {"uv": [0, 0, 2, 5], "texture": "#1"}, 13 | "east": {"uv": [4, 0, 5, 5], "texture": "#1"}, 14 | "south": {"uv": [2, 0, 4, 5], "texture": "#1"}, 15 | "west": {"uv": [0, 5, 1, 10], "texture": "#1"}, 16 | "up": {"uv": [3, 7, 1, 6], "texture": "#1"}, 17 | "down": {"uv": [3, 5, 1, 6], "texture": "#1"} 18 | } 19 | }, 20 | { 21 | "name": "body_bottom", 22 | "from": [5, 3, 7], 23 | "to": [6, 9, 9], 24 | "faces": { 25 | "north": {"uv": [4.5, 5, 5, 8], "texture": "#1"}, 26 | "east": {"uv": [0, 13, 1, 16], "texture": "#1"}, 27 | "south": {"uv": [4, 5, 4.5, 8], "texture": "#1"}, 28 | "west": {"uv": [3, 5, 4, 8], "texture": "#1"}, 29 | "up": {"uv": [1.5, 7, 2, 8], "texture": "#1"}, 30 | "down": {"uv": [1, 7, 1.5, 8], "texture": "#1"} 31 | } 32 | }, 33 | { 34 | "name": "body_top", 35 | "from": [10, 3, 7], 36 | "to": [11, 9, 9], 37 | "faces": { 38 | "north": {"uv": [9, 4.125, 9.5, 7.125], "texture": "#1"}, 39 | "east": {"uv": [7.5, 4.125, 8.5, 7.125], "texture": "#1"}, 40 | "south": {"uv": [8.5, 4.125, 9, 7.125], "texture": "#1"}, 41 | "west": {"uv": [0, 13, 1, 16], "texture": "#1"}, 42 | "up": {"uv": [9.5, 5.125, 10, 6.125], "texture": "#1"}, 43 | "down": {"uv": [9.5, 4.125, 10, 5.125], "texture": "#1"} 44 | } 45 | }, 46 | { 47 | "name": "forehead", 48 | "from": [5.01, 6.01, 7], 49 | "to": [6.01, 8.135, 9], 50 | "rotation": {"angle": -45, "axis": "z", "origin": [0, 0, 0]}, 51 | "faces": { 52 | "north": {"uv": [6.5, 0, 7, 1.0625], "texture": "#1"}, 53 | "east": {"uv": [5.5, 0, 6.5, 1.0625], "texture": "#1"}, 54 | "south": {"uv": [5, 0, 5.5, 1.0625], "texture": "#1"}, 55 | "west": {"uv": [0, 14.9375, 1, 16], "texture": "#1"}, 56 | "up": {"uv": [0, 15, 0.5, 16], "texture": "#1"}, 57 | "down": {"uv": [0, 15, 0.5, 16], "texture": "#1"} 58 | } 59 | }, 60 | { 61 | "name": "mouf_top", 62 | "from": [6, 1.5, 7], 63 | "to": [7.5, 1.5, 9], 64 | "faces": { 65 | "north": {"uv": [0, 16, 0.75, 16], "texture": "#1"}, 66 | "east": {"uv": [0, 16, 1, 16], "texture": "#1"}, 67 | "south": {"uv": [0, 16, 0.75, 16], "texture": "#1"}, 68 | "west": {"uv": [0, 16, 1, 16], "texture": "#1"}, 69 | "up": {"uv": [0, 15, 0.75, 16], "texture": "#1"}, 70 | "down": {"uv": [2, 7, 2.75, 8], "texture": "#1"} 71 | } 72 | }, 73 | { 74 | "name": "mouf_side", 75 | "from": [7.5, 0, 7], 76 | "to": [7.5, 1.5, 9], 77 | "faces": { 78 | "north": {"uv": [0, 15.25, 0, 16], "texture": "#1"}, 79 | "east": {"uv": [0, 15.25, 1, 16], "texture": "#1"}, 80 | "south": {"uv": [0, 15.25, 0, 16], "texture": "#1"}, 81 | "west": {"uv": [1, 8, 2, 8.75], "texture": "#1"}, 82 | "up": {"uv": [0, 15, 0, 16], "texture": "#1"}, 83 | "down": {"uv": [0, 15, 0, 16], "texture": "#1"} 84 | } 85 | }, 86 | { 87 | "name": "back", 88 | "from": [9.5, -4.5, 7.5], 89 | "to": [13.5, -2.5, 8.5], 90 | "rotation": {"angle": 45, "axis": "z", "origin": [0, 0, 0]}, 91 | "faces": { 92 | "north": {"uv": [5, 2.125, 7, 3.125], "texture": "#1"}, 93 | "east": {"uv": [7, 2.5, 7.5, 3.5], "texture": "#1"}, 94 | "south": {"uv": [5, 1.125, 7, 2.125], "texture": "#1"}, 95 | "west": {"uv": [0, 15, 0.5, 16], "texture": "#1"}, 96 | "up": {"uv": [5, 3.625, 7, 4.125], "texture": "#1"}, 97 | "down": {"uv": [5, 3.125, 7, 3.625], "texture": "#1"} 98 | } 99 | }, 100 | { 101 | "name": "flipper", 102 | "from": [-1.875, 7, 7.5], 103 | "to": [0.125, 8.5, 8.5], 104 | "rotation": {"angle": -45, "axis": "z", "origin": [0, 0, 0]}, 105 | "faces": { 106 | "north": {"uv": [7, 1.75, 8, 2.5], "texture": "#1"}, 107 | "east": {"uv": [0, 15.25, 0.5, 16], "texture": "#1"}, 108 | "south": {"uv": [7, 0.5, 8, 1.25], "texture": "#1"}, 109 | "west": {"uv": [7.5, 2.5, 8, 3.25], "texture": "#1"}, 110 | "up": {"uv": [7, 1.25, 8, 1.75], "texture": "#1"}, 111 | "down": {"uv": [7, 0, 8, 0.5], "texture": "#1"} 112 | } 113 | }, 114 | { 115 | "name": "tail_main", 116 | "from": [7.25, 10, 7], 117 | "to": [8.75, 17, 8], 118 | "faces": { 119 | "north": {"uv": [5.75, 4.125, 6.5, 7.625], "texture": "#1"}, 120 | "east": {"uv": [6.5, 4.125, 7, 7.625], "texture": "#1"}, 121 | "south": {"uv": [5, 4.125, 5.75, 7.625], "texture": "#1"}, 122 | "west": {"uv": [7, 4.125, 7.5, 7.625], "texture": "#1"}, 123 | "up": {"uv": [0, 15.5, 0.75, 16], "texture": "#1"}, 124 | "down": {"uv": [0, 15.5, 0.75, 16], "texture": "#1"} 125 | } 126 | }, 127 | { 128 | "name": "tail_source", 129 | "from": [6.75, 10, 7], 130 | "to": [9.25, 10.5, 8.5], 131 | "faces": { 132 | "north": {"uv": [8, 1, 9.25, 1.25], "texture": "#1"}, 133 | "east": {"uv": [8, 1.5, 8.75, 1.75], "texture": "#1"}, 134 | "south": {"uv": [8, 0.75, 9.25, 1], "texture": "#1"}, 135 | "west": {"uv": [8, 1.25, 8.75, 1.5], "texture": "#1"}, 136 | "up": {"uv": [8, 0, 9.25, 0.75], "texture": "#1"}, 137 | "down": {"uv": [0, 15.25, 1.25, 16], "texture": "#1"} 138 | } 139 | }, 140 | { 141 | "name": "tail_small", 142 | "from": [17, 6, 7], 143 | "to": [18, 8, 8], 144 | "rotation": {"angle": 45, "axis": "z", "origin": [0, 0, 0]}, 145 | "faces": { 146 | "north": {"uv": [9.5, 2.375, 10, 3.375], "texture": "#1"}, 147 | "east": {"uv": [9, 2.375, 9.5, 3.375], "texture": "#1"}, 148 | "south": {"uv": [8.5, 2.375, 9, 3.375], "texture": "#1"}, 149 | "west": {"uv": [8, 2.375, 8.5, 3.375], "texture": "#1"}, 150 | "up": {"uv": [8, 1.875, 8.5, 2.375], "texture": "#1"}, 151 | "down": {"uv": [0, 15.5, 0.5, 16], "texture": "#1"} 152 | } 153 | }, 154 | { 155 | "name": "tail_up", 156 | "from": [17, 5, 7], 157 | "to": [19.5, 6.5, 8], 158 | "rotation": {"angle": 45, "axis": "z", "origin": [0, 0, 0]}, 159 | "faces": { 160 | "north": {"uv": [9.25, 0, 10, 1.25], "rotation": 270, "texture": "#1"}, 161 | "east": {"uv": [9.25, 1.25, 10, 1.75], "rotation": 90, "texture": "#1"}, 162 | "south": {"uv": [10, 0, 10.75, 1.25], "rotation": 90, "texture": "#1"}, 163 | "west": {"uv": [0, 15.5, 0.75, 16], "rotation": 90, "texture": "#1"}, 164 | "up": {"uv": [11.25, 0, 11.75, 1.25], "rotation": 90, "texture": "#1"}, 165 | "down": {"uv": [10.75, 0, 11.25, 1.25], "rotation": 90, "texture": "#1"} 166 | } 167 | }, 168 | { 169 | "name": "hole_cover", 170 | "from": [6, 3, 7.125], 171 | "to": [10, 7, 7.125], 172 | "faces": { 173 | "north": {"uv": [10, 1.25, 12, 3.25], "texture": "#1"}, 174 | "east": {"uv": [0, 14, 0, 16], "texture": "#1"}, 175 | "south": {"uv": [0, 14, 2, 16], "texture": "#1"}, 176 | "west": {"uv": [0, 14, 0, 16], "texture": "#1"}, 177 | "up": {"uv": [0, 16, 2, 16], "texture": "#1"}, 178 | "down": {"uv": [0, 16, 2, 16], "texture": "#1"} 179 | } 180 | }, 181 | { 182 | "name": "cords", 183 | "from": [7, 3, 6.875], 184 | "to": [9, 18, 6.875], 185 | "faces": { 186 | "north": {"uv": [12, 0, 13.5, 11.25], "texture": "#1"}, 187 | "east": {"uv": [0, 9, 0, 16], "texture": "#1"}, 188 | "south": {"uv": [13.5, 0, 12, 11.25], "texture": "#1"}, 189 | "west": {"uv": [0, 9, 0, 16], "texture": "#1"}, 190 | "up": {"uv": [0, 16, 1, 16], "texture": "#1"}, 191 | "down": {"uv": [0, 16, 1, 16], "texture": "#1"} 192 | } 193 | } 194 | ], 195 | "display": { 196 | "thirdperson_righthand": { 197 | "rotation": [-126, -172, -118], 198 | "translation": [-6.5, -1.75, 3.5], 199 | "scale": [1.25, 1.25, 1.25] 200 | }, 201 | "firstperson_righthand": { 202 | "rotation": [0, 0, 62], 203 | "translation": [-8.5, -2, 1.5], 204 | "scale": [1.5, 1.5, 1.5] 205 | }, 206 | "gui": { 207 | "rotation": [0, 180, 43], 208 | "translation": [-1, -1.25, 0] 209 | }, 210 | "fixed": { 211 | "translation": [0, -1.25, 0], 212 | "scale": [1.5, 1.5, 1.5] 213 | } 214 | }, 215 | "groups": [ 216 | { 217 | "name": "mody", 218 | "origin": [0, 0, 0], 219 | "color": 0, 220 | "children": [0, 1, 2, 3] 221 | }, 222 | { 223 | "name": "mouf", 224 | "origin": [0, 0, 0], 225 | "color": 0, 226 | "children": [4, 5] 227 | }, 228 | { 229 | "name": "fins", 230 | "origin": [0, 0, 0], 231 | "color": 0, 232 | "children": [6, 7] 233 | }, 234 | { 235 | "name": "tail", 236 | "origin": [0, 0, 0], 237 | "color": 0, 238 | "children": [8, 9, 10, 11] 239 | }, 240 | { 241 | "name": "instrumentality", 242 | "origin": [0, 0, 0], 243 | "color": 0, 244 | "children": [12, 13] 245 | } 246 | ] 247 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/models/item/blahaj_bass_hand.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "blahaj:item/blahaj_bass" 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/models/item/blue_shark.json: -------------------------------------------------------------------------------- 1 | { 2 | "texture_size": [32, 32], 3 | "textures": { 4 | "0": "blahaj:item/shork" 5 | }, 6 | "elements": [ 7 | { 8 | "name": "shork", 9 | "from": [6, 6, 0], 10 | "to": [10, 10, 9], 11 | "faces": { 12 | "north": {"uv": [4.5, 4.5, 6.5, 6.5], "texture": "#0"}, 13 | "east": {"uv": [0, 4.5, 4.5, 6.5], "texture": "#0"}, 14 | "south": {"uv": [11, 4.5, 13, 6.5], "texture": "#0"}, 15 | "west": {"uv": [6.5, 4.5, 11, 6.5], "texture": "#0"}, 16 | "up": {"uv": [6.5, 4.5, 4.5, 0], "texture": "#0"}, 17 | "down": {"uv": [8.5, 0, 6.5, 4.5], "texture": "#0"} 18 | } 19 | }, 20 | { 21 | "name": "tail", 22 | "from": [7, 7, 9], 23 | "to": [9, 9, 16], 24 | "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 15.5]}, 25 | "faces": { 26 | "north": {"uv": [3.5, 10, 4.5, 11], "texture": "#0"}, 27 | "east": {"uv": [0, 10, 3.5, 11], "texture": "#0"}, 28 | "south": {"uv": [8, 10, 9, 11], "texture": "#0"}, 29 | "west": {"uv": [4.5, 10, 8, 11], "texture": "#0"}, 30 | "up": {"uv": [4.5, 10, 3.5, 6.5], "texture": "#0"}, 31 | "down": {"uv": [5.5, 6.5, 4.5, 10], "texture": "#0"} 32 | } 33 | }, 34 | { 35 | "name": "tail base", 36 | "from": [6.5, 6.5, 9], 37 | "to": [9.5, 9.5, 11], 38 | "faces": { 39 | "north": {"uv": [1, 12, 2.5, 13.5], "texture": "#0"}, 40 | "east": {"uv": [0, 12, 1, 13.5], "texture": "#0"}, 41 | "south": {"uv": [3.5, 12, 5, 13.5], "texture": "#0"}, 42 | "west": {"uv": [2.5, 12, 3.5, 13.5], "texture": "#0"}, 43 | "up": {"uv": [2.5, 12, 1, 11], "texture": "#0"}, 44 | "down": {"uv": [4, 11, 2.5, 12], "texture": "#0"} 45 | } 46 | }, 47 | { 48 | "name": "tail stabilizer", 49 | "from": [7.5, 8, 14], 50 | "to": [8.5, 12, 16], 51 | "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 9, 15]}, 52 | "faces": { 53 | "north": {"uv": [1, 1, 1.5, 3], "texture": "#0"}, 54 | "east": {"uv": [0, 1, 1, 3], "texture": "#0"}, 55 | "south": {"uv": [2.5, 1, 3, 3], "texture": "#0"}, 56 | "west": {"uv": [1.5, 1, 2.5, 3], "texture": "#0"}, 57 | "up": {"uv": [1.5, 1, 1, 0], "texture": "#0"}, 58 | "down": {"uv": [2, 0, 1.5, 1], "texture": "#0"} 59 | } 60 | }, 61 | { 62 | "name": "left pectoral", 63 | "from": [5, 5, 6], 64 | "to": [6, 7, 10], 65 | "rotation": {"angle": 22.5, "axis": "x", "origin": [6, 7, 7]}, 66 | "faces": { 67 | "north": {"uv": [7.5, 8.5, 8, 9.5], "texture": "#0"}, 68 | "east": {"uv": [5.5, 8.5, 7.5, 9.5], "texture": "#0"}, 69 | "south": {"uv": [10, 8.5, 10.5, 9.5], "texture": "#0"}, 70 | "west": {"uv": [8, 8.5, 10, 9.5], "texture": "#0"}, 71 | "up": {"uv": [8, 8.5, 7.5, 6.5], "texture": "#0"}, 72 | "down": {"uv": [8.5, 6.5, 8, 8.5], "texture": "#0"} 73 | } 74 | }, 75 | { 76 | "name": "right pectoral", 77 | "from": [10, 5, 6], 78 | "to": [11, 7, 10], 79 | "shade": false, 80 | "rotation": {"angle": 22.5, "axis": "x", "origin": [10, 7, 7]}, 81 | "faces": { 82 | "north": {"uv": [8, 8.5, 7.5, 9.5], "texture": "#0"}, 83 | "east": {"uv": [10, 8.5, 8, 9.5], "texture": "#0"}, 84 | "south": {"uv": [10.5, 8.5, 10, 9.5], "texture": "#0"}, 85 | "west": {"uv": [7.5, 8.5, 5.5, 9.5], "texture": "#0"}, 86 | "up": {"uv": [7.5, 8.5, 8, 6.5], "texture": "#0"}, 87 | "down": {"uv": [8, 6.5, 8.5, 8.5], "texture": "#0"} 88 | } 89 | }, 90 | { 91 | "name": "dorsal fin", 92 | "from": [7, 9, 5], 93 | "to": [9, 14, 8], 94 | "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 7]}, 95 | "faces": { 96 | "north": {"uv": [10, 1.5, 11, 4], "texture": "#0"}, 97 | "east": {"uv": [8.5, 1.5, 10, 4], "texture": "#0"}, 98 | "south": {"uv": [12.5, 1.5, 13.5, 4], "texture": "#0"}, 99 | "west": {"uv": [11, 1.5, 12.5, 4], "texture": "#0"}, 100 | "up": {"uv": [11, 1.5, 10, 0], "texture": "#0"}, 101 | "down": {"uv": [12, 0, 11, 1.5], "texture": "#0"} 102 | } 103 | }, 104 | { 105 | "name": "back dorsal", 106 | "from": [7.5, 8.5, 12], 107 | "to": [8.5, 9.5, 13], 108 | "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 9, 12.5]}, 109 | "faces": { 110 | "north": {"uv": [2.5, 0.5, 3, 1], "texture": "#0"}, 111 | "east": {"uv": [2, 0.5, 2.5, 1], "texture": "#0"}, 112 | "south": {"uv": [3.5, 0.5, 4, 1], "texture": "#0"}, 113 | "west": {"uv": [3, 0.5, 3.5, 1], "texture": "#0"}, 114 | "up": {"uv": [3, 0.5, 2.5, 0], "texture": "#0"}, 115 | "down": {"uv": [3.5, 0, 3, 0.5], "texture": "#0"} 116 | } 117 | }, 118 | { 119 | "name": "mouf back", 120 | "from": [6, 6, 1], 121 | "to": [10, 7, 1], 122 | "faces": { 123 | "north": {"uv": [0, 3.5, 2, 4], "texture": "#0"}, 124 | "east": {"uv": [0, 3.5, 0, 4], "texture": "#0"}, 125 | "south": {"uv": [2, 3.5, 4, 4], "texture": "#0"}, 126 | "west": {"uv": [2, 3.5, 2, 4], "texture": "#0"}, 127 | "up": {"uv": [2, 3.5, 0, 3.5], "texture": "#0"}, 128 | "down": {"uv": [4, 3.5, 2, 3.5], "texture": "#0"} 129 | } 130 | }, 131 | { 132 | "name": "mouf top", 133 | "from": [6, 7, 0], 134 | "to": [10, 7, 1], 135 | "faces": { 136 | "north": {"uv": [0.5, 3.5, 2.5, 3.5], "texture": "#0"}, 137 | "east": {"uv": [0, 3.5, 0.5, 3.5], "texture": "#0"}, 138 | "south": {"uv": [3, 3.5, 5, 3.5], "texture": "#0"}, 139 | "west": {"uv": [2.5, 3.5, 3, 3.5], "texture": "#0"}, 140 | "up": {"uv": [2.5, 3.5, 0.5, 3], "texture": "#0"}, 141 | "down": {"uv": [4.5, 3, 2.5, 3.5], "texture": "#0"} 142 | } 143 | } 144 | ], 145 | "display": { 146 | "thirdperson_righthand": { 147 | "rotation": [140, -60, 105], 148 | "translation": [-5, -2.25, 3.75], 149 | "scale": [1.15, 1.15, 1.15] 150 | }, 151 | "firstperson_righthand": { 152 | "rotation": [70, -55, 60], 153 | "translation": [-3.25, 1.25, 1] 154 | }, 155 | "ground": { 156 | "rotation": [0, 90, 0], 157 | "translation": [0, 2, 0], 158 | "scale": [0.5, 0.5, 0.5] 159 | }, 160 | "gui": { 161 | "rotation": [30, 135, 0], 162 | "translation": [0.19, -0.25, 0], 163 | "scale": [1.15, 1.15, 1.15] 164 | }, 165 | "head": { 166 | "translation": [0, 9, 0], 167 | "scale": [1.25, 1.25, 1.25] 168 | }, 169 | "fixed": { 170 | "rotation": [0, -90, 0], 171 | "translation": [0, -1, -3] 172 | } 173 | } 174 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/models/item/blue_whale.json: -------------------------------------------------------------------------------- 1 | { 2 | "credit": "Made with Blockbench", 3 | "texture_size": [32, 32], 4 | "textures": { 5 | "0": "blahaj:item/blue_whale", 6 | "particle": "blahaj:item/blue_whale" 7 | }, 8 | "elements": [ 9 | { 10 | "name": "tail stabilizer", 11 | "from": [4, 7, 14], 12 | "to": [12, 9, 16], 13 | "rotation": {"angle": 0, "axis": "x", "origin": [8, 9, 15]}, 14 | "faces": { 15 | "north": {"uv": [7, 7, 11, 8], "texture": "#0"}, 16 | "east": {"uv": [6, 7, 7, 8], "texture": "#0"}, 17 | "south": {"uv": [12, 7, 16, 8], "texture": "#0"}, 18 | "west": {"uv": [11, 7, 12, 8], "texture": "#0"}, 19 | "up": {"uv": [11, 7, 7, 6], "texture": "#0"}, 20 | "down": {"uv": [15, 6, 11, 7], "texture": "#0"} 21 | } 22 | }, 23 | { 24 | "name": "right pectoral", 25 | "from": [11, 7, 3], 26 | "to": [15, 8, 5], 27 | "rotation": {"angle": -22.5, "axis": "y", "origin": [11, 7, 3]}, 28 | "faces": { 29 | "north": {"uv": [7, 9, 9, 9.5], "texture": "#0"}, 30 | "east": {"uv": [6, 9, 7, 9.5], "texture": "#0"}, 31 | "south": {"uv": [10, 9, 12, 9.5], "texture": "#0"}, 32 | "west": {"uv": [9, 9, 10, 9.5], "texture": "#0"}, 33 | "up": {"uv": [9, 9, 7, 8], "texture": "#0"}, 34 | "down": {"uv": [11, 8, 9, 9], "texture": "#0"} 35 | } 36 | }, 37 | { 38 | "name": "left pectoral", 39 | "from": [1, 7, 3], 40 | "to": [5, 8, 5], 41 | "rotation": {"angle": 22.5, "axis": "y", "origin": [5, 7, 3]}, 42 | "faces": { 43 | "north": {"uv": [1, 9.5, 3, 10], "texture": "#0"}, 44 | "east": {"uv": [0, 9.5, 1, 10], "texture": "#0"}, 45 | "south": {"uv": [4, 9.5, 6, 10], "texture": "#0"}, 46 | "west": {"uv": [3, 9.5, 4, 10], "texture": "#0"}, 47 | "up": {"uv": [3, 9.5, 1, 8.5], "texture": "#0"}, 48 | "down": {"uv": [5, 8.5, 3, 9.5], "texture": "#0"} 49 | } 50 | }, 51 | { 52 | "name": "whael", 53 | "from": [5, 6, 0], 54 | "to": [11, 10, 8], 55 | "faces": { 56 | "north": {"uv": [4, 4, 7, 6], "texture": "#0"}, 57 | "east": {"uv": [0, 4, 4, 6], "texture": "#0"}, 58 | "south": {"uv": [11, 4, 14, 6], "texture": "#0"}, 59 | "west": {"uv": [7, 4, 11, 6], "texture": "#0"}, 60 | "up": {"uv": [7, 4, 4, 0], "texture": "#0"}, 61 | "down": {"uv": [10, 0, 7, 4], "texture": "#0"} 62 | } 63 | }, 64 | { 65 | "name": "tail", 66 | "from": [6.5, 7, 11], 67 | "to": [9.5, 9, 14], 68 | "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 15.5]}, 69 | "faces": { 70 | "north": {"uv": [1.5, 7.5, 3, 8.5], "texture": "#0"}, 71 | "east": {"uv": [0, 7.5, 1.5, 8.5], "texture": "#0"}, 72 | "south": {"uv": [4.5, 7.5, 6, 8.5], "texture": "#0"}, 73 | "west": {"uv": [3, 7.5, 4.5, 8.5], "texture": "#0"}, 74 | "up": {"uv": [3, 7.5, 1.5, 6], "texture": "#0"}, 75 | "down": {"uv": [4.5, 6, 3, 7.5], "texture": "#0"} 76 | } 77 | }, 78 | { 79 | "name": "dorsal fin", 80 | "from": [7.5, 10, 5], 81 | "to": [8.5, 13, 7], 82 | "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 5]}, 83 | "faces": { 84 | "north": {"uv": [11, 1, 11.5, 2.5], "texture": "#0"}, 85 | "east": {"uv": [10, 1, 11, 2.5], "texture": "#0"}, 86 | "south": {"uv": [12.5, 1, 13, 2.5], "texture": "#0"}, 87 | "west": {"uv": [11.5, 1, 12.5, 2.5], "texture": "#0"}, 88 | "up": {"uv": [11.5, 1, 11, 0], "texture": "#0"}, 89 | "down": {"uv": [12, 0, 11.5, 1], "texture": "#0"} 90 | } 91 | }, 92 | { 93 | "from": [6, 6.5, 8], 94 | "to": [10, 9.5, 11], 95 | "faces": { 96 | "north": {"uv": [1.5, 11.5, 3.5, 13], "texture": "#0"}, 97 | "east": {"uv": [0, 11.5, 1.5, 13], "texture": "#0"}, 98 | "south": {"uv": [5, 11.5, 7, 13], "texture": "#0"}, 99 | "west": {"uv": [3.5, 11.5, 5, 13], "texture": "#0"}, 100 | "up": {"uv": [3.5, 11.5, 1.5, 10], "texture": "#0"}, 101 | "down": {"uv": [5.5, 10, 3.5, 11.5], "texture": "#0"} 102 | } 103 | } 104 | ], 105 | "display": { 106 | "thirdperson_righthand": { 107 | "rotation": [130, -60, 100], 108 | "translation": [-4, -1.5, 3.25], 109 | "scale": [1.1, 1.1, 1.1] 110 | }, 111 | "firstperson_righthand": { 112 | "rotation": [70, -55, 60], 113 | "translation": [-3.25, 1.25, 1] 114 | }, 115 | "ground": { 116 | "rotation": [0, 90, 0], 117 | "translation": [0, 2, 0], 118 | "scale": [0.5, 0.5, 0.5] 119 | }, 120 | "gui": { 121 | "rotation": [30, 135, 0], 122 | "translation": [-0.4, 0, 0], 123 | "scale": [0.98, 0.98, 0.98] 124 | }, 125 | "head": { 126 | "translation": [0, 9, 0], 127 | "scale": [1.25, 1.25, 1.25] 128 | }, 129 | "fixed": { 130 | "rotation": [0, -90, 0], 131 | "translation": [0, -1, -3] 132 | } 133 | } 134 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/models/item/bread.json: -------------------------------------------------------------------------------- 1 | { 2 | "texture_size": [32, 32], 3 | "textures": { 4 | "0": "blahaj:item/bred", 5 | "particle": "#0" 6 | }, 7 | "elements": [ 8 | { 9 | "name": "shork", 10 | "from": [5, 5, -1], 11 | "to": [11, 11, 16], 12 | "faces": { 13 | "north": {"uv": [8.5, 3, 11.5, 6], "texture": "#0"}, 14 | "east": {"uv": [0, 0, 8.5, 3], "texture": "#0"}, 15 | "south": {"uv": [8.5, 0, 11.5, 3], "texture": "#0"}, 16 | "west": {"uv": [0, 3, 8.5, 6], "texture": "#0"}, 17 | "up": {"uv": [3, 14.5, 0, 6], "texture": "#0"}, 18 | "down": {"uv": [6, 6, 3, 14.5], "texture": "#0"} 19 | } 20 | } 21 | ], 22 | "display": { 23 | "thirdperson_righthand": { 24 | "rotation": [-48.96, 12.4, -13.43], 25 | "translation": [-3.75, -2.5, 3] 26 | }, 27 | "firstperson_righthand": { 28 | "rotation": [-90, 32, 0], 29 | "translation": [-4.5, 1.25, 1] 30 | }, 31 | "ground": { 32 | "scale": [0.5, 0.5, 0.5] 33 | }, 34 | "gui": { 35 | "rotation": [30, 135, 0], 36 | "translation": [0.36, 0, 0], 37 | "scale": [0.98, 0.98, 0.98] 38 | }, 39 | "head": { 40 | "rotation": [0, 90, 0], 41 | "translation": [0, 10, 0], 42 | "scale": [1.25, 1.25, 1.25] 43 | }, 44 | "fixed": { 45 | "rotation": [0, -90, 0], 46 | "translation": [0, -1, -3.5] 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/models/item/glitch.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "blahaj:item/blue_shark", 3 | "textures": { 4 | "0": "blahaj:item/glitch" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/models/item/gray_shark.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "blahaj:item/blue_shark", 3 | "textures": { 4 | "0": "blahaj:item/gray_shork" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/models/item/killer_whale.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "blahaj:item/blue_whale", 3 | "textures": { 4 | "0": "blahaj:item/killer_whale", 5 | "particle": "blahaj:item/killer_whale" 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/models/item/seal.json: -------------------------------------------------------------------------------- 1 | { 2 | "texture_size": [32, 32], 3 | "textures": { 4 | "0": "blahaj:item/seal", 5 | "particle": "blahaj:item/seal" 6 | }, 7 | "elements": [ 8 | { 9 | "name": "mainBody", 10 | "from": [4, 0, 3], 11 | "to": [12, 6, 13], 12 | "rotation": {"angle": 0, "axis": "y", "origin": [0, -1, 0]}, 13 | "faces": { 14 | "north": {"uv": [4, 1.5, 6, 3], "texture": "#0"}, 15 | "east": {"uv": [0, 2.5, 2.5, 4], "texture": "#0"}, 16 | "south": {"uv": [4, 0, 6, 1.5], "texture": "#0"}, 17 | "west": {"uv": [0, 4, 2.5, 5.5], "texture": "#0"}, 18 | "up": {"uv": [2, 2.5, 0, 0], "texture": "#0"}, 19 | "down": {"uv": [4, 0, 2, 2.5], "texture": "#0"} 20 | } 21 | }, 22 | { 23 | "name": "leftSide", 24 | "from": [3, 1, 4], 25 | "to": [4, 5, 12], 26 | "rotation": {"angle": 0, "axis": "y", "origin": [0, -1, 0]}, 27 | "faces": { 28 | "north": {"uv": [8.5, 0, 8.75, 1], "texture": "#0"}, 29 | "east": {"uv": [6, 0, 8, 1], "texture": "#0"}, 30 | "south": {"uv": [8.5, 1, 8.75, 2], "texture": "#0"}, 31 | "west": {"uv": [6, 1, 8, 2], "texture": "#0"}, 32 | "up": {"uv": [8.25, 0, 8.5, 2], "texture": "#0"}, 33 | "down": {"uv": [8, 0, 8.25, 2], "texture": "#0"} 34 | } 35 | }, 36 | { 37 | "name": "rightSide", 38 | "from": [12, 1, 4], 39 | "to": [13, 5, 12], 40 | "rotation": {"angle": 0, "axis": "y", "origin": [16, -1, 0]}, 41 | "faces": { 42 | "north": {"uv": [8.75, 0, 8.5, 1], "texture": "#0"}, 43 | "east": {"uv": [8, 1, 6, 2], "texture": "#0"}, 44 | "south": {"uv": [8.75, 1, 8.5, 2], "texture": "#0"}, 45 | "west": {"uv": [8, 0, 6, 1], "texture": "#0"}, 46 | "up": {"uv": [8.5, 0, 8.25, 2], "texture": "#0"}, 47 | "down": {"uv": [8.25, 0, 8, 2], "texture": "#0"} 48 | } 49 | }, 50 | { 51 | "name": "front", 52 | "from": [5, 1, 2], 53 | "to": [11, 5, 3], 54 | "rotation": {"angle": 0, "axis": "y", "origin": [0, -1, 0]}, 55 | "faces": { 56 | "north": {"uv": [0, 5.5, 3, 7.5], "texture": "#0"}, 57 | "east": {"uv": [3, 5.5, 3.5, 7.5], "texture": "#0"}, 58 | "south": {"uv": [3.5, 5.5, 6.5, 7.5], "texture": "#0"}, 59 | "west": {"uv": [6.5, 5.5, 7, 7.5], "texture": "#0"}, 60 | "up": {"uv": [6.5, 5.5, 3.5, 5], "texture": "#0"}, 61 | "down": {"uv": [3, 7.5, 0, 8], "texture": "#0"} 62 | } 63 | }, 64 | { 65 | "name": "back", 66 | "from": [5, 1, 13], 67 | "to": [11, 5, 14], 68 | "rotation": {"angle": 0, "axis": "y", "origin": [0, -1, 0]}, 69 | "faces": { 70 | "north": {"uv": [0.25, 8.25, 1.75, 9.25], "texture": "#0"}, 71 | "east": {"uv": [1.75, 8.25, 2, 9.25], "texture": "#0"}, 72 | "south": {"uv": [2, 8.25, 3.5, 9.25], "texture": "#0"}, 73 | "west": {"uv": [0, 8.25, 0.25, 9.25], "texture": "#0"}, 74 | "up": {"uv": [1.75, 8.25, 0.25, 8], "texture": "#0"}, 75 | "down": {"uv": [1.75, 9.25, 0.25, 9.5], "texture": "#0"} 76 | } 77 | }, 78 | { 79 | "name": "tail", 80 | "from": [7.5, 3, 14], 81 | "to": [8.5, 4, 15.5], 82 | "rotation": {"angle": 0, "axis": "y", "origin": [0, -1, 0]}, 83 | "faces": { 84 | "north": {"uv": [3.75, 8.75, 4, 9], "texture": "#0"}, 85 | "east": {"uv": [3.75, 7.75, 4.25, 8], "texture": "#0"}, 86 | "south": {"uv": [4, 8.75, 4.25, 9], "texture": "#0"}, 87 | "west": {"uv": [3.75, 8, 4.25, 8.25], "texture": "#0"}, 88 | "up": {"uv": [4.25, 8.75, 4, 8.25], "texture": "#0"}, 89 | "down": {"uv": [4, 8.25, 3.75, 8.75], "texture": "#0"} 90 | } 91 | }, 92 | { 93 | "name": "flipperLeft", 94 | "from": [7, 2, 14], 95 | "to": [7.5, 3.25, 16], 96 | "rotation": {"angle": 45, "axis": "z", "origin": [7, 2, 2]}, 97 | "faces": { 98 | "north": {"uv": [4.5, 8.75, 5, 9.75], "texture": "#0"}, 99 | "east": {"uv": [4.5, 7.75, 5.5, 8.25], "texture": "#0"}, 100 | "south": {"uv": [5, 8.75, 5.5, 9.75], "texture": "#0"}, 101 | "west": {"uv": [4.5, 8.25, 5.5, 8.75], "texture": "#0"}, 102 | "up": {"uv": [5.5, 7.75, 5.75, 8.75], "texture": "#0"}, 103 | "down": {"uv": [5.75, 7.75, 6, 8.75], "texture": "#0"} 104 | } 105 | }, 106 | { 107 | "name": "flipperRight", 108 | "from": [8.5, 2, 14], 109 | "to": [9, 3.25, 16], 110 | "rotation": {"angle": -45, "axis": "z", "origin": [9, 2, 2]}, 111 | "faces": { 112 | "north": {"uv": [7.75, 7.75, 7.5, 8.75], "texture": "#0"}, 113 | "east": {"uv": [7.25, 8.25, 6.25, 8.75], "texture": "#0"}, 114 | "south": {"uv": [7.5, 7.75, 7.25, 8.75], "texture": "#0"}, 115 | "west": {"uv": [7.25, 7.75, 6.25, 8.25], "texture": "#0"}, 116 | "up": {"uv": [6.75, 8.75, 6.25, 9.75], "texture": "#0"}, 117 | "down": {"uv": [7.25, 8.75, 6.75, 9.75], "texture": "#0"} 118 | } 119 | }, 120 | { 121 | "name": "nose", 122 | "from": [7, 2.5, 1.5], 123 | "to": [9, 3, 2], 124 | "rotation": {"angle": 0, "axis": "y", "origin": [7, 3, 2]}, 125 | "faces": { 126 | "north": {"uv": [7.25, 6.25, 8.25, 6.5], "texture": "#0"}, 127 | "east": {"uv": [7.25, 6.75, 7.5, 7], "texture": "#0"}, 128 | "south": {"uv": [7.25, 6.5, 8.25, 6.75], "texture": "#0"}, 129 | "west": {"uv": [7.5, 6.75, 7.75, 7], "texture": "#0"}, 130 | "up": {"uv": [7.25, 5.75, 8.25, 6], "texture": "#0"}, 131 | "down": {"uv": [7.25, 6, 8.25, 6.25], "texture": "#0"} 132 | } 133 | }, 134 | { 135 | "name": "leftFlipper", 136 | "from": [1, 0, 4.25], 137 | "to": [4, 0.5, 6.25], 138 | "rotation": {"angle": 22.5, "axis": "z", "origin": [1, 0, 4]}, 139 | "faces": { 140 | "north": {"uv": [0, 12, 1.5, 12.25], "texture": "#0"}, 141 | "east": {"uv": [0, 11.75, 1, 12], "texture": "#0"}, 142 | "south": {"uv": [0, 12.25, 1.5, 12.5], "texture": "#0"}, 143 | "west": {"uv": [1, 11.75, 2, 12], "texture": "#0"}, 144 | "up": {"uv": [0, 9.75, 1.5, 10.75], "texture": "#0"}, 145 | "down": {"uv": [0, 10.75, 1.5, 11.75], "texture": "#0"} 146 | } 147 | }, 148 | { 149 | "name": "rightFlipper", 150 | "from": [12, 0, 4.25], 151 | "to": [15, 0.5, 6.25], 152 | "rotation": {"angle": -22.5, "axis": "z", "origin": [15, 0, 4]}, 153 | "faces": { 154 | "north": {"uv": [3.75, 12, 2.25, 12.25], "texture": "#0"}, 155 | "east": {"uv": [3.25, 11.75, 2.25, 12], "texture": "#0"}, 156 | "south": {"uv": [3.75, 12.25, 2.25, 12.5], "texture": "#0"}, 157 | "west": {"uv": [4.25, 11.75, 3.25, 12], "texture": "#0"}, 158 | "up": {"uv": [3.75, 9.75, 2.25, 10.75], "texture": "#0"}, 159 | "down": {"uv": [3.75, 10.75, 2.25, 11.75], "texture": "#0"} 160 | } 161 | } 162 | ], 163 | "display": { 164 | "thirdperson_righthand": { 165 | "rotation": [90, -45, 100], 166 | "translation": [-8.25, 2.75, 1] 167 | }, 168 | "firstperson_righthand": { 169 | "rotation": [-55, -145, -20], 170 | "translation": [-12, 5.5, -4.75], 171 | "scale": [1.25, 1.25, 1.25] 172 | }, 173 | "ground": { 174 | "translation": [0, 0.5, 0], 175 | "scale": [0.5, 0.5, 0.5] 176 | }, 177 | "gui": { 178 | "rotation": [180, 56, -150], 179 | "translation": [1.25, 3, 0] 180 | }, 181 | "head": { 182 | "translation": [0, 14, 0] 183 | }, 184 | "fixed": { 185 | "rotation": [-90, 90, 0], 186 | "translation": [0, 0, -8] 187 | } 188 | }, 189 | "groups": [ 190 | 0, 191 | { 192 | "name": "poofs", 193 | "origin": [8, 8, 8], 194 | "color": 0, 195 | "children": [1, 2, 3, 4] 196 | }, 197 | { 198 | "name": "tail", 199 | "origin": [8, 8, 8], 200 | "color": 0, 201 | "children": [5, 6, 7] 202 | }, 203 | { 204 | "name": "face", 205 | "origin": [8, 8, 8], 206 | "color": 0, 207 | "children": [8] 208 | }, 209 | { 210 | "name": "flippers", 211 | "origin": [8, 8, 8], 212 | "color": 0, 213 | "children": [9, 10] 214 | } 215 | ] 216 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/models/item/trans_shark.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "blahaj:item/blue_shark", 3 | "textures": { 4 | "0": "blahaj:item/beyou_shork" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/sounds.json: -------------------------------------------------------------------------------- 1 | { 2 | "blahaj_bass.c1": {"sounds": ["blahaj:instruments/blahaj_bass/c1"]}, 3 | "blahaj_bass.c2": {"sounds": ["blahaj:instruments/blahaj_bass/c2"]}, 4 | "blahaj_bass.c3": {"sounds": ["blahaj:instruments/blahaj_bass/c3"]}, 5 | "blahaj_bass.c4": {"sounds": ["blahaj:instruments/blahaj_bass/c4"]}, 6 | "blahaj_bass.c5": {"sounds": ["blahaj:instruments/blahaj_bass/c5"]}, 7 | "blahaj_bass.c6": {"sounds": ["blahaj:instruments/blahaj_bass/c6"]}, 8 | "blahaj_bass.c7": {"sounds": ["blahaj:instruments/blahaj_bass/c7"]}, 9 | "blahaj_bass.c8": {"sounds": ["blahaj:instruments/blahaj_bass/c8"]} 10 | } -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c1.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c2.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c3.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c4.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c5.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c5.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c6.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c6.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c7.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c7.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c8.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/sounds/instruments/blahaj_bass/c8.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/textures/item/beyou_shork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/textures/item/beyou_shork.png -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/textures/item/blahaj_bass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/textures/item/blahaj_bass.png -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/textures/item/blue_whale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/textures/item/blue_whale.png -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/textures/item/bred.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/textures/item/bred.png -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/textures/item/glitch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/textures/item/glitch.png -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/textures/item/gray_shork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/textures/item/gray_shork.png -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/textures/item/killer_whale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/textures/item/killer_whale.png -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/textures/item/seal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/textures/item/seal.png -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/textures/item/shork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/textures/item/shork.png -------------------------------------------------------------------------------- /src/main/resources/assets/blahaj/textures/model/blahaj_backpack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecraftorsMC/blahaj/d8f15145f39fcf5327de1742b2f11dbd2980766b/src/main/resources/assets/blahaj/textures/model/blahaj_backpack.png -------------------------------------------------------------------------------- /src/main/resources/blahaj.accesswidener: -------------------------------------------------------------------------------- 1 | accessWidener v2 named 2 | 3 | accessible field net/minecraft/loot/LootTable pools [Lnet/minecraft/loot/LootPool; 4 | extendable class net/minecraft/item/ItemStack -------------------------------------------------------------------------------- /src/main/resources/blahaj.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "package": "mc.recraftors.blahaj.mixin", 5 | "compatibilityLevel": "JAVA_17", 6 | "plugin": "mc.recraftors.blahaj.mixin.compat.Plugin", 7 | "mixins": [ 8 | "AnvilScreenHandlerMixin", 9 | "EnchantmentMixin", 10 | "ForgingScreenHandlerMixin", 11 | "ItemGroupsMixin", 12 | "ItemMixin", 13 | "ItemsMixin", 14 | "ItemStackMixin", 15 | "LivingEntityMixin", 16 | "LootManagerMixin", 17 | "LootTableMixin", 18 | "MinecraftServerMixin", 19 | "RecipeManagerMixin", 20 | "ServerRecipeBookMixin", 21 | "compat.andromeda.present.AutoAdvGenerationMixin", 22 | "compat.immersive_melodies.present.ItemsMixin", 23 | "compat.travelersbackpack.present.ModBlockEntityTypesMixin", 24 | "compat.travelersbackpack.present.ModBlocksMixin", 25 | "compat.travelersbackpack.present.ModItemGroupsMixin", 26 | "compat.travelersbackpack.present.ModItemsMixin", 27 | "compat.travelersbackpack.present.ResourceUtilsMixin" 28 | ], 29 | "client": [ 30 | "ClientPlayNetworkHandlerMixin", 31 | "compat.notenoughanimations.present.HeldItemHandlerMixin", 32 | "compat.notenoughanimations.present.SleepAnimationMixin", 33 | "compat.travelersbackpack.and.trinkets.TravelersBackpackWearableModelMixin", 34 | "compat.trinkets.present.BlahajMixin", 35 | "compat.trinkets.present.CapeFeatureRendererMixin", 36 | "compat.trinkets.present.CuddlyItemMixin", 37 | "compat.trinkets.present.PlayerEntityModelMixin", 38 | "render.AllayEntityMixin", 39 | "render.BipedEntityModelMixin", 40 | "render.HeldItemRendererMixin", 41 | "render.LivingEntityRendererMixin", 42 | "render.PlayerEntityRendererMixin", 43 | "render.TooltipComponentMixin" 44 | ], 45 | "injectors": { 46 | "defaultRequire": 1 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/resources/data/blahaj/loot_tables/blocks/blahaj_backpack.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:block", 3 | "pools": [ 4 | { 5 | "bonus_rolls": 0.0, 6 | "conditions": [ 7 | { 8 | "condition": "minecraft:survives_explosion" 9 | } 10 | ], 11 | "entries": [ 12 | { 13 | "type": "minecraft:item", 14 | "functions": [ 15 | { 16 | "function": "minecraft:copy_name", 17 | "source": "block_entity" 18 | }, 19 | { 20 | "function": "minecraft:copy_nbt", 21 | "ops": [ 22 | { 23 | "op": "replace", 24 | "source": "Tier", 25 | "target": "Tier" 26 | }, 27 | { 28 | "op": "replace", 29 | "source": "Inventory", 30 | "target": "Inventory" 31 | }, 32 | { 33 | "op": "replace", 34 | "source": "CraftingInventory", 35 | "target": "CraftingInventory" 36 | }, 37 | { 38 | "op": "replace", 39 | "source": "LeftTank", 40 | "target": "LeftTank" 41 | }, 42 | { 43 | "op": "replace", 44 | "source": "LeftTankAmount", 45 | "target": "LeftTankAmount" 46 | }, 47 | { 48 | "op": "replace", 49 | "source": "RightTank", 50 | "target": "RightTank" 51 | }, 52 | { 53 | "op": "replace", 54 | "source": "RightTankAmount", 55 | "target": "RightTankAmount" 56 | }, 57 | { 58 | "op": "replace", 59 | "source": "Ability", 60 | "target": "Ability" 61 | }, 62 | { 63 | "op": "replace", 64 | "source": "LastTime", 65 | "target": "LastTime" 66 | }, 67 | { 68 | "op": "replace", 69 | "source": "UnsortableSlots", 70 | "target": "UnsortableSlots" 71 | }, 72 | { 73 | "op": "replace", 74 | "source": "MemorySlots", 75 | "target": "MemorySlots" 76 | }, 77 | { 78 | "op": "replace", 79 | "source": "CraftingSettings", 80 | "target": "CraftingSettings" 81 | } 82 | ], 83 | "source": "block_entity" 84 | }, 85 | { 86 | "conditions": [ 87 | { 88 | "condition": "travelersbackpack:has_color" 89 | } 90 | ], 91 | "function": "minecraft:copy_nbt", 92 | "ops": [ 93 | { 94 | "op": "replace", 95 | "source": "Color", 96 | "target": "Color" 97 | } 98 | ], 99 | "source": "block_entity" 100 | }, 101 | { 102 | "conditions": [ 103 | { 104 | "condition": "travelersbackpack:has_sleeping_bag_color" 105 | } 106 | ], 107 | "function": "minecraft:copy_nbt", 108 | "ops": [ 109 | { 110 | "op": "replace", 111 | "source": "SleepingBagColor", 112 | "target": "SleepingBagColor" 113 | } 114 | ], 115 | "source": "block_entity" 116 | } 117 | ], 118 | "name": "blahaj:blahaj_backpack" 119 | } 120 | ], 121 | "rolls": 1.0 122 | } 123 | ] 124 | } -------------------------------------------------------------------------------- /src/main/resources/data/blahaj/recipes/blahaj_backpack.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "travelersbackpack:backpack_shapeless", 3 | "ingredients": [ 4 | { 5 | "item": "travelersbackpack:standard" 6 | }, 7 | { 8 | "item": "blahaj:blue_whale" 9 | } 10 | ], 11 | "result": { 12 | "item": "blahaj:blahaj_backpack" 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/data/blahaj/recipes/blahaj_bass.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | " I", 5 | "WN ", 6 | "BW " 7 | ], 8 | "key": { 9 | "I": { 10 | "item": "minecraft:iron_block" 11 | }, 12 | "W": { 13 | "item": "minecraft:light_blue_wool" 14 | }, 15 | "N": { 16 | "item": "minecraft:note_block" 17 | }, 18 | "B": { 19 | "item": "blahaj:blue_shark" 20 | } 21 | }, 22 | "result": { 23 | "item": "blahaj:blahaj_bass" 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/resources/data/blahaj/recipes/blavingad_orca.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:smithing_transform", 3 | "base": { 4 | "item": "blahaj:blue_whale" 5 | }, 6 | "addition": { 7 | "item": "minecraft:white_dye" 8 | }, 9 | "template": { 10 | "item": "minecraft:black_dye" 11 | }, 12 | "result": { 13 | "item": "blahaj:killer_whale" 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/resources/data/blahaj/recipes/blue_shark.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | " # ", 5 | "###", 6 | "PW " 7 | ], 8 | "key": { 9 | "#": { 10 | "item": "minecraft:light_blue_wool" 11 | }, 12 | "P": { 13 | "item": "minecraft:pink_dye" 14 | }, 15 | "W": { 16 | "item": "minecraft:white_wool" 17 | } 18 | }, 19 | "result": { 20 | "item": "blahaj:blue_shark", 21 | "count": 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/resources/data/blahaj/recipes/blue_whale.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | " # ", 5 | "###", 6 | "GW " 7 | ], 8 | "key": { 9 | "#": { 10 | "item": "minecraft:blue_wool" 11 | }, 12 | "G": { 13 | "item": "minecraft:light_gray_wool" 14 | }, 15 | "W": { 16 | "item": "minecraft:white_wool" 17 | } 18 | }, 19 | "result": { 20 | "item": "blahaj:blue_whale", 21 | "count": 1 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/resources/data/blahaj/recipes/bread.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "OOO", 5 | "OOO" 6 | ], 7 | "key": { 8 | "O": { 9 | "item": "minecraft:orange_wool" 10 | } 11 | }, 12 | "result": { 13 | "item": "blahaj:bread", 14 | "count": 1 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/data/blahaj/recipes/seal.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "###", 5 | "B#W" 6 | ], 7 | "key": { 8 | "#": { 9 | "item": "minecraft:light_gray_wool" 10 | }, 11 | "B": { 12 | "item": "minecraft:black_wool" 13 | }, 14 | "W": { 15 | "item": "minecraft:white_wool" 16 | } 17 | }, 18 | "result": { 19 | "item": "blahaj:seal", 20 | "count": 1 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/resources/data/blahaj/tags/items/blavingad_usable.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:potion", 4 | "minecraft:splash_potion", 5 | "minecraft:lingering_potion", 6 | { 7 | "id": "#c:potions", 8 | "required": false 9 | }, 10 | "minecraft:experience_bottle", 11 | "minecraft:totem_of_undying" 12 | ] 13 | } -------------------------------------------------------------------------------- /src/main/resources/data/blahaj/tags/items/cuddly_items.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "blahaj:blue_shark", 4 | "blahaj:gray_shark", 5 | "blahaj:trans_shark", 6 | "blahaj:trans_shark", 7 | "blahaj:blue_whale", 8 | "blahaj:killer_whale", 9 | "blahaj:bread", 10 | "blahaj:glitch" 11 | ] 12 | } -------------------------------------------------------------------------------- /src/main/resources/data/blahaj/tags/items/non_containable.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "blahaj:blue_whale" 4 | ] 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/c/tags/items/hidden_from_recipe_viewers.json: -------------------------------------------------------------------------------- 1 | { 2 | "replace": false, 3 | "values": [ 4 | "blahaj:glitch" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/main/resources/data/travelersbackpack/tags/items/custom_travelers_backpack.json: -------------------------------------------------------------------------------- 1 | { 2 | "replace": false, 3 | "values": [ 4 | { 5 | "id": "blahaj:blahaj_backpack", 6 | "required": false 7 | } 8 | ] 9 | } -------------------------------------------------------------------------------- /src/main/resources/data/trinkets/tags/items/chest/back.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "#blahaj:cuddly_items", 4 | { 5 | "id": "blahaj:blahaj_backpack", 6 | "required": false 7 | } 8 | ] 9 | } -------------------------------------------------------------------------------- /src/main/resources/data/trinkets/tags/items/chest/cape.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "#blahaj:cuddly_items" 4 | ] 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/trinkets/tags/items/chest/necklace.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "#blahaj:cuddly_items" 4 | ] 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/trinkets/tags/items/chest/shoulder.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "#blahaj:cuddly_items" 4 | ] 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/trinkets/tags/items/head/crown.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "#blahaj:cuddly_items" 4 | ] 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/trinkets/tags/items/head/hat.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "#blahaj:cuddly_items" 4 | ] 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/trinkets/tags/items/legs/belt.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "#blahaj:cuddly_items" 4 | ] 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/trinkets/tags/items/legs/thighs.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "#blahaj:cuddly_items" 4 | ] 5 | } -------------------------------------------------------------------------------- /src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "blahaj", 4 | "version": "${version}", 5 | "name": "Blahaj Expanded", 6 | "description": "BLAHAJ", 7 | "authors": [ 8 | { 9 | "name": "Recraftors MC", 10 | "role": "Group", 11 | "contact": { 12 | "homepage": "https://codeberg.org/RecraftorsMC" 13 | } 14 | }, 15 | { 16 | "name": "hibi", 17 | "role": "Original mod owner", 18 | "contact": { 19 | "homepage": "https://github.com/Hibiii" 20 | } 21 | }, 22 | { 23 | "name": "Nerjal Nosk", 24 | "role": "maintainer", 25 | "contact": { 26 | "homepage": "https://codeberg.org/NerjalNosk" 27 | } 28 | }, 29 | { 30 | "name": "KayoticCarnige", 31 | "role": "artist", 32 | "contact": { 33 | "homepage": "https://github.com/kckarnige" 34 | } 35 | } 36 | ], 37 | "contact": { 38 | "sources": "https://codeberg.org/RecraftorsMC/blahaj", 39 | "homepage": "https://modrinth.com/mod/mcr_blahaj", 40 | "issues": "https://codeberg.org/RecraftorsMC/blahaj/issues" 41 | }, 42 | "license": "GPL 3.0", 43 | "icon": "assets/blahaj/icon.png", 44 | "environment": "*", 45 | "entrypoints": { 46 | "main": [ 47 | "mc.recraftors.blahaj.Blahaj" 48 | ] 49 | }, 50 | "mixins": [ 51 | "blahaj.mixins.json" 52 | ], 53 | "depends": { 54 | "fabricloader": ">=0.15.2", 55 | "minecraft": "1.20.1", 56 | "unruled_api": "*" 57 | }, 58 | "accessWidener": "blahaj.accesswidener" 59 | } 60 | --------------------------------------------------------------------------------