diff --git a/.github/workflows/blob-build.yml b/.github/workflows/blob-build.yml index ae69bea..8e74189 100644 --- a/.github/workflows/blob-build.yml +++ b/.github/workflows/blob-build.yml @@ -10,17 +10,28 @@ jobs: if: startsWith(github.event.head_commit.message, '[CI skip]') == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up JDK 21 uses: actions/setup-java@v4 with: - java-version: 17 + java-version: 21 distribution: temurin - - name: Build with Maven - run: mvn package --file pom.xml + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Build with Gradle + run: ./gradlew clean shadowJar + + - name: Rename jar file + run: mv build/libs/ExtraHeads-*.jar build/libs/ExtraHeads.jar + - name: Upload to Blob Builds uses: WalshyDev/blob-builds/gh-action@main with: project: ExtraHeads + file: ./build/libs/ExtraHeads.jar apiToken: ${{ secrets.BLOB_BUILDS_API_TOKEN }} releaseNotes: ${{ github.event.head_commit.message }} diff --git a/.github/workflows/maven.yml b/.github/workflows/ci.yml similarity index 51% rename from .github/workflows/maven.yml rename to .github/workflows/ci.yml index 991b086..375cb7d 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/ci.yml @@ -1,3 +1,5 @@ +name: Java CI + on: push: branches: @@ -11,11 +13,17 @@ jobs: if: startsWith(github.event.head_commit.message, '[CI skip]') == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up JDK 21 uses: actions/setup-java@v4 with: - java-version: 17 + java-version: 21 distribution: temurin - - name: Build with Maven - run: mvn package --file pom.xml + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Build with Gradle + run: ./gradlew clean shadowJar diff --git a/.gitignore b/.gitignore index 6a60859..0b14b1c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,24 @@ -.classpath +.gradle +**/build/ +!src/**/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Avoid ignore Gradle wrappper properties +!gradle-wrapper.properties + +# Cache of project +.gradletasknamecache + +# Eclipse Gradle plugin generated files +# Eclipse Core .project -*.iml -/.idea/ -/.settings/ -/bin/ -/target/ -dependency-reduced-pom.xml \ No newline at end of file +# JDT-specific (Eclipse Java Development Tools) +.classpath + +.idea/ +vscode/ diff --git a/README.md b/README.md index 1b1dd88..cfebf4b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # ExtraHeads -ExtraHeads is a [Slimefun4](https://github.com/Slimefun/Slimefun4/) Addon.
+ExtraHeads is a [Slimefun4](https://github.com/Slimefun/Slimefun4/) Addon. You need to install Slimefun4 in order for this plugin to work. ExtraHeads is a Slimefun4 Addon that simply adds new mob heads to the game. @@ -9,6 +9,9 @@ You can increase your chances by using a Sword of Beheading. ## Download ExtraHeads You can download ExtraHeads right here: [Dev Builds](https://blob.build/project/ExtraHeads) +### Requirements +- Java 21+ +- Minecraft 1.18+ ## Discord You can find Slimefun's community on Discord! diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..3156542 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,58 @@ +plugins { + id("java") + id("maven-publish") + id("io.freefair.lombok") version "8.7.1" + id("com.gradleup.shadow") version "8.3.0" + id("net.minecrell.plugin-yml.bukkit") version "0.6.0" +} + +repositories { + mavenCentral() + maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") + maven("https://repo.papermc.io/repository/maven-public/") + maven("https://jitpack.io") + maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") +} + +dependencies { + compileOnly("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT") + compileOnly("com.github.Slimefun:Slimefun4:e02a0f61d1") + compileOnly("me.clip:placeholderapi:2.11.6") + implementation("org.bstats:bstats-bukkit:3.0.3") + implementation("com.google.code.findbugs:jsr305:3.0.2") + implementation("net.guizhanss:guizhanlib-all:2.0.0-SNAPSHOT") +} + +group = "io.github.thebusybiscuit" +version = "UNOFFICIAL" + +java { + sourceCompatibility = JavaVersion.VERSION_21 +} + +publishing { + publications.create("maven") { + from(components["java"]) + } +} + +tasks.shadowJar { + fun doRelocate(from: String) { + val last = from.split(".").last() + relocate(from, "io.github.thebusybiscuit.extraheads.libs.$last") + } + doRelocate("org.bstats") + doRelocate("javax.annotation") + minimize() + archiveClassifier = "" +} + +bukkit { + main = "io.github.thebusybiscuit.extraheads.ExtraHeads" + apiVersion = "1.18" + authors = listOf("TheBusyBiscuit", "ybw0014") + description = "A Slimefun Addon that adds heads of mobs" + website = "https://github.com/Slimefun-Addon-Community/ExtraHeads" + depend = listOf("Slimefun") + softDepend = listOf("PlaceholderAPI") +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..d64cd49 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..b82aa23 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..1aa94a4 --- /dev/null +++ b/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | 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 + if ! command -v java >/dev/null 2>&1 + then + 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 +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@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=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +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 execute + +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 + +: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 %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 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! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 7d16db0..0000000 --- a/pom.xml +++ /dev/null @@ -1,125 +0,0 @@ - - - 4.0.0 - io.github.thebusybiscuit - ExtraHeads - UNOFFICIAL - - - 16 - 16 - UTF-8 - - - - - paper-repo - https://repo.destroystokyo.com/repository/maven-public/ - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - jitpack.io - https://jitpack.io - - - bstats-repo - https://repo.codemc.org/repository/maven-public - - - - - ${project.name} v${project.version} - clean package - ${basedir}/src/main/java - - - - ${basedir}/src/main/resources - true - - * - - - - ${basedir} - - - LICENSE - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.5.0 - - - true - - - - - org.bstats - io.github.thebusybiscuit.extraheads.bstats - - - - - - - *:* - - META-INF/* - - - - - - - - package - - shade - - - - - - - - - - org.spigotmc - spigot-api - 1.20.1-R0.1-SNAPSHOT - provided - - - - com.github.slimefun - Slimefun4 - RC-36 - provided - - - io.github.baked-libs - dough-api - - - - - - org.bstats - bstats-bukkit - 3.0.2 - compile - - - diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..790f71e --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "ExtraHeads" diff --git a/src/main/java/io/github/thebusybiscuit/extraheads/ExtraHeads.java b/src/main/java/io/github/thebusybiscuit/extraheads/ExtraHeads.java index 66e4160..cebc1ce 100644 --- a/src/main/java/io/github/thebusybiscuit/extraheads/ExtraHeads.java +++ b/src/main/java/io/github/thebusybiscuit/extraheads/ExtraHeads.java @@ -1,177 +1,57 @@ package io.github.thebusybiscuit.extraheads; -import java.util.EnumMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; +import javax.annotation.Nonnull; import org.bstats.bukkit.Metrics; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.entity.EntityType; -import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; -import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; +import io.github.thebusybiscuit.extraheads.listeners.HeadListener; +import io.github.thebusybiscuit.extraheads.setup.ItemSetup; +import io.github.thebusybiscuit.extraheads.setup.Registry; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; -import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; -import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; -import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; -import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.libraries.dough.config.Config; -import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; import io.github.thebusybiscuit.slimefun4.libraries.dough.updater.BlobBuildUpdater; -import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; -import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; + +import lombok.Getter; public class ExtraHeads extends JavaPlugin implements SlimefunAddon { - private final Map mobs = new EnumMap<>(EntityType.class); + @Getter + private static ExtraHeads instance; - private Config cfg; - private Logger logger; + private Registry registry; - private ItemGroup itemGroup; - private RecipeType recipeType; + public static Registry getRegistry() { + return getInstance().registry; + } @Override public void onEnable() { - cfg = new Config(this); - logger = getLogger(); + instance = this; + + // registry and config + registry = new Registry(new Config(this)); // Setting up bStats new Metrics(this, 5650); - if (cfg.getBoolean("options.auto-update") && getDescription().getVersion().startsWith("Dev")) { + if (registry.getConfig().getBoolean("options.auto-update") && getPluginVersion().startsWith("Dev")) { new BlobBuildUpdater(this, getFile(), "ExtraHeads").start(); } - itemGroup = new ItemGroup( - new NamespacedKey(this, "heads"), - new CustomItemStack( - SlimefunUtils.getCustomHead("5f1379a82290d7abe1efaabbc70710ff2ec02dd34ade386bc00c930c461cf932"), - "&7Extra Heads" - ), - 1 - ); - recipeType = new RecipeType( - new NamespacedKey(this, "decapitation"), - new CustomItemStack( - Material.IRON_SWORD, - "&6Kill the specified Mob" - ) - ); - - registerHead(EntityType.BAT, "2796aa6d18edc5b724bd89e983bc3215a41bf775d112635e9b5835d1b8ad20cb"); - registerHead(EntityType.BLAZE, "b78ef2e4cf2c41a2d14bfde9caff10219f5b1bf5b35a49eb51c6467882cb5f0"); - registerHead(EntityType.CAVE_SPIDER, "41645dfd77d09923107b3496e94eeb5c30329f97efc96ed76e226e98224"); - registerHead(EntityType.CHICKEN, "1638469a599ceef7207537603248a9ab11ff591fd378bea4735b346a7fae893"); - registerHead(EntityType.COW, "5d6c6eda942f7f5f71c3161c7306f4aed307d82895f9d2b07ab4525718edc5"); - registerHead(EntityType.DOLPHIN, "cefe7d803a45aa2af1993df2544a28df849a762663719bfefc58bf389ab7f5"); - registerHead(EntityType.DROWNED, "c84df79c49104b198cdad6d99fd0d0bcf1531c92d4ab6269e40b7d3cbbb8e98c"); - registerHead(EntityType.ELDER_GUARDIAN, "4adc4a6f53afa116027b51d6f2e433ee7afa5d59b2ffa04780be464fa5d61a"); - registerHead(EntityType.ENDERMAN, "7a59bb0a7a32965b3d90d8eafa899d1835f424509eadd4e6b709ada50b9cf"); - registerHead(EntityType.EVOKER, "d954135dc82213978db478778ae1213591b93d228d36dd54f1ea1da48e7cba6"); - registerHead(EntityType.GHAST, "8b6a72138d69fbbd2fea3fa251cabd87152e4f1c97e5f986bf685571db3cc0"); - registerHead(EntityType.GUARDIAN, "932c24524c82ab3b3e57c2052c533f13dd8c0beb8bdd06369bb2554da86c123"); - registerHead(EntityType.HORSE, "61902898308730c4747299cb5a5da9c25838b1d059fe46fc36896fee662729"); - registerHead(EntityType.HUSK, "d674c63c8db5f4ca628d69a3b1f8a36e29d8fd775e1a6bdb6cabb4be4db121"); - registerHead(EntityType.ILLUSIONER, "2f2882dd09723e47c0ab9663eab083d6a5969273706110c82910e61bf8a8f07e"); - registerHead(EntityType.IRON_GOLEM, "89091d79ea0f59ef7ef94d7bba6e5f17f2f7d4572c44f90f76c4819a714"); - registerHead(EntityType.LLAMA, "2a5f10e6e6232f182fe966f501f1c3799d45ae19031a1e4941b5dee0feff059b"); - registerHead(EntityType.MAGMA_CUBE, "38957d5023c937c4c41aa2412d43410bda23cf79a9f6ab36b76fef2d7c429"); - registerHead(EntityType.MUSHROOM_COW, "d0bc61b9757a7b83e03cd2507a2157913c2cf016e7c096a4d6cf1fe1b8db"); - registerHead(EntityType.OCELOT, "5657cd5c2989ff97570fec4ddcdc6926a68a3393250c1be1f0b114a1db1"); - registerHead(EntityType.PARROT, "a4ba8d66fecb1992e94b8687d6ab4a5320ab7594ac194a2615ed4df818edbc3"); - registerHead(EntityType.PIG, "621668ef7cb79dd9c22ce3d1f3f4cb6e2559893b6df4a469514e667c16aa4"); - registerHead(EntityType.POLAR_BEAR, "442123ac15effa1ba46462472871b88f1b09c1db467621376e2f71656d3fbc"); - registerHead(EntityType.RABBIT, "ff1559194a175935b8b4fea6614bec60bf81cf524af6f564333c555e657bc"); - registerHead(EntityType.SHEEP, "f31f9ccc6b3e32ecf13b8a11ac29cd33d18c95fc73db8a66c5d657ccb8be70"); - registerHead(EntityType.SHULKER, "b1d3534d21fe8499262de87affbeac4d25ffde35c8bdca069e61e1787ff2f"); - registerHead(EntityType.SLIME, "16ad20fc2d579be250d3db659c832da2b478a73a698b7ea10d18c9162e4d9b5"); - registerHead(EntityType.SPIDER, "cd541541daaff50896cd258bdbdd4cf80c3ba816735726078bfe393927e57f1"); - registerHead(EntityType.SQUID, "01433be242366af126da434b8735df1eb5b3cb2cede39145974e9c483607bac"); - registerHead(EntityType.STRAY, "78ddf76e555dd5c4aa8a0a5fc584520cd63d489c253de969f7f22f85a9a2d56"); - registerHead(EntityType.TURTLE, "0a4050e7aacc4539202658fdc339dd182d7e322f9fbcc4d5f99b5718a"); - registerHead(EntityType.VEX, "c2ec5a516617ff1573cd2f9d5f3969f56d5575c4ff4efefabd2a18dc7ab98cd"); - registerHead(EntityType.VILLAGER, "822d8e751c8f2fd4c8942c44bdb2f5ca4d8ae8e575ed3eb34c18a86e93b"); - registerHead(EntityType.VINDICATOR, "6deaec344ab095b48cead7527f7dee61b063ff791f76a8fa76642c8676e2173"); - registerHead(EntityType.WITCH, "ddedbee42be472e3eb791e7dbdfaf18c8fe593c638ba1396c9ef68f555cbce"); - registerHead(EntityType.WITHER, "cdf74e323ed41436965f5c57ddf2815d5332fe999e68fbb9d6cf5c8bd4139f"); - registerHead(EntityType.ZOMBIE_VILLAGER, "a6224941314bca2ebbb66b10ffd94680cc98c3435eeb71a228a08fd42c24db"); - registerHead(EntityType.RAVAGER, "1cb9f139f9489d86e410a06d8cbc670c8028137508e3e4bef612fe32edd60193"); - registerHead(EntityType.PILLAGER, "4aee6bb37cbfc92b0d86db5ada4790c64ff4468d68b84942fde04405e8ef5333"); - registerHead(EntityType.FOX, "46cff7a19e683a08e4587ea1457880313d5f341f346ceb5b0551195d810e3"); - registerHead(EntityType.PANDA, "7818b681cace1c641919f53edadecb142330d089a826b56219138c33b7a5e0db"); - registerHead(EntityType.WANDERING_TRADER, "5f1379a82290d7abe1efaabbc70710ff2ec02dd34ade386bc00c930c461cf932"); - registerHead(EntityType.PIGLIN, "11d18bbd0d795b9ac8efaad655e3d0c59fcbb9b964c2a9948ef537f4a3fbbf87"); - registerHead(EntityType.ZOMBIFIED_PIGLIN, "e935842af769380f78e8b8a88d1ea6ca2807c1e5693c2cf797456620833e936f"); - registerHead(EntityType.STRIDER, "18a9adf780ec7dd4625c9c0779052e6a15a451866623511e4c82e9655714b3c1"); - - if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_17)) { - registerHead(EntityType.AXOLOTL, "5c138f401c67fc2e1e387d9c90a9691772ee486e8ddbf2ed375fc8348746f936"); - registerHead(EntityType.GLOW_SQUID, "57327ee11812b764c7ade70b282cce4c58e635b2015244081d1490543da7280e"); - registerHead(EntityType.GOAT, "457a0d538fa08a7affe312903468861720f9fa34e86d44b89dcec5639265f03"); - } - - if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_19)) { - // https://minecraft-heads.com/custom-heads/animals/61373-allay - registerHead(EntityType.ALLAY, "df5de940bfe499c59ee8dac9f9c3919e7535eff3a9acb16f4842bf290f4c679f"); - // https://minecraft-heads.com/custom-heads/animals/63169-cold-frog - registerHead(EntityType.FROG, "45852a95928897746012988fbd5dbaa1b70b7a5fb65157016f4ff3f245374c08"); - // https://minecraft-heads.com/custom-heads/animals/51348-tadpole - registerHead(EntityType.TADPOLE, "987035f5352334c2cba6ac4c65c2b9059739d6d0e839c1dd98d75d2e77957847"); - } - - if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_20)) { - // https://minecraft-heads.com/custom-heads/animals/62878-camel - registerHead(EntityType.CAMEL, "3642c9f71131b5df4a8c21c8c6f10684f22abafb8cd68a1d55ac4bf263a53a31"); - // https://minecraft-heads.com/custom-heads/animals/64113-sniffer - registerHead(EntityType.SNIFFER, "fe5a8341c478a134302981e6a7758ea4ecfd8d62a0df4067897e75502f9b25de"); - } - - cfg.save(); + ItemSetup.setup(); new HeadListener(this); } - private void registerHead(EntityType type, String texture) { - try { - double chance = cfg.getOrSetDefault("chances." + type.toString(), 5.0); - SlimefunItemStack item = new SlimefunItemStack( - type + "_HEAD", - texture, - "&f" + ChatUtils.humanize(type.toString()) + " Head" - ); - new MobHead( - itemGroup, - item, - recipeType, - new CustomItemStack( - item, - "&rKill 1 " + ChatUtils.humanize(type.name()), - "&7Chance: &e" + chance + "%" - ) - ).register(this, () -> mobs.put(type, item)); - } catch (Exception x) { - logger.log(Level.WARNING, x, () -> "Could not load Mob Head for Entity: " + type); - } - } - - public Map getMobDrops() { - return mobs; - } - - public Config getCfg() { - return cfg; - } - @Override + @Nonnull public JavaPlugin getJavaPlugin() { return this; } @Override + @Nonnull public String getBugTrackerURL() { return "https://github.com/Slimefun-Addon-Community/ExtraHeads/issues"; } diff --git a/src/main/java/io/github/thebusybiscuit/extraheads/HeadListener.java b/src/main/java/io/github/thebusybiscuit/extraheads/HeadListener.java deleted file mode 100644 index da0777c..0000000 --- a/src/main/java/io/github/thebusybiscuit/extraheads/HeadListener.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.github.thebusybiscuit.extraheads; - -import java.util.concurrent.ThreadLocalRandom; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDeathEvent; - -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; -import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; - -public class HeadListener implements Listener { - - private final ExtraHeads plugin; - - public HeadListener(ExtraHeads plugin) { - this.plugin = plugin; - - plugin.getServer().getPluginManager().registerEvents(this, plugin); - } - - @EventHandler(ignoreCancelled = true) - public void onKill(EntityDeathEvent e) { - if (!plugin.getMobDrops().containsKey(e.getEntityType())) { - return; - } - - double chance = plugin.getCfg().getDouble("chances." + e.getEntityType()); - Player killer = e.getEntity().getKiller(); - - if (killer != null && SlimefunUtils.isItemSimilar(killer.getInventory().getItemInMainHand(), SlimefunItems.SWORD_OF_BEHEADING, true)) { - chance *= plugin.getCfg().getDouble("options.sword-of-beheading-multiplier"); - } - - if (ThreadLocalRandom.current().nextInt(100) < chance) { - e.getEntity().getWorld().dropItemNaturally(e.getEntity().getLocation(), plugin.getMobDrops().get(e.getEntityType())); - } - } - -} diff --git a/src/main/java/io/github/thebusybiscuit/extraheads/MobHead.java b/src/main/java/io/github/thebusybiscuit/extraheads/MobHead.java deleted file mode 100644 index d97c5fe..0000000 --- a/src/main/java/io/github/thebusybiscuit/extraheads/MobHead.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.github.thebusybiscuit.extraheads; - -import org.bukkit.inventory.ItemStack; - -import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; -import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; -import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; -import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; - -public class MobHead extends SlimefunItem { - - private Runnable runnable; - - public MobHead(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack recipe) { - super(itemGroup, item, recipeType, new ItemStack[] { null, null, null, null, recipe, null, null, null, null }); - } - - public void register(ExtraHeads plugin, Runnable runnable) { - this.runnable = runnable; - register(plugin); - } - - @Override - public void postRegister() { - super.postRegister(); - - if (!isDisabled()) { - runnable.run(); - } - } - -} diff --git a/src/main/java/io/github/thebusybiscuit/extraheads/items/MobHead.java b/src/main/java/io/github/thebusybiscuit/extraheads/items/MobHead.java new file mode 100644 index 0000000..e7acc44 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/extraheads/items/MobHead.java @@ -0,0 +1,38 @@ +package io.github.thebusybiscuit.extraheads.items; + +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; + +import io.github.thebusybiscuit.extraheads.ExtraHeads; +import io.github.thebusybiscuit.extraheads.setup.ItemGroups; +import io.github.thebusybiscuit.extraheads.setup.RecipeTypes; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; + +import lombok.Getter; + +public class MobHead extends SlimefunItem { + + @Getter + private final EntityType entityType; + + @ParametersAreNonnullByDefault + public MobHead(EntityType type, SlimefunItemStack item, ItemStack recipe) { + super(ItemGroups.MAIN, item, RecipeTypes.DECAPITATION, new ItemStack[] { + null, null, null, null, recipe, null, null, null, null + }); + + this.entityType = type; + } + + @Override + public void postRegister() { + super.postRegister(); + + if (!isDisabled()) { + ExtraHeads.getRegistry().getHeads().put(entityType, this); + } + } +} diff --git a/src/main/java/io/github/thebusybiscuit/extraheads/listeners/HeadListener.java b/src/main/java/io/github/thebusybiscuit/extraheads/listeners/HeadListener.java new file mode 100644 index 0000000..57065c5 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/extraheads/listeners/HeadListener.java @@ -0,0 +1,58 @@ +package io.github.thebusybiscuit.extraheads.listeners; + +import java.util.concurrent.ThreadLocalRandom; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.inventory.ItemStack; + +import io.github.thebusybiscuit.extraheads.ExtraHeads; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; +import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SwordOfBeheading; + +public class HeadListener implements Listener { + + private final ExtraHeads plugin; + + public HeadListener(ExtraHeads plugin) { + this.plugin = plugin; + + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler(ignoreCancelled = true) + public void onKill(EntityDeathEvent e) { + var registry = ExtraHeads.getRegistry(); + var entityType = e.getEntityType(); + double chance = getChance(entityType, e.getEntity().getKiller()); + + if (ThreadLocalRandom.current().nextInt(100) < chance) { + e.getEntity().getWorld().dropItemNaturally(e.getEntity().getLocation(), registry.getHeads().get(entityType).getItem().clone()); + } + } + + private double getChance(@Nonnull EntityType type, @Nullable Player killer) { + if (!ExtraHeads.getRegistry().getHeads().containsKey(type)) { + return 0; + } + double chance = ExtraHeads.getRegistry().getConfig().getDouble("chances." + type); + + if (killer == null) { + return chance; + } + + ItemStack item = killer.getInventory().getItemInMainHand(); + SwordOfBeheading sword = (SwordOfBeheading) SlimefunItems.SWORD_OF_BEHEADING.getItem(); + if (item.isEmpty() || sword == null || !sword.isItem(item) || sword.isDisabledIn(killer.getWorld())) { + return chance; + } + + return chance * ExtraHeads.getRegistry().getConfig().getDouble("options.sword-of-beheading-multiplier"); + } +} diff --git a/src/main/java/io/github/thebusybiscuit/extraheads/setup/ItemGroups.java b/src/main/java/io/github/thebusybiscuit/extraheads/setup/ItemGroups.java new file mode 100644 index 0000000..4a09150 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/extraheads/setup/ItemGroups.java @@ -0,0 +1,20 @@ +package io.github.thebusybiscuit.extraheads.setup; + +import org.bukkit.NamespacedKey; + +import io.github.thebusybiscuit.extraheads.ExtraHeads; +import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; +import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public final class ItemGroups { + + public static final ItemGroup MAIN = new ItemGroup( + new NamespacedKey(ExtraHeads.getInstance(), "extra_heads"), + new CustomItemStack(SlimefunUtils.getCustomHead("5f1379a82290d7abe1efaabbc70710ff2ec02dd34ade386bc00c930c461cf932"), "&7Extra Heads"), + 1 + ); +} diff --git a/src/main/java/io/github/thebusybiscuit/extraheads/setup/ItemSetup.java b/src/main/java/io/github/thebusybiscuit/extraheads/setup/ItemSetup.java new file mode 100644 index 0000000..120163f --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/extraheads/setup/ItemSetup.java @@ -0,0 +1,123 @@ +package io.github.thebusybiscuit.extraheads.setup; + +import java.util.logging.Level; + +import org.bukkit.entity.EntityType; + +import io.github.thebusybiscuit.extraheads.ExtraHeads; +import io.github.thebusybiscuit.extraheads.items.MobHead; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; +import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; +import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; + +import net.guizhanss.guizhanlib.minecraft.utils.MinecraftVersionUtil; +import net.guizhanss.guizhanlib.minecraft.utils.compatibility.EntityTypeX; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class ItemSetup { + + public static void setup() { + registerHead(EntityType.BAT, "2796aa6d18edc5b724bd89e983bc3215a41bf775d112635e9b5835d1b8ad20cb"); + registerHead(EntityType.BLAZE, "b78ef2e4cf2c41a2d14bfde9caff10219f5b1bf5b35a49eb51c6467882cb5f0"); + registerHead(EntityType.CAVE_SPIDER, "41645dfd77d09923107b3496e94eeb5c30329f97efc96ed76e226e98224"); + registerHead(EntityType.CHICKEN, "1638469a599ceef7207537603248a9ab11ff591fd378bea4735b346a7fae893"); + registerHead(EntityType.COW, "5d6c6eda942f7f5f71c3161c7306f4aed307d82895f9d2b07ab4525718edc5"); + registerHead(EntityType.DOLPHIN, "cefe7d803a45aa2af1993df2544a28df849a762663719bfefc58bf389ab7f5"); + registerHead(EntityType.DROWNED, "c84df79c49104b198cdad6d99fd0d0bcf1531c92d4ab6269e40b7d3cbbb8e98c"); + registerHead(EntityType.ELDER_GUARDIAN, "4adc4a6f53afa116027b51d6f2e433ee7afa5d59b2ffa04780be464fa5d61a"); + registerHead(EntityType.ENDERMAN, "7a59bb0a7a32965b3d90d8eafa899d1835f424509eadd4e6b709ada50b9cf"); + registerHead(EntityType.EVOKER, "d954135dc82213978db478778ae1213591b93d228d36dd54f1ea1da48e7cba6"); + registerHead(EntityType.GHAST, "8b6a72138d69fbbd2fea3fa251cabd87152e4f1c97e5f986bf685571db3cc0"); + registerHead(EntityType.GUARDIAN, "932c24524c82ab3b3e57c2052c533f13dd8c0beb8bdd06369bb2554da86c123"); + registerHead(EntityType.HORSE, "61902898308730c4747299cb5a5da9c25838b1d059fe46fc36896fee662729"); + registerHead(EntityType.HUSK, "d674c63c8db5f4ca628d69a3b1f8a36e29d8fd775e1a6bdb6cabb4be4db121"); + registerHead(EntityType.ILLUSIONER, "2f2882dd09723e47c0ab9663eab083d6a5969273706110c82910e61bf8a8f07e"); + registerHead(EntityType.IRON_GOLEM, "89091d79ea0f59ef7ef94d7bba6e5f17f2f7d4572c44f90f76c4819a714"); + registerHead(EntityType.LLAMA, "2a5f10e6e6232f182fe966f501f1c3799d45ae19031a1e4941b5dee0feff059b"); + registerHead(EntityType.MAGMA_CUBE, "38957d5023c937c4c41aa2412d43410bda23cf79a9f6ab36b76fef2d7c429"); + registerHead(EntityTypeX.MOOSHROOM, "d0bc61b9757a7b83e03cd2507a2157913c2cf016e7c096a4d6cf1fe1b8db"); + registerHead(EntityType.OCELOT, "5657cd5c2989ff97570fec4ddcdc6926a68a3393250c1be1f0b114a1db1"); + registerHead(EntityType.PARROT, "a4ba8d66fecb1992e94b8687d6ab4a5320ab7594ac194a2615ed4df818edbc3"); + registerHead(EntityType.PIG, "621668ef7cb79dd9c22ce3d1f3f4cb6e2559893b6df4a469514e667c16aa4"); + registerHead(EntityType.POLAR_BEAR, "442123ac15effa1ba46462472871b88f1b09c1db467621376e2f71656d3fbc"); + registerHead(EntityType.RABBIT, "ff1559194a175935b8b4fea6614bec60bf81cf524af6f564333c555e657bc"); + registerHead(EntityType.SHEEP, "f31f9ccc6b3e32ecf13b8a11ac29cd33d18c95fc73db8a66c5d657ccb8be70"); + registerHead(EntityType.SHULKER, "b1d3534d21fe8499262de87affbeac4d25ffde35c8bdca069e61e1787ff2f"); + registerHead(EntityType.SLIME, "16ad20fc2d579be250d3db659c832da2b478a73a698b7ea10d18c9162e4d9b5"); + registerHead(EntityType.SPIDER, "cd541541daaff50896cd258bdbdd4cf80c3ba816735726078bfe393927e57f1"); + registerHead(EntityType.SQUID, "01433be242366af126da434b8735df1eb5b3cb2cede39145974e9c483607bac"); + registerHead(EntityType.STRAY, "78ddf76e555dd5c4aa8a0a5fc584520cd63d489c253de969f7f22f85a9a2d56"); + registerHead(EntityType.TURTLE, "0a4050e7aacc4539202658fdc339dd182d7e322f9fbcc4d5f99b5718a"); + registerHead(EntityType.VEX, "c2ec5a516617ff1573cd2f9d5f3969f56d5575c4ff4efefabd2a18dc7ab98cd"); + registerHead(EntityType.VILLAGER, "822d8e751c8f2fd4c8942c44bdb2f5ca4d8ae8e575ed3eb34c18a86e93b"); + registerHead(EntityType.VINDICATOR, "6deaec344ab095b48cead7527f7dee61b063ff791f76a8fa76642c8676e2173"); + registerHead(EntityType.WITCH, "ddedbee42be472e3eb791e7dbdfaf18c8fe593c638ba1396c9ef68f555cbce"); + registerHead(EntityType.WITHER, "cdf74e323ed41436965f5c57ddf2815d5332fe999e68fbb9d6cf5c8bd4139f"); + registerHead(EntityType.ZOMBIE_VILLAGER, "a6224941314bca2ebbb66b10ffd94680cc98c3435eeb71a228a08fd42c24db"); + registerHead(EntityType.RAVAGER, "1cb9f139f9489d86e410a06d8cbc670c8028137508e3e4bef612fe32edd60193"); + registerHead(EntityType.PILLAGER, "4aee6bb37cbfc92b0d86db5ada4790c64ff4468d68b84942fde04405e8ef5333"); + registerHead(EntityType.FOX, "46cff7a19e683a08e4587ea1457880313d5f341f346ceb5b0551195d810e3"); + registerHead(EntityType.PANDA, "7818b681cace1c641919f53edadecb142330d089a826b56219138c33b7a5e0db"); + registerHead(EntityType.WANDERING_TRADER, "5f1379a82290d7abe1efaabbc70710ff2ec02dd34ade386bc00c930c461cf932"); + registerHead(EntityType.PIGLIN, "11d18bbd0d795b9ac8efaad655e3d0c59fcbb9b964c2a9948ef537f4a3fbbf87"); + registerHead(EntityType.ZOMBIFIED_PIGLIN, "e935842af769380f78e8b8a88d1ea6ca2807c1e5693c2cf797456620833e936f"); + registerHead(EntityType.STRIDER, "18a9adf780ec7dd4625c9c0779052e6a15a451866623511e4c82e9655714b3c1"); + registerHead(EntityType.AXOLOTL, "5c138f401c67fc2e1e387d9c90a9691772ee486e8ddbf2ed375fc8348746f936"); + registerHead(EntityType.GLOW_SQUID, "57327ee11812b764c7ade70b282cce4c58e635b2015244081d1490543da7280e"); + registerHead(EntityType.GOAT, "457a0d538fa08a7affe312903468861720f9fa34e86d44b89dcec5639265f03"); + + if (MinecraftVersionUtil.isAtLeast(19)) { + // https://minecraft-heads.com/custom-heads/animals/61373-allay + registerHead(EntityType.ALLAY, "df5de940bfe499c59ee8dac9f9c3919e7535eff3a9acb16f4842bf290f4c679f"); + // https://minecraft-heads.com/custom-heads/animals/63169-cold-frog + registerHead(EntityType.FROG, "45852a95928897746012988fbd5dbaa1b70b7a5fb65157016f4ff3f245374c08"); + // https://minecraft-heads.com/custom-heads/animals/51348-tadpole + registerHead(EntityType.TADPOLE, "987035f5352334c2cba6ac4c65c2b9059739d6d0e839c1dd98d75d2e77957847"); + } + + if (MinecraftVersionUtil.isAtLeast(20)) { + // https://minecraft-heads.com/custom-heads/animals/62878-camel + registerHead(EntityType.CAMEL, "3642c9f71131b5df4a8c21c8c6f10684f22abafb8cd68a1d55ac4bf263a53a31"); + // https://minecraft-heads.com/custom-heads/animals/64113-sniffer + registerHead(EntityType.SNIFFER, "fe5a8341c478a134302981e6a7758ea4ecfd8d62a0df4067897e75502f9b25de"); + } + + if (MinecraftVersionUtil.isAtLeast(20, 5)) { + // https://minecraft-heads.com/custom-heads/head/91910-armadillo + registerHead(EntityType.ARMADILLO, "9852b33ba294f560090752d113fe728cbc7dd042029a38d5382d65a2146068b7"); + } + + if (MinecraftVersionUtil.isAtLeast(21)) { + // https://minecraft-heads.com/custom-heads/head/87691-bogged + registerHead(EntityType.BOGGED, "a3b9003ba2d05562c75119b8a62185c67130e9282f7acbac4bc2824c21eb95d9"); + // https://minecraft-heads.com/custom-heads/head/69108-breeze + registerHead(EntityType.BREEZE, "a275728af7e6a29c88125b675a39d88ae9919bb61fdc200337fed6ab0c49d65c"); + } + + ExtraHeads.getRegistry().getConfig().save(); + } + + private static void registerHead(EntityType type, String texture) { + try { + double chance = ExtraHeads.getRegistry().getConfig().getOrSetDefault("chances." + type.toString(), 5.0); + SlimefunItemStack item = new SlimefunItemStack( + type + "_HEAD", + texture, + "&f" + ChatUtils.humanize(type.toString()) + " Head" + ); + new MobHead( + type, + item, + new CustomItemStack( + item, + "&rKill 1 " + ChatUtils.humanize(type.name()), + "&7Chance: &e" + chance + "%" + ) + ).register(ExtraHeads.getInstance()); + } catch (Exception x) { + ExtraHeads.getInstance().getLogger().log(Level.WARNING, x, () -> "Could not load Mob Head for Entity: " + type); + } + } +} diff --git a/src/main/java/io/github/thebusybiscuit/extraheads/setup/RecipeTypes.java b/src/main/java/io/github/thebusybiscuit/extraheads/setup/RecipeTypes.java new file mode 100644 index 0000000..a34ded2 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/extraheads/setup/RecipeTypes.java @@ -0,0 +1,19 @@ +package io.github.thebusybiscuit.extraheads.setup; + +import org.bukkit.Material; +import org.bukkit.NamespacedKey; + +import io.github.thebusybiscuit.extraheads.ExtraHeads; +import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class RecipeTypes { + + public static final RecipeType DECAPITATION = new RecipeType( + new NamespacedKey(ExtraHeads.getInstance(), "decapitation"), + new CustomItemStack(Material.IRON_SWORD, "&6Kill the specified Mob") + ); +} diff --git a/src/main/java/io/github/thebusybiscuit/extraheads/setup/Registry.java b/src/main/java/io/github/thebusybiscuit/extraheads/setup/Registry.java new file mode 100644 index 0000000..4482972 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/extraheads/setup/Registry.java @@ -0,0 +1,26 @@ +package io.github.thebusybiscuit.extraheads.setup; + +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Nonnull; + +import org.bukkit.entity.EntityType; + +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; +import io.github.thebusybiscuit.slimefun4.libraries.dough.config.Config; + +import lombok.Getter; + +@Getter +public class Registry { + + private final Config config; + private final Map heads = new EnumMap<>(EntityType.class); + private final Map> entityNames = new HashMap<>(); + + public Registry(@Nonnull Config config) { + this.config = config; + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml deleted file mode 100644 index 0c82c97..0000000 --- a/src/main/resources/plugin.yml +++ /dev/null @@ -1,7 +0,0 @@ -name: ExtraHeads -version: ${project.version} -author: TheBusyBiscuit -depend: [Slimefun] - -main: io.github.thebusybiscuit.extraheads.ExtraHeads -api-version: 1.16 \ No newline at end of file