diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..82036e9 --- /dev/null +++ b/build.gradle @@ -0,0 +1,77 @@ +plugins { + id 'fabric-loom' version '0.11-SNAPSHOT' + id 'maven-publish' +} + +sourceCompatibility = 17 +targetCompatibility = 17 + +archivesBaseName = "${modid}" +version = "${version}" + "-" + project.minecraft_version + +repositories { + maven { url = "https://maven.fabricmc.net/" } + mavenLocal() +} + +dependencies { + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +tasks.withType(JavaCompile).configureEach { + // ensure that the encoding is set to UTF-8, no matter what the system default is + // this fixes some edge cases with special characters not displaying correctly + // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html + // If Javadoc is generated, this must be specified in that task too. + it.options.encoding = "UTF-8" + + // Minecraft 1.17 (21w19a) upwards uses Java 16. + it.options.release = 17 +} + +java { + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() +} + +jar { + from("LICENSE") { + rename { "${it}_${project.archivesBaseName}"} + } +} + +// configure the maven publication +publishing { + publications { + mavenJava(MavenPublication) { + // add all the jars that should be included when publishing to maven + artifact(remapJar) { + builtBy remapJar + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + // Notice: This block does NOT have the same function as the block in the top level. + // The repositories here will be used for publishing your artifact, not for + // retrieving dependencies. + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..f88b94e --- /dev/null +++ b/gradle.properties @@ -0,0 +1,15 @@ +#Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx1G + +## Minecraft & Fabric Dependency Versions +minecraft_version = 1.19 +# https://maven.fabricmc.net/net/fabricmc/yarn +yarn_mappings = 1.19+build.1 +# https://maven.fabricmc.net/net/fabricmc/fabric-loader +loader_version = 0.14.6 + +## Mod Information +version=1.3.2 +modid=betterdroppeditems + +fabric_version=0.55.2+1.19 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..29953ea Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..54e9a60 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..f91a4fe --- /dev/null +++ b/settings.gradle @@ -0,0 +1,9 @@ +pluginManagement { + repositories { + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + gradlePluginPortal() + } +} diff --git a/src/main/java/bdi/mixin/ItemEntityMixin.java b/src/main/java/bdi/mixin/ItemEntityMixin.java new file mode 100644 index 0000000..b7b64a6 --- /dev/null +++ b/src/main/java/bdi/mixin/ItemEntityMixin.java @@ -0,0 +1,27 @@ +package bdi.mixin; + +import bdi.util.ItemEntityRotator; +import net.minecraft.entity.ItemEntity; +import net.minecraft.util.math.Vec3d; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(ItemEntity.class) +public class ItemEntityMixin implements ItemEntityRotator { + private Vec3d rotation = new Vec3d(0, 0, 0); + + public Vec3d getRotation() { + return rotation; + } + + public void setRotation(Vec3d rotation) { + this.rotation = rotation; + } + + public void addRotation(Vec3d rotation) { + this.rotation.add(rotation); + } + + public void addRotation(double x, double y, double z) { + this.rotation.add(x, y, z); + } +} diff --git a/src/main/java/bdi/mixin/ItemEntityRendererMixin.java b/src/main/java/bdi/mixin/ItemEntityRendererMixin.java new file mode 100644 index 0000000..78154a7 --- /dev/null +++ b/src/main/java/bdi/mixin/ItemEntityRendererMixin.java @@ -0,0 +1,237 @@ +package bdi.mixin; + +import bdi.util.ItemEntityRotator; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.block.ShapeContext; +import net.minecraft.block.SkullBlock; +import net.minecraft.client.render.OverlayTexture; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.EntityRenderer; +import net.minecraft.client.render.entity.EntityRendererFactory; +import net.minecraft.client.render.entity.ItemEntityRenderer; +import net.minecraft.client.render.item.ItemRenderer; +import net.minecraft.client.render.model.BakedModel; +import net.minecraft.client.render.model.json.ModelTransformation; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.ItemEntity; +import net.minecraft.item.*; +import net.minecraft.tag.FluidTags; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3f; +import net.minecraft.util.shape.VoxelShape; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.Random; + +@Mixin(ItemEntityRenderer.class) +public abstract class ItemEntityRendererMixin extends EntityRenderer { + + @Final private final Random random = new Random(); + @Final private ItemRenderer itemRenderer; + + private int getRenderedAmount(ItemStack stack) { + int i = 1; + if (stack.getCount() > 48) { + i = 5; + } else if (stack.getCount() > 32) { + i = 4; + } else if (stack.getCount() > 16) { + i = 3; + } else if (stack.getCount() > 1) { + i = 2; + } + + return i; + } + + private ItemEntityRendererMixin(EntityRendererFactory.Context dispatcher) { + super(dispatcher); + } + + @Inject(at = @At("RETURN"), method = "") + private void onConstructor(EntityRendererFactory.Context context, CallbackInfo ci) { + this.shadowRadius = 0; + } + + @Inject(at = @At("HEAD"), method = "render(Lnet/minecraft/entity/ItemEntity;FFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", cancellable = true) + private void render(ItemEntity dropped, float f, float partialTicks, MatrixStack matrix, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo callback) { + ItemStack itemStack = dropped.getStack(); + + // setup seed for random rotation + int seed = itemStack.isEmpty() ? 187 : Item.getRawId(itemStack.getItem()) + itemStack.getDamage(); + this.random.setSeed(seed); + + matrix.push(); + BakedModel bakedModel = this.itemRenderer.getModel(itemStack, dropped.world, null, seed); + boolean hasDepthInGui = bakedModel.hasDepth(); + + // decide how many item layers to render + int renderCount = this.getRenderedAmount(itemStack); + + // Helper for manipulating data on the current ItemEntity + ItemEntityRotator rotator = (ItemEntityRotator) dropped; + + // Certain BlockItems (Grass Block, Jukebox, Dirt, Ladders) are fine being rotated 180 degrees like standard items. + // Other BlockItems (Carpet, Slab) do not like being rotated and should stay flat. + // To determine whether a block should be flat or rotated, we check the collision box height. + // Anything that takes up more than half a block vertically is rotated. + boolean renderBlockFlat = false; + if(dropped.getStack().getItem() instanceof BlockItem && !(dropped.getStack().getItem() instanceof AliasedBlockItem)) { + Block b = ((BlockItem) dropped.getStack().getItem()).getBlock(); + VoxelShape shape = b.getOutlineShape(b.getDefaultState(), dropped.world, dropped.getBlockPos(), ShapeContext.absent()); + + // Only blocks with a collision box of <.5 should be rendered flat + if(shape.getMax(Direction.Axis.Y) <= .5) { + renderBlockFlat = true; + } + } + + // Make full blocks flush with ground + Item item = dropped.getStack().getItem(); + if(item instanceof BlockItem && !(item instanceof AliasedBlockItem) && !renderBlockFlat) { + // make blocks flush with the ground + matrix.translate(0, -0.06, 0); + } + + // Give all non-flat items a 90* spin + if(!renderBlockFlat) { + matrix.translate(0, .185, .0); + matrix.multiply(Vec3f.POSITIVE_X.getRadialQuaternion(1.571F)); + matrix.translate(0, -.185, -.0); + } + + // Item is flying through air + boolean isAboveWater = dropped.world.getBlockState(dropped.getBlockPos()).getFluidState().getFluid().isIn(FluidTags.WATER); + if(!dropped.isOnGround() && (!dropped.isSubmergedInWater() && !isAboveWater)) { + float rotation = ((float) dropped.getItemAge() + partialTicks) / 20.0F + dropped.getHeight(); // calculate rotation based on age and ticks + + // 90* items/blocks (non-flat) get spin on Z axis, flat items/blocks get spin on Y axis + if(!renderBlockFlat) { + // rotate renderer + matrix.translate(0, .185, .0); + matrix.multiply(Vec3f.POSITIVE_Z.getRadialQuaternion(rotation)); + matrix.translate(0, -.185, .0); + + // save rotation in entity + rotator.setRotation(new Vec3d(0, 0, rotation)); + } else { + // rotate renderer + matrix.multiply(Vec3f.POSITIVE_Y.getRadialQuaternion(rotation)); + + // save rotation in entity + rotator.setRotation(new Vec3d(0, rotation, 0)); + + // Translate down to become flush with floor + matrix.translate(0, -.065, 0); + } + + // Carrots/Potatoes/Redstone/other crops in air need vertical offset + if(dropped.getStack().getItem() instanceof AliasedBlockItem) { + matrix.translate(0, 0, .195); + } + + else if (!(dropped.getStack().getItem() instanceof BlockItem)) { + // Translate down to become flush with floor + matrix.translate(0, 0, .195); + } + } + + // Carrots/Potatoes/Redstone/other crops on ground + else if(dropped.getStack().getItem() instanceof AliasedBlockItem){ + matrix.translate(0, .185, .0); + matrix.multiply(Vec3f.POSITIVE_Z.getRadialQuaternion((float) rotator.getRotation().z)); + matrix.translate(0, -.185, .0); + + // Translate down to become flush with floor + matrix.translate(0, 0, .195); + } + + // Ladders/Slabs/Carpet and other short blocks on ground + else if(renderBlockFlat) { + matrix.multiply(Vec3f.POSITIVE_Y.getRadialQuaternion((float) rotator.getRotation().y)); + + // Translate down to become flush with floor + matrix.translate(0, -.065, 0); + } + + + // Normal blocks/items on ground + else { + // Translate normal items down to become flush with floor + if (!(dropped.getStack().getItem() instanceof BlockItem)) { + matrix.translate(0, 0, .195); + } + + matrix.translate(0, .185, .0); + matrix.multiply(Vec3f.POSITIVE_Z.getRadialQuaternion((float) rotator.getRotation().z)); + matrix.translate(0, -.185, .0); + } + + // special-case soul sand + if(dropped.world.getBlockState(dropped.getBlockPos()).getBlock().equals(Blocks.SOUL_SAND)) { + matrix.translate(0, 0, -.1); + } + + // special-case skulls + if(dropped.getStack().getItem() instanceof BlockItem) { + if(((BlockItem) dropped.getStack().getItem()).getBlock() instanceof SkullBlock) { + matrix.translate(0, .11, 0); + } + } + + float scaleX = bakedModel.getTransformation().ground.scale.getX(); + float scaleY = bakedModel.getTransformation().ground.scale.getY(); + float scaleZ = bakedModel.getTransformation().ground.scale.getZ(); + + float x; + float y; + if (!hasDepthInGui) { + float r = -0.0F * (float)(renderCount) * 0.5F * scaleX; + x = -0.0F * (float)(renderCount) * 0.5F * scaleY; + y = -0.09375F * (float)(renderCount) * 0.5F * scaleZ; + matrix.translate(r, x, y); + } + + // render each item in the stack on the ground (higher stack count == more items displayed) + for(int u = 0; u < renderCount; ++u) { + matrix.push(); + + // random positioning for rendered items, is especially seen in 64 block stacks on the ground + if (u > 0) { + if (hasDepthInGui) { + x = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F; + y = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F; + float z = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F; + matrix.translate(x, y, z); + } else { + x = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F * 0.5F; + y = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F * 0.5F; + matrix.translate(x, y, 0.0D); + matrix.multiply(Vec3f.POSITIVE_Z.getRadialQuaternion(this.random.nextFloat())); + } + } + + // render item + this.itemRenderer.renderItem(itemStack, ModelTransformation.Mode.GROUND, false, matrix, vertexConsumerProvider, i, OverlayTexture.DEFAULT_UV, bakedModel); + + // end + matrix.pop(); + + // translate based on scale, which gies vertical layering to high stack count items + if (!hasDepthInGui) { + matrix.translate(0.0F * scaleX, 0.0F * scaleY, 0.0625F * scaleZ); + } + } + + // end + matrix.pop(); + super.render(dropped, f, partialTicks, matrix, vertexConsumerProvider, i); + callback.cancel(); + } +} diff --git a/src/main/java/bdi/util/ItemEntityRotator.java b/src/main/java/bdi/util/ItemEntityRotator.java new file mode 100644 index 0000000..ac8eb7b --- /dev/null +++ b/src/main/java/bdi/util/ItemEntityRotator.java @@ -0,0 +1,13 @@ +package bdi.util; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.util.math.Vec3d; + +@Environment(EnvType.CLIENT) +public interface ItemEntityRotator { + Vec3d getRotation(); + void setRotation(Vec3d rotation); + void addRotation(Vec3d rotation); + void addRotation(double x, double y, double z); +} diff --git a/src/main/resources/assets/betterdroppeditems/icon.png b/src/main/resources/assets/betterdroppeditems/icon.png new file mode 100644 index 0000000..fbcfe5c Binary files /dev/null and b/src/main/resources/assets/betterdroppeditems/icon.png differ diff --git a/src/main/resources/betterdroppeditems.mixins.json b/src/main/resources/betterdroppeditems.mixins.json new file mode 100644 index 0000000..6f30d01 --- /dev/null +++ b/src/main/resources/betterdroppeditems.mixins.json @@ -0,0 +1,12 @@ +{ + "required": true, + "package": "bdi.mixin", + "compatibilityLevel": "JAVA_17", + "client": [ + "ItemEntityMixin", + "ItemEntityRendererMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..95fff24 --- /dev/null +++ b/src/main/resources/fabric.mod.json @@ -0,0 +1,29 @@ +{ + "schemaVersion": 1, + "id": "betterdroppeditems", + "version": "${version}", + "name": "Better Dropped Items", + "description": "Improves the visuals of dropped items!", + "authors": [ + "Draylar", + "Yuuki" + ], + "contact": { + "homepage": "https://www.curseforge.com/minecraft/mc-mods/better-dropped-items", + "sources": "https://github.com/Draylar/better-dropped-items", + "issues": "https://github.com/Draylar/better-dropped-items/issues/" + }, + + "license": "MIT", + "icon": "assets/betterdroppeditems/icon.png", + + "environment": "client", + "mixins": [ + "betterdroppeditems.mixins.json" + ], + + "depends": { + "fabricloader": ">=0.14.3", + "fabric": "*" + } +} \ No newline at end of file