diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml new file mode 100644 index 0000000..ce5d912 --- /dev/null +++ b/.github/workflows/gradle.yml @@ -0,0 +1,29 @@ +name: Build + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build with Gradle + run: ./gradlew build + - name: Upload jar + uses: actions/upload-artifact@v1 + with: + name: Artifacts + path: build/libs/ \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ead6b55 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# eclipse +bin +*.launch +.settings +.metadata +.classpath +.project + +# idea +out +*.ipr +*.iws +*.iml +.idea + +# gradle +build +.gradle + +# other +eclipse +run +*.psd +*.bat \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..a8ca584 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# **Toolbreak Warning** +> With this plugin you can prevent breaking your expensive tools, especially when you're mining with high efficiency enchantments and/or haste. + +### You can customize these Settings: +- If the addon is enabled or not +- The message that pops up, when your tool's durability is low +- At what percentage of durability the warning should come (customizable for each tooltype) + +### Installation +1. Press `Win` + `R` +2. Paste this into the window that popped up: `%appdata%/.minecraft/LabyMod/addons-1.12` and press enter +3. It should open your Labymod addon directory; Paste the [Toolbreak_Warning.jar](https://github.com/RappyTV/Toolbreak-Warning/releases/download/1.0.0/Toolbreak_Warning.jar) in there. +4. Launch your Labymod client. + +If you have any problems with the addon/have update ideas, feel free to +- Open an Issue [here](https://github.com/RappyTV/Toolbreak-Warning/issues/new/choose) + or +- Open a ticket on my [Discord Server](https://rappytv.com/server) in [this](https://discord.com/channels/815912035124248587/840285653946204181) channel + +--- + +### Social Networks + +[RappyTV | Website][website] +[RappyTV | YouTube][youtube] +[RappyTV | Instagram][instagram] +[RappyTV | Discord][dcServer] +[RappyTV | TikTok][tiktok] + +[website]: https://rappytv.com/ +[youtube]: https://youtube.com/c/RappyTVTutorials +[instagram]: https://instagram.com/rappyytv +[dcbotplaylist]: https://youtube.com/playlist?list=PL-NddfqjbJVZ2-CGquW0I42J9IGUkXq12 +[dcServer]: https://rappytv.com/server +[dcBot]: https://rappytv.com/bot +[tiktok]: https://tiktok.com/@rappytv \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..7dbf167 --- /dev/null +++ b/build.gradle @@ -0,0 +1,83 @@ +buildscript { + repositories { + jcenter() + maven { url = "http://files.minecraftforge.net/maven" } + } + dependencies { + classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' + } +} +apply plugin: 'net.minecraftforge.gradle.forge' +//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. + + +version = "1.0" +group = "com.yourname.modid" // http://maven.apache.org/guides/mini/guide-naming-conventions.html +archivesBaseName = "modid" + +sourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +compileJava { + sourceCompatibility = targetCompatibility = '1.8' +} + +minecraft { + version = "1.12.2-14.23.5.2768" + runDir = "run" + + // the mappings can be changed at any time, and must be in the following format. + // snapshot_YYYYMMDD snapshot are built nightly. + // stable_# stables are built at the discretion of the MCP team. + // Use non-default mappings at your own risk. they may not always work. + // simply re-run your setup task after changing the mappings to update your workspace. + mappings = "snapshot_20171003" + // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. +} + +dependencies { + // you may put jars on which you depend on in ./libs + // or you may define them like so.. + //compile "some.group:artifact:version:classifier" + //compile "some.group:artifact:version" + + // real examples + //compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env + //compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env + + // the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime. + //provided 'com.mod-buildcraft:buildcraft:6.0.8:dev' + + // the deobf configurations: 'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided, + // except that these dependencies get remapped to your current MCP mappings + //deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev' + //deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev' + + // for more info... + // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html + // http://www.gradle.org/docs/current/userguide/dependency_management.html + +} + +processResources { + // this will ensure that this task is redone when the versions change. + inputs.property "version", project.version + inputs.property "mcversion", project.minecraft.version + + // replace stuff in mcmod.info, nothing else + from(sourceSets.main.resources.srcDirs) { + include 'mcmod.info' + + // replace version and mcversion + expand 'version':project.version, 'mcversion':project.minecraft.version + } + + // copy everything else except the mcmod.info + from(sourceSets.main.resources.srcDirs) { + exclude 'mcmod.info' + } +} + +reobf { + jar { + useNotchSrg() + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..e9b9fd5 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,3 @@ +# Sets default memory used for gradle commands. Can be overridden by user or command line properties. +# This is required to provide enough memory for the Minecraft decompilation process. +org.gradle.jvmargs=-Xmx3G diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..30d399d 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..e18cba7 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Sep 14 12:28:28 PDT 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..91a7e26 --- /dev/null +++ b/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# 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 +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# 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\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +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" ] ; 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"` + + # 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 + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/libs/labymod-1.12.2.jar b/libs/labymod-1.12.2.jar new file mode 100644 index 0000000..4e8e162 Binary files /dev/null and b/libs/labymod-1.12.2.jar differ diff --git a/src/main/java/com/rappytv/prevtb/events/ToolUse.java b/src/main/java/com/rappytv/prevtb/events/ToolUse.java new file mode 100644 index 0000000..91d7491 --- /dev/null +++ b/src/main/java/com/rappytv/prevtb/events/ToolUse.java @@ -0,0 +1,32 @@ +package com.rappytv.prevtb.events; + +import com.rappytv.prevtb.main.Main; +import com.rappytv.prevtb.util.Util; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +public class ToolUse { + + @SubscribeEvent + public void onUse(BlockEvent.BreakEvent e) { + if(!Main.enabled) return; + EntityPlayer p = e.getPlayer(); + ItemStack i = p.getHeldItemMainhand(); + + if(i == null) return; + if(!i.isItemStackDamageable()) return; + if(p.isCreative()) return; + + if(Util.isPickaxe(i)) { + Util.pickaxeUsed(i); + } + else if(Util.isAxe(i)) { + Util.axeUsed(i); + } + else if(Util.isShovel(i)) { + Util.shovelUsed(i); + } + } +} diff --git a/src/main/java/com/rappytv/prevtb/main/Main.java b/src/main/java/com/rappytv/prevtb/main/Main.java new file mode 100644 index 0000000..bd0127f --- /dev/null +++ b/src/main/java/com/rappytv/prevtb/main/Main.java @@ -0,0 +1,140 @@ +package com.rappytv.prevtb.main; + +import com.rappytv.prevtb.events.ToolUse; +import net.labymod.api.LabyModAddon; +import net.labymod.settings.elements.*; +import net.labymod.utils.Consumer; +import net.labymod.utils.Material; + +import java.util.List; + +public class Main extends LabyModAddon { + + public static boolean enabled = true; + public static String warnMsg = "\u00A7cDo you really want to continue using this tool? Its durability is {durability}%!"; + public static int warnPercentagePickaxe = 5; + public static int warnPercentageAxe = 5; + public static int warnPercentageShovel = 5; + public static Main instance; + + @Override + public void onEnable() { + // Sets the instance + instance = this; + + getApi().registerForgeListener(new ToolUse()); + } + + @Override + public void loadConfig() { + enabled = !getConfig().has("warn.enabled") || getConfig().get("warn.enabled").getAsBoolean(); + warnMsg = getConfig().has("warn.warnmsg") ? getConfig().get("warn.warnmsg").getAsString() : warnMsg; + + warnPercentagePickaxe = getConfig().has("warn.pick") ? getConfig().get("warn.pick").getAsInt() : warnPercentagePickaxe; + warnPercentageAxe = getConfig().has("warn.axe") ? getConfig().get("warn.axe").getAsInt() : warnPercentageAxe; + warnPercentageShovel = getConfig().has("warn.shovel") ? getConfig().get("warn.shovel").getAsInt() : warnPercentageShovel; + } + + @Override + protected void fillSettings(List list) { + BooleanElement enabledBool = new BooleanElement("Enabled", new ControlElement.IconData(Material.LEVER), new Consumer() { + + @Override + public void accept(Boolean accepted) { + enabled = accepted; + + getConfig().addProperty("warn.enabled", enabled); + saveConfig(); + } + }, enabled); + + StringElement warnmsg = new StringElement("Warn Message", new ControlElement.IconData(Material.REDSTONE_TORCH_ON), warnMsg, new Consumer() { + + @Override + public void accept(String accepted) { + warnMsg = accepted; + + getConfig().addProperty("warn.msg", warnMsg); + saveConfig(); + } + }); + + SliderElement pickSlider = new SliderElement("Pickaxe Warn Percentage", + new ControlElement.IconData(Material.IRON_PICKAXE), warnPercentagePickaxe); + SliderElement axeSlider = new SliderElement( "Axe Warn Percentage", + new ControlElement.IconData(Material.IRON_AXE), warnPercentageAxe); + SliderElement spadeSlider = new SliderElement( "Shovel Warn Percentage", + new ControlElement.IconData(Material.IRON_SPADE), warnPercentageShovel); + + { + // Setting the slider's min & max values + pickSlider.setRange(1, 25); + + // Setting slider steps + pickSlider.setSteps(1); + + // Adding change listener + pickSlider.addCallback(new Consumer() { + + @Override + public void accept(Integer accepted) { + warnPercentagePickaxe = accepted; + + getConfig().addProperty("warn.pick", warnPercentagePickaxe); + saveConfig(); + } + }); + } + + { + // Setting the slider's min & max values + axeSlider.setRange(1, 25); + + // Setting slider steps + axeSlider.setSteps(1); + + // Adding change listener + axeSlider.addCallback(new Consumer() { + + @Override + public void accept(Integer accepted) { + warnPercentageAxe = accepted; + + getConfig().addProperty("warn.axe", warnPercentageAxe); + saveConfig(); + } + }); + } + + { + // Setting the slider's min & max values + spadeSlider.setRange(1, 25); + + // Setting slider steps + spadeSlider.setSteps(1); + + // Adding change listener + spadeSlider.addCallback(new Consumer() { + + @Override + public void accept(Integer accepted) { + warnPercentageShovel = accepted; + + getConfig().addProperty("warn.shovel", warnPercentageShovel); + saveConfig(); + } + }); + } + + // Adding setting + list.add(enabledBool); + list.add(warnmsg); + list.add(pickSlider); + list.add(axeSlider); + list.add(spadeSlider); + } + + public static Main getMain() { + return instance; + } +} diff --git a/src/main/java/com/rappytv/prevtb/util/Util.java b/src/main/java/com/rappytv/prevtb/util/Util.java new file mode 100644 index 0000000..b15dac6 --- /dev/null +++ b/src/main/java/com/rappytv/prevtb/util/Util.java @@ -0,0 +1,61 @@ +package com.rappytv.prevtb.util; + +import com.rappytv.prevtb.main.Main; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiChat; +import net.minecraft.item.*; + +public class Util { + + public static void msg(String text) { + Main.getMain().getApi().displayMessageInChat(text); + } + + public static boolean isAxe(ItemStack i) { + return i.getItem() instanceof ItemAxe; + } + + public static boolean isPickaxe(ItemStack i) { + return i.getItem() instanceof ItemPickaxe; + } + + public static boolean isShovel(ItemStack i) { + return i.getItem() instanceof ItemSpade; + } + + public static void pickaxeUsed(ItemStack itemStack) { + Item i = itemStack.getItem(); + + int itemWarnInt = (Main.warnPercentagePickaxe * i.getMaxDamage(itemStack)) / 100; + int itemUsedInt = i.getMaxDamage(itemStack) - i.getDamage(itemStack); + + if(itemUsedInt == itemWarnInt) { + msg(Main.warnMsg.replace("{durability}", Main.warnPercentagePickaxe + "")); + Minecraft.getMinecraft().displayGuiScreen(new GuiChat()); + } + } + + public static void axeUsed(ItemStack itemStack) { + Item i = itemStack.getItem(); + + int itemWarnInt = (Main.warnPercentageAxe * i.getMaxDamage(itemStack)) / 100; + int itemUsedInt = i.getMaxDamage(itemStack) - i.getDamage(itemStack); + + if(itemUsedInt == itemWarnInt) { + msg(Main.warnMsg.replace("{durability}", Main.warnPercentageAxe + "")); + Minecraft.getMinecraft().displayGuiScreen(new GuiChat()); + } + } + + public static void shovelUsed(ItemStack itemStack) { + Item i = itemStack.getItem(); + + int itemWarnInt = (Main.warnPercentageShovel * i.getMaxDamage(itemStack)) / 100; + int itemUsedInt = i.getMaxDamage(itemStack) - i.getDamage(itemStack); + + if(itemUsedInt == itemWarnInt) { + msg(Main.warnMsg.replace("{durability}", Main.warnPercentageShovel + "")); + Minecraft.getMinecraft().displayGuiScreen(new GuiChat()); + } + } +} diff --git a/src/main/resources/addon.json b/src/main/resources/addon.json new file mode 100644 index 0000000..8358bab --- /dev/null +++ b/src/main/resources/addon.json @@ -0,0 +1,10 @@ +{ + "uuid": "%uuid%", + "name": "ToolBreak Warning", + "mainClass": "com.rappytv.prevtb.main.Main", + "description": "Stops you from using your currently used tool when its almost destroyed. [CUSTOMIZABLE]", + "version": 1.0, + "author": "RappyTV#6969", + "category": 2, + "icon": "https://cdn.discordapp.com/attachments/962708390805655593/974731356137467995/icon.png" +} \ No newline at end of file diff --git a/src/main/resources/icon.png b/src/main/resources/icon.png new file mode 100644 index 0000000..604f684 Binary files /dev/null and b/src/main/resources/icon.png differ