diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 0a39c543a..92af0675b 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -17,13 +17,13 @@ Rules for all types of posts: Rules for posting an Issue on GitHub: 1. This Issue Section is ONLY for Slimefun-related Issues, Issues about other Plugins or Slimefun Addons should not be posted here. -2. Please consult our [Troubleshooting Guide](#troubleshooting-guide) before posting. +2. Please consult our [Troubleshooting Guide](https://github.com/TheBusyBiscuit/Slimefun4/wiki/How-to-report-bugs) before posting. 3. Check other Issues before posting to make sure you are not posting a duplicate. -4. Do not put any Tags inside your title like [IMPORTANT], [URGENT] or [SUGGESTION]. Try to be professional by making your title as short as possible, we will assign it the required labels if necessary. -5. Do not post your Issue more than once, this is considered spam and does not benefit our community in any way. Do not repost your Issue if it was closed either. +4. Please do not put any Tags inside your title like [IMPORTANT], [URGENT] or [SUGGESTION]. Try to be professional by making your title as short as possible, we will assign it the required labels if necessary. +5. Do not post your Issue more than once, this is considered spam and does not benefit our community in any way. Do not repost your Issue if it was closed either, just leave a comment stating that the issue has still persisted and give more context on it. 6. Give us all available information right away, it may be a bit of time-wasting for us to keep asking for more Info. And this includes any Information to reproduce your Issue step-by-step. 7. Check whether there are newer versions available than the ones you are using, it might be that your Issue has been fixed already. -8. All text logs must be posted via a link to http://pastebin.com or similiar websites. +8. All text logs must be posted via a link to https://pastebin.com/ or similiar websites, long logs are very hard to read and get weirdly formatted when you post them on here. Using a proper pasting site allows us to keep things clean and easy to read. Your Issue will be CLOSED WITHOUT WARNING if we think you violated these Rules. @@ -35,26 +35,3 @@ Guidelines for making a Pull Request on GitHub: 2. Try to make your values configurable in the config.yml / Items.yml or any additional file. This may not be necessary at every instance but it does give the end-users a way to customize their experience. 3. If your Pull Request is made in response to an Issue opened on GitHub, comment on that Issue and reference your Pull Request to show that you are proposing a fix for it. 4. Name your commits appropriately. Standards like "Add files via upload" or "Update Readme.md" are lame. Make sure that the commit message stands for it's changes. (e.g. "Fixed Furnaces duplicating Items") - -## Troubleshooting Guide - -### Step 1: Check whether you have installed Slimefun correctly -Slimefun requires [CS-CoreLib](http://dev.bukkit.org/bukkit-plugins/cs-corelib) to run. -If it has not been installed automatically for you, then please download & install it manually. - -### Step 2: Check whether you are running on the latest Versions -Both, [Slimefun](http://dev.bukkit.org/bukkit-plugins/slimefun/files) and [CS-CoreLib](http://dev.bukkit.org/bukkit-plugins/cs-corelib/files) are updated from time to time. -You should be sure that you run the latest Versions (at the time you post your Issue) of both Plugins. - -### Step 3: Does it have to do with Items called 'CS-CoreLib's Head'? -Well in that case, you have been the victim of corruption, unless you have an Error/Crash Report that we can work with, there is literally nothing we can do about it. -Corrupting Files/Data can happen from time to time and getting completely rid of it would require a ton of work and even then it is still not completely impossible to occur. - -### Step 4: Do you get an Error, do you have an Error Report? -Check your /plugins/Slimefun/error-reports/ directory and if it contains any Files, then please upload those to http://pastebin.com -and provide us with a link. - -When providing us Errors from your Server Log MAKE SURE THEY ARE ERRORS. -It has happened more often than you may think that people send us messages. -Try to read the suspected 'Error' before uploading it to http://pastebin.com -If it says "Please install CS-CoreLib", then you may want to rethink whether you want to ask us what it means... diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index b5ec9bd24..8c869ff27 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -7,24 +7,46 @@ assignees: '' --- -## Description (Required) - + -## Steps to reproduce the Issue (Required) +## Description (REQUIRED) + + + + + +## Steps to reproduce the Issue (REQUIRED) + + -## Expected behavior (Required) - -## Server Log / Error Report - - +## Expected behavior (REQUIRED) + + + -## Environment (Required) - + +## Server Log + + + + + +## Error Reports + + + + + +## Environment (REQUIRED) + - + + + + - Server Software (Spigot/Paper): - Minecraft Version: - Slimefun Version: - CS-CoreLib Version: diff --git a/.github/workflows/close-invalid-issues.yml b/.github/workflows/close-invalid-issues.yml index 248850e63..bcfa7120d 100644 --- a/.github/workflows/close-invalid-issues.yml +++ b/.github/workflows/close-invalid-issues.yml @@ -1,12 +1,15 @@ name: Close invalid Issue -on: - issues: +on: + issues: types: [opened] jobs: comment: + + name: Invalid Issues runs-on: ubuntu-latest + if: contains(github.event.issue.labels.*.name, 'Bug Report') == false steps: - name: Close Issue @@ -29,6 +32,6 @@ jobs: body: |- Your issue seems to be missing our template. [Click here to create a bug report](https://github.com/TheBusyBiscuit/Slimefun4/issues/new/choose) - + Please remember that this Bug Tracker is exclusively reserved for Bug reports, any other form of discussion, like suggestions or questions should be posted on our discord server (You can find a link [on our main page](https://github.com/TheBusyBiscuit/Slimefun4#discord)). diff --git a/.github/workflows/closed-issues-reason.yml b/.github/workflows/closed-issues-reason.yml index c9212540d..06546fdb1 100644 --- a/.github/workflows/closed-issues-reason.yml +++ b/.github/workflows/closed-issues-reason.yml @@ -1,6 +1,7 @@ name: Respond to closed Issue -on: - issues: + +on: + issues: types: [closed] jobs: @@ -28,20 +29,19 @@ jobs: token: ${{ secrets.ACCESS_TOKEN }} issue_number: ${{ github.event.issue.number }} body: |- - Your issue was closed, it may fall under one or more of the following categories. + Your issue has been closed by an admin, it may fall under one or more of the following categories. **Please wait for an admin to tick off the points that apply.** - - Please respond below, if you have any questions. - Do **not** open a new Issue unless explicitly told otherwise, comment below or edit your post instead. - +
+ * [ ] You did not follow our template. Please follow the Issue template to help us identify your issue more effectively. * [ ] You did not provide any information about your versions (We absolutely need the exact version numbers that are installed on your Server, \"latest\" is not helpful) - * [ ] You did not provide a proper description to the problem. Try to write at least 4-6 sentences on how to reproduce this. + * [ ] You did not provide a proper description to the problem. Try to write at least 4-6 sentences and/or provide screenshots or videos on how to reproduce this. * [ ] We were unable to reproduce issue, if you think your issue still persists then please comment down below and give a better description on how to reproduce it. * [ ] Your issue was posted in a foreign language, we only accept english issues on here. - * [ ] Your issue is not a bug, it is either intended or something we cannot change. + * [ ] Your issue is not a bug, it is intended to work this way. + * [ ] Your issue is not really a bug, it is a limitation or simply something we have no control over. * [ ] Your issue is not a bug, please only use this issue tracker to report bugs. Any other kind of communication should happen on discord. - * [ ] Your issue was already reported, it is a duplicate. Check the other issues first before posting! + * [ ] Your issue has already been reported before, it is a duplicate. Check the other issues first before posting! * [ ] You posted an error without using pastebin. Please always post errors via pastebin otherwise they become nearly unreadable. * [ ] You seem to be reporting multiple bugs at once. Please make a seperate issue for each bug you encountered, so we can properly handle them individually. * [ ] Your issue has already been fixed in a later version of Slimefun or CS-CoreLib, you should update. @@ -50,5 +50,8 @@ jobs: * [ ] You are using an unsupported version of Minecraft. We only provide support for the Minecraft versions Slimefun was developed for, older versions are not supported anymore. * [ ] You are using a \"stable\" version of Slimefun (prefixed with \"RC - \"), your issue may have been fixed in a development build, so we only accept bug reports from those. * [ ] You are on the wrong issue tracker. We would like to remind you that this Issue Tracker is **only for Slimefun**. To report bugs on any addons, head to the corresponding issue tracker of that addon. - +
+ + Please respond below, if you have any further questions. + Do **not** open a new Issue unless explicitly told otherwise, comment below or edit your post instead.
Make sure to check out our article on [How to report bugs](https://github.com/TheBusyBiscuit/Slimefun4/wiki/How-to-report-bugs) for even more information. diff --git a/.github/workflows/discord-webhook.yml b/.github/workflows/discord-webhook.yml index b3e0783c8..c11ccaf3d 100644 --- a/.github/workflows/discord-webhook.yml +++ b/.github/workflows/discord-webhook.yml @@ -9,6 +9,7 @@ on: jobs: report: + name: Discord Webhook runs-on: ubuntu-latest if: github.repository == 'TheBusyBiscuit/Slimefun4' diff --git a/.github/workflows/duplicates.yml b/.github/workflows/duplicates.yml index 99f4ebc26..c1b481ced 100644 --- a/.github/workflows/duplicates.yml +++ b/.github/workflows/duplicates.yml @@ -1,12 +1,15 @@ name: Mark Issue as duplicate -on: - issue_comment: +on: + issue_comment: types: [created] jobs: comment: + + name: Mark Issue as duplicate runs-on: ubuntu-latest + if: contains(github.event.comment.body, 'Duplicate of ') steps: - name: Add label to the Issue diff --git a/.github/workflows/maven-compiler.yml b/.github/workflows/maven-compiler.yml index 0aa9a2e80..1e041876b 100644 --- a/.github/workflows/maven-compiler.yml +++ b/.github/workflows/maven-compiler.yml @@ -17,6 +17,7 @@ on: jobs: build: + name: Maven build runs-on: ubuntu-latest steps: diff --git a/.github/workflows/translator-webhook.yml b/.github/workflows/translator-webhook.yml index 0f5118b52..03f276aba 100644 --- a/.github/workflows/translator-webhook.yml +++ b/.github/workflows/translator-webhook.yml @@ -1,18 +1,19 @@ name: Translation Notifier -on: + +on: push: branches: - master paths: - 'src/main/resources/languages/**_en.yml' - + jobs: notify: - + name: Translation-Notifier runs-on: ubuntu-latest if: github.repository == 'TheBusyBiscuit/Slimefun4' - + steps: - name: Discord Notification uses: Ilshidur/action-discord@master diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml index 9d18c206a..38e1780e4 100644 --- a/.github/workflows/update-changelog.yml +++ b/.github/workflows/update-changelog.yml @@ -1,19 +1,19 @@ name: Changelog Populator -on: +on: push: branches: - master paths: - 'CHANGELOG.md' - + jobs: populate: name: Changelog Generator runs-on: ubuntu-latest if: github.repository == 'TheBusyBiscuit/Slimefun4' - + steps: - name: TOC Generator uses: technote-space/toc-generator@v2.4.0 diff --git a/.github/workflows/url-checker.yml b/.github/workflows/url-checker.yml new file mode 100644 index 000000000..db92ab64e --- /dev/null +++ b/.github/workflows/url-checker.yml @@ -0,0 +1,26 @@ +name: URL Validator + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + build: + + name: URL Checker + runs-on: ubuntu-latest + + steps: + - name: URL-checker + uses: SuperKogito/URLs-checker@0.2.1 + with: + git_path: https://github.com/TheBusyBiscuit/Slimefun4 + file_types: .md,.java,.yml + print_all: False + retry_count: 2 + ## These URLs will always be correct, even if their services may be offline right now + white_listed_patterns: http://textures.minecraft.net/texture/,https://pastebin.com/,https://www.spigotmc.org/threads/spigot-bungeecord-1-16-1.447405/#post-3852349 diff --git a/.github/workflows/yaml-linter.yml b/.github/workflows/yaml-linter.yml new file mode 100644 index 000000000..445e5afe2 --- /dev/null +++ b/.github/workflows/yaml-linter.yml @@ -0,0 +1,25 @@ +name: YAML Linter + +on: + push: + paths: + - '**.yml' + pull_request: + branches: + - master + paths: + - '**.yml' + +jobs: + linter: + + name: YAML Linter + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v1 + - name: YAML Linter + uses: ibiqlik/action-yamllint@v1.0.0 + with: + config_file: '.github/yaml-lint.yml' diff --git a/.github/yaml-lint.yml b/.github/yaml-lint.yml new file mode 100644 index 000000000..07a8c09fd --- /dev/null +++ b/.github/yaml-lint.yml @@ -0,0 +1,17 @@ +extends: default +locale: en_US.UTF-8 + +yaml-files: +- '*.yml' + +rules: + line-length: + max: 160 + level: warning + + ## We don't need indentation warnings + indentation: disable + + trailing-spaces: + ignore: | + /src/main/resources/languages/*.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 2eda43a04..ad9af9284 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ **Table of contents** -- [Release Candidate 15 (TBD)](#release-candidate-15-tbd) +- [Release Candidate 16 (TBD)](#release-candidate-16-tbd) +- [Release Candidate 15 (01 Aug 2020)](#release-candidate-15-01-aug-2020) - [Release Candidate 14 (12 Jul 2020)](#release-candidate-14-12-jul-2020) - [Release Candidate 13 (16 Jun 2020)](#release-candidate-13-16-jun-2020) - [Release Candidate 12 (27 May 2020)](#release-candidate-12-27-may-2020) @@ -20,18 +21,70 @@ -## Release Candidate 15 (TBD) +## Release Candidate 16 (TBD) + +#### Additions +* Added an option for Industrial Miners to mine Ancient Debris +* Added a new language: Korean +* (API) Added support for adding custom Piglin Barter drops +* (API) Added BlockPlacerPlaceEvent +* (API) Added ToolUseHandler +* Added "Sand -> Sandstone" recipe to the Electric Press +* Added "Red Sand -> Red Sandstone" recipe to the Electric Press +* Industrial Miners can now also mine Gilded Blackstone +* Added a config option to disable Players from burning when exposed to radiation + +#### Changes +* Performance improvement for Programmable Android rotations +* Removed Gravel -> Flint recipe from the Grind stone +* Performance improvements for miner talismans +* Performance improvements for idling Enhanced Furnaces when using Paper +* Performance improvements for Rainbow Blocks +* Crafting a Rag now yields two items +* Small performance improvements for Slimefun guides +* Small performance improvements for Cargo networks +* Small performance improvements for Miner Androids + +#### Fixes +* Fixed Programmable Androids rotating in the wrong direction +* Fixed #2176 +* Fixed #2164 +* Fixed #2147 +* Fixed #2179 +* Fixed Reinforced Spawners not working sometimes +* Fixed Explosive Pickaxe not handling normal Shulker boxes correctly +* Fixed #2103 +* Fixed #2184 +* Fixed #2183 +* Fixed #2181 +* Fixed #2180 +* Fixed #2122 +* Fixed #2168 +* Fixed #2203 +* Fixed #2205 +* Fixed #2209 +* Fixed #2217 +* Fixed Miner Talisman sending messages when drops were not even doubled +* Fixed #2077 +* Fixed #2207 +* Fixed ChestTerminal timings showing up as cargo nodes +* Fixed timings reports never arriving sometimes +* Fixed #2138 + +## Release Candidate 15 (01 Aug 2020) #### Additions * Added "Bone Block -> Bone meal" recipe to the Grind Stone * Added a [Metrics module](https://github.com/Slimefun/MetricsModule) which allows us to release updates to metrics (bStats) independently from the main plugin * Added "Compressed Carbon -> Carbon" recipe to the Ore Crusher * Added "Carbon -> Coal" recipe to the Ore Crusher +* Added an option to disable the message "Ignoring duplicate block" * Added Iron Golem Assembler * Added Reinforced Cloth * Added Bee protection to Hazmat Suit * Added Enchantment Rune * Added Tape Measure +* Added a permission node for /sf debug_fish #### Changes * Refactored and reworked the Generator API @@ -44,6 +97,12 @@ * Optimized Cargo networks for Paper * Optimized Multiblocks for Paper * Optimized Enhanced Furnaces for Paper +* Optimized Programmable Androids for Paper +* General performance improvements for Talismans +* General performance improvements for GPS Emergency Transmitters +* General performance improvements for Infused Magnets +* Ancient Altars now support for protection plugins +* Ancient Pedestals now support for protection plugins #### Fixes * Fixed Slimefun Armor sometimes not applying its effects @@ -51,6 +110,20 @@ * Fixed #2093 * Fixed #2086 * Fixed #1894 +* Fixed #2097 +* Fixed Wither Assembler requiring more items than it actually consumes +* Fixed Metrics not updating automatically +* Fixed #2143 +* Fixed #2145 +* Fixed #2151 +* Fixed old Talismans not working +* Fixed Talismans sometimes not getting consumed properly +* Fixed old Infused Magnets not working +* Fixed old GPS Emergency Transmitters not working +* Fixed #2156 +* Fixed #2165 +* Fixed #2162 +* Fixed #2166 ## Release Candidate 14 (12 Jul 2020) diff --git a/README.md b/README.md index 78a818163..94aabee21 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Check out our [Addons](https://github.com/TheBusyBiscuit/Slimefun4/wiki/Addons), ### Quick navigation * **[Download Slimefun4](#download-slimefun-4)** +* **[Screenshots](#screenshots)** * **[Discord Support Server](#discord)** * **[Bug Tracker](https://github.com/TheBusyBiscuit/Slimefun4/issues)** * **[Wiki](https://github.com/TheBusyBiscuit/Slimefun4/wiki)** @@ -54,6 +55,16 @@ While "stable" builds most definitely contain more bugs than development builds +## Screenshots +So what does Slimefun look like?
+Well, we asked some users on our [Discord server](#discord) to send us some screenshots, so see for yourself: +| Reactors and electricity | Awesome factories | Magic and Altars | +| :-------------------------------------------: | :--------------------------------------: | :----------------------------------------: | +| ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase1.png) | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase6.png) | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase5.png) | +| *Screenshot provided by HamtaBot#0001* | *Screenshot provided by Piͭxͪeͤl (mnb)#5049* | *Screenshot provided by Kilaruna#4981* | +| ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase4.png) | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase3.png) | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase2.png) | +| *Screenshot provided by GalaxyKat11#3816* | *Screenshot provided by TamThan#7987* | *Screenshot provided by Kilaruna#4981* | + ## Discord You can find Slimefun's community on Discord and connect with **over 2000** users of this plugin from all over the world.
Click the badge down below to join the server for suggestions/questions or other discussions about this plugin.
@@ -181,5 +192,5 @@ This information includes (but is not limited to) * date of the last commit to this repository -Additionally the plugin connects to https://mojang.com/ to retrieve the Minecraft skins of our contributors (if possible).
+Additionally the plugin connects to [textures.minecraft.net](https://www.minecraft.net/en-us) to retrieve the Minecraft skins of our contributors (if possible).
Note that Slimefun is not associated with `Mojang Studios` or Minecraft. diff --git a/pom.xml b/pom.xml index 1e7d52776..9cd7e2639 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - io.github.thebusybiscuit + com.github.thebusybiscuit Slimefun @@ -22,7 +22,7 @@ 1.8 - 1.16.1 + 1.16.2 https://hub.spigotmc.org/javadocs/spigot/ @@ -47,6 +47,16 @@ + + sonatype-snapshots + http://oss.sonatype.org/content/repositories/snapshots + + false + + + true + + jitpack.io https://jitpack.io @@ -57,7 +67,7 @@ paper-repo - https://repo.destroystokyo.com/repository/maven-public/ + https://papermc.io/repo/repository/maven-public/ worldedit-repo @@ -303,14 +313,14 @@ com.github.seeseemelk - MockBukkit - v1.15-d952559324-1 + MockBukkit-v1.15 + 0.3.1-SNAPSHOT test org.mockito mockito-core - 3.4.4 + 3.5.2 test @@ -318,7 +328,7 @@ com.github.TheBusyBiscuit CS-CoreLib2 - 0.24 + 0.25 compile @@ -330,7 +340,7 @@ com.konghq unirest-java - 3.8.06 + 3.9.00 com.google.code.gson @@ -341,7 +351,7 @@ io.papermc paperlib - 1.0.4 + 1.0.5 compile @@ -364,7 +374,7 @@ me.clip placeholderapi - 2.10.6 + 2.10.9 provided diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java index 4297e2223..462c77064 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java @@ -84,7 +84,7 @@ public class ErrorReport { addon.getLogger().log(Level.WARNING, ""); addon.getLogger().log(Level.WARNING, "An Error occurred! It has been saved as: "); addon.getLogger().log(Level.WARNING, "/plugins/Slimefun/error-reports/{0}", file.getName()); - addon.getLogger().log(Level.WARNING, "Please put this file on https://pastebin.com and report this to the developer(s)."); + addon.getLogger().log(Level.WARNING, "Please put this file on https://pastebin.com/ and report this to the developer(s)."); if (addon.getBugTrackerURL() != null) { addon.getLogger().log(Level.WARNING, "Bug Tracker: {0}", addon.getBugTrackerURL()); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AncientAltarCraftEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AncientAltarCraftEvent.java index 0710aaf20..0d8463bca 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AncientAltarCraftEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AncientAltarCraftEvent.java @@ -45,14 +45,6 @@ public class AncientAltarCraftEvent extends PlayerEvent implements Cancellable { this.output = output; } - public static HandlerList getHandlerList() { - return handlers; - } - - public HandlerList getHandlers() { - return handlers; - } - /** * This method returns the main altar's block {@link Block} * @@ -95,4 +87,13 @@ public class AncientAltarCraftEvent extends PlayerEvent implements Cancellable { cancelled = cancel; } + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidMineEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidMineEvent.java index 2ab8419eb..0f28d6f07 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidMineEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidMineEvent.java @@ -34,14 +34,6 @@ public class AndroidMineEvent extends Event implements Cancellable { this.android = android; } - public static HandlerList getHandlerList() { - return handlers; - } - - public HandlerList getHandlers() { - return handlers; - } - /** * This method returns the mined {@link Block} * @@ -71,4 +63,13 @@ public class AndroidMineEvent extends Event implements Cancellable { cancelled = cancel; } + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + } \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AutoDisenchantEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AutoDisenchantEvent.java index 015289443..c3d38193b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AutoDisenchantEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AutoDisenchantEvent.java @@ -27,14 +27,6 @@ public class AutoDisenchantEvent extends Event implements Cancellable { this.item = item; } - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - /** * This returns the {@link ItemStack} that is being disenchanted. * @@ -54,4 +46,13 @@ public class AutoDisenchantEvent extends Event implements Cancellable { this.cancelled = cancel; } + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/BlockPlacerPlaceEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/BlockPlacerPlaceEvent.java new file mode 100644 index 000000000..b2e30f85c --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/BlockPlacerPlaceEvent.java @@ -0,0 +1,113 @@ +package io.github.thebusybiscuit.slimefun4.api.events; + +import org.apache.commons.lang.Validate; +import org.bukkit.block.Block; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockEvent; +import org.bukkit.inventory.ItemStack; + +import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.BlockPlacer; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; + +/** + * This {@link Event} is fired whenever a {@link BlockPlacer} wants to place a {@link Block}. + * + * @author TheBusyBiscuit + * + */ +public class BlockPlacerPlaceEvent extends BlockEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + private final Block blockPlacer; + private ItemStack placedItem; + + private boolean cancelled = false; + private boolean locked = false; + + /** + * This creates a new {@link BlockPlacerPlaceEvent}. + * + * @param blockPlacer + * The {@link BlockPlacer} + * @param placedItem + * The {@link ItemStack} of the {@link Block} that was placed + * @param block + * The placed {@link Block} + */ + public BlockPlacerPlaceEvent(Block blockPlacer, ItemStack placedItem, Block block) { + super(block); + + this.placedItem = placedItem; + this.blockPlacer = blockPlacer; + } + + /** + * This method returns the {@link BlockPlacer} + * + * @return The {@link BlockPlacer} + */ + public Block getBlockPlacer() { + return blockPlacer; + } + + /** + * This returns the placed {@link ItemStack}. + * + * @return The placed {@link ItemStack} + */ + public ItemStack getItemStack() { + return placedItem; + } + + /** + * This sets the placed {@link ItemStack}. + * + * @param item + * The {@link ItemStack} to be placed + */ + public void setItemStack(ItemStack item) { + Validate.notNull(item, "The ItemStack must not be null!"); + + if (!locked) { + this.placedItem = item; + } + else { + SlimefunItem.getByItem(placedItem).warn("A BlockPlacerPlaceEvent cannot be modified from within a BlockPlaceHandler!"); + } + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + if (!locked) { + cancelled = cancel; + } + else { + SlimefunItem.getByItem(placedItem).warn("A BlockPlacerPlaceEvent cannot be modified from within a BlockPlaceHandler!"); + } + } + + /** + * This marks this {@link Event} as immutable, it can no longer be modified afterwards. + */ + public void setImmutable() { + locked = true; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + +} \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/GEOResourceGenerationEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/GEOResourceGenerationEvent.java index d560dab5c..acfdf7936 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/GEOResourceGenerationEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/GEOResourceGenerationEvent.java @@ -129,12 +129,13 @@ public class GEOResourceGenerationEvent extends Event { return biome; } - public HandlerList getHandlers() { - return handlers; - } - public static HandlerList getHandlerList() { return handlers; } + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/MultiBlockInteractEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/MultiBlockInteractEvent.java index 2d61f648a..fec7b8097 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/MultiBlockInteractEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/MultiBlockInteractEvent.java @@ -25,14 +25,6 @@ public class MultiBlockInteractEvent extends PlayerEvent implements Cancellable private final BlockFace clickedFace; private boolean cancelled; - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - public MultiBlockInteractEvent(Player p, MultiBlock mb, Block clicked, BlockFace face) { super(p); this.multiBlock = mb; @@ -77,4 +69,13 @@ public class MultiBlockInteractEvent extends PlayerEvent implements Cancellable this.cancelled = cancel; } + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerLanguageChangeEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerLanguageChangeEvent.java index 08a628508..ca5b9c283 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerLanguageChangeEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerLanguageChangeEvent.java @@ -30,14 +30,6 @@ public class PlayerLanguageChangeEvent extends Event { this.to = to; } - public static HandlerList getHandlerList() { - return handlers; - } - - public HandlerList getHandlers() { - return handlers; - } - /** * Returns the {@link Player} who triggered this {@link Event}, * the {@link Player} who switched his {@link Language} to be precise. @@ -66,4 +58,13 @@ public class PlayerLanguageChangeEvent extends Event { return to; } + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerRightClickEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerRightClickEvent.java index 52234355f..e7580179e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerRightClickEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerRightClickEvent.java @@ -50,14 +50,6 @@ public class PlayerRightClickEvent extends Event { } } - public static HandlerList getHandlerList() { - return handlers; - } - - public HandlerList getHandlers() { - return handlers; - } - public PlayerInteractEvent getInteractEvent() { return event; } @@ -144,4 +136,13 @@ public class PlayerRightClickEvent extends Event { blockResult = result; } + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/ReactorExplodeEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/ReactorExplodeEvent.java index 230211e2d..4a2af108a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/ReactorExplodeEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/ReactorExplodeEvent.java @@ -47,12 +47,13 @@ public class ReactorExplodeEvent extends Event { return reactor; } - public HandlerList getHandlers() { - return handlers; - } - public static HandlerList getHandlerList() { return handlers; } + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/ResearchUnlockEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/ResearchUnlockEvent.java index cd517ea68..53a3e74e3 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/ResearchUnlockEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/ResearchUnlockEvent.java @@ -23,14 +23,6 @@ public class ResearchUnlockEvent extends Event implements Cancellable { private final Research research; private boolean cancelled; - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - public ResearchUnlockEvent(Player p, Research research) { this.player = p; this.research = research; @@ -54,4 +46,13 @@ public class ResearchUnlockEvent extends Event implements Cancellable { this.cancelled = cancel; } + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/WaypointCreateEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/WaypointCreateEvent.java index 4dc2a2962..8f2866331 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/WaypointCreateEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/WaypointCreateEvent.java @@ -32,14 +32,6 @@ public class WaypointCreateEvent extends PlayerEvent implements Cancellable { private final boolean deathpoint; private boolean cancelled; - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - public WaypointCreateEvent(Player player, String name, Location location) { super(player); @@ -112,4 +104,13 @@ public class WaypointCreateEvent extends PlayerEvent implements Cancellable { this.cancelled = cancel; } + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java index 511c8e418..9fd78d6b1 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java @@ -283,6 +283,14 @@ public class GPSNetwork { if (!event.isCancelled()) { String id = ChatColor.stripColor(ChatColors.color(event.getName())).toUpperCase(Locale.ROOT).replace(' ', '_'); + + for (Waypoint wp : profile.getWaypoints()) { + if (wp.getId().equals(id)) { + SlimefunPlugin.getLocalization().sendMessage(p, "gps.waypoint.duplicate", true, msg -> msg.replace("%waypoint%", event.getName())); + return; + } + } + profile.addWaypoint(new Waypoint(profile, id, event.getLocation(), event.getName())); p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1F, 1F); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/HashedArmorpiece.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/HashedArmorpiece.java index a848cadca..a3bbe0185 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/HashedArmorpiece.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/HashedArmorpiece.java @@ -99,4 +99,9 @@ public final class HashedArmorpiece { return item; } + @Override + public String toString() { + return "HashedArmorpiece {hash=" + hash + ",item=" + item.map(SlimefunItem::getID).orElse(null) + '}'; + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/network/Network.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/network/Network.java index 0158dbbd4..9cc30d2d0 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/network/Network.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/network/Network.java @@ -225,6 +225,11 @@ public abstract class Network { }); } + /** + * This returns the {@link Location} of the regulator block for this {@link Network} + * + * @return The {@link Location} of our regulator + */ public Location getRegulator() { return regulator; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java index a030a751e..0184fb95c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java @@ -32,8 +32,8 @@ import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.slimefun4.api.gps.Waypoint; import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece; -import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectiveArmor; import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType; +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectiveArmor; import io.github.thebusybiscuit.slimefun4.core.guide.GuideHistory; import io.github.thebusybiscuit.slimefun4.core.researching.Research; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; @@ -455,11 +455,13 @@ public final class PlayerProfile { int armorCount = 0; NamespacedKey setId = null; + for (HashedArmorpiece armorpiece : armor) { Optional armorPiece = armorpiece.getItem(); if (!armorPiece.isPresent()) { - return false; + setId = null; + continue; } if (armorPiece.get() instanceof ProtectiveArmor) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java index 710cd83e4..b6bc8f953 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java @@ -13,7 +13,9 @@ import java.util.concurrent.ConcurrentHashMap; import org.bukkit.Location; import org.bukkit.Server; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Piglin; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.collections.KeyMap; @@ -64,10 +66,12 @@ public class SlimefunRegistry { private boolean enableResearches; private boolean freeCreativeResearches; private boolean researchFireworks; + private boolean logDuplicateBlockEntries; private final Set tickers = new HashSet<>(); private final Set radioactive = new HashSet<>(); - private final Set activeChunks = new HashSet<>(); + private final Set activeChunks = ConcurrentHashMap.newKeySet(); + private final Set barterDrops = new HashSet<>(); private final KeyMap geoResources = new KeyMap<>(); @@ -82,7 +86,7 @@ public class SlimefunRegistry { private final Map, Set> globalItemHandlers = new HashMap<>(); private final Map blockHandlers = new HashMap<>(); - private final Map> activeTickers = new HashMap<>(); + private final Map> activeTickers = new ConcurrentHashMap<>(); private final Map automatedCraftingChamberRecipes = new HashMap<>(); @@ -98,6 +102,7 @@ public class SlimefunRegistry { backwardsCompatibility = cfg.getBoolean("options.backwards-compatibility") || SlimefunPlugin.getMinecraftVersion().isBefore(MinecraftVersion.MINECRAFT_1_14); freeCreativeResearches = cfg.getBoolean("researches.free-in-creative-mode"); researchFireworks = cfg.getBoolean("researches.enable-fireworks"); + logDuplicateBlockEntries = cfg.getBoolean("options.log-duplicate-block-entries"); } /** @@ -193,10 +198,26 @@ public class SlimefunRegistry { return layouts.get(layout); } + /** + * This returns a {@link Map} connecting the {@link EntityType} with a {@link Set} + * of {@link ItemStack ItemStacks} which would be dropped when an {@link Entity} of that type was killed. + * + * @return The {@link Map} of custom mob drops + */ public Map> getMobDrops() { return mobDrops; } + /** + * This returns a {@link Set} of {@link ItemStack ItemStacks} which can be obtained by bartering + * with {@link Piglin Piglins}. + * + * @return A {@link Set} of bartering drops + */ + public Set getBarteringDrops() { + return barterDrops; + } + public Set getRadioactiveItems() { return radioactive; } @@ -265,4 +286,8 @@ public class SlimefunRegistry { return automatedCraftingChamberRecipes; } + public boolean logDuplicateBlockEntries() { + return logDuplicateBlockEntries; + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/PiglinBarterDrop.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/PiglinBarterDrop.java new file mode 100644 index 000000000..32a3b6449 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/PiglinBarterDrop.java @@ -0,0 +1,36 @@ +package io.github.thebusybiscuit.slimefun4.core.attributes; + +import org.bukkit.entity.Piglin; +import org.bukkit.event.entity.EntityDropItemEvent; + +import io.github.thebusybiscuit.slimefun4.implementation.listeners.PiglinListener; +import me.mrCookieSlime.Slimefun.Lists.RecipeType; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; + +/** + * This interface, when attached to a {@link SlimefunItem}, provides a variable (0-100%) chance for + * a {@link SlimefunItem} to be dropped by a {@link Piglin} on {@link EntityDropItemEvent}. + * + * @author dNiym + * + * @see PiglinListener + * @see RandomMobDrop + * + */ +@FunctionalInterface +public interface PiglinBarterDrop extends ItemAttribute { + + /** + * Implement this method to make this {@link SlimefunItem} have a variable chance + * of being dropped by a {@link Piglin} when bartering with them. This interface + * should be used with the {@link RecipeType#BARTER_DROP}. + * + * It is recommended that this chance is kept reasonably low to feel like + * a vanilla drop as a 100% chance will completely override all {@link Piglin} + * barter drops. (NOTE: this feature only exists in 1.16+) + * + * @return The integer chance (1-99%) this {@link SlimefunItem} has to drop. + */ + int getBarteringLootChance(); + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/Placeable.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/Placeable.java index 6bc83f5e7..abd41a071 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/Placeable.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/Placeable.java @@ -37,18 +37,4 @@ public interface Placeable { return false; } - default void onPlace(Player p, Block b) { - // Override this as necessary - } - - default boolean onBreak(Player p, Block b) { - // Override this as necessary - return true; - } - - default boolean onExplode(Block b) { - // Override this as necessary - return true; - } - } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RandomMobDrop.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RandomMobDrop.java index a873b8620..136ccb96c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RandomMobDrop.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RandomMobDrop.java @@ -12,12 +12,13 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; /** * This interface, when attached to a {@link SlimefunItem}, provides an easy method for adding * a % chance to drop for an {@link SlimefunItem} on {@link EntityDeathEvent}, this chance is 0-100 - * and used in conjunction with the MOB_DROP {@link RecipeType}. + * and used in conjunction with the {@link RecipeType#MOB_DROP}. * * @author dNiym * * @see BasicCircuitBoard * @see MobDropListener + * @see PiglinBarterDrop * */ @FunctionalInterface @@ -25,8 +26,8 @@ public interface RandomMobDrop extends ItemAttribute { /** * Implement this method to make the object have a variable chance of being - * added to the dropList when {@link EntityType} (specified in the recipe) - * is killed by the {@link Player} + * added to the dropList when {@link EntityType} specified in + * the {@link RecipeType#MOB_DROP} is killed by the {@link Player}. * * @return The integer chance (0-100%) {@link SlimefunItem} has to drop. */ diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SubCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SubCommand.java index ede461878..4edbd09c4 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SubCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SubCommand.java @@ -4,6 +4,7 @@ import java.util.Map; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import org.bukkit.command.defaults.HelpCommand; import org.bukkit.entity.Player; import io.github.thebusybiscuit.slimefun4.core.services.localization.Language; @@ -23,14 +24,35 @@ public abstract class SubCommand { protected final SlimefunPlugin plugin; protected final SlimefunCommand cmd; - protected SubCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { + private final String name; + private final boolean hidden; + + protected SubCommand(SlimefunPlugin plugin, SlimefunCommand cmd, String name, boolean hidden) { this.plugin = plugin; this.cmd = cmd; + + this.name = name; + this.hidden = hidden; } - public abstract String getName(); + /** + * This returns the name of this {@link SubCommand}, the name is equivalent to the + * first argument given to the actual command. + * + * @return The name of this {@link SubCommand} + */ + public final String getName() { + return name; + } - public abstract boolean isHidden(); + /** + * This method returns whether this {@link SubCommand} is hidden from the {@link HelpCommand}. + * + * @return Whether to hide this {@link SubCommand} + */ + public final boolean isHidden() { + return hidden; + } protected void recordUsage(Map commandUsage) { commandUsage.merge(this, 1, Integer::sum); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/BackpackCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/BackpackCommand.java index f607010c3..1b1478e30 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/BackpackCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/BackpackCommand.java @@ -17,12 +17,7 @@ import me.mrCookieSlime.Slimefun.api.Slimefun; class BackpackCommand extends SubCommand { BackpackCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { - super(plugin, cmd); - } - - @Override - public String getName() { - return "backpack"; + super(plugin, cmd, "backpack", false); } @Override @@ -30,11 +25,6 @@ class BackpackCommand extends SubCommand { return "commands.backpack.description"; } - @Override - public boolean isHidden() { - return false; - } - @Override public void onExecute(CommandSender sender, String[] args) { if (!(sender instanceof Player) || !sender.hasPermission("slimefun.command.backpack")) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/CheatCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/CheatCommand.java index faa553341..450abd94d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/CheatCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/CheatCommand.java @@ -11,17 +11,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; class CheatCommand extends SubCommand { CheatCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { - super(plugin, cmd); - } - - @Override - public String getName() { - return "cheat"; - } - - @Override - public boolean isHidden() { - return false; + super(plugin, cmd, "cheat", false); } @Override diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/DebugFishCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/DebugFishCommand.java index dcc63f273..f1e8656fc 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/DebugFishCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/DebugFishCommand.java @@ -11,23 +11,13 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; class DebugFishCommand extends SubCommand { DebugFishCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { - super(plugin, cmd); - } - - @Override - public String getName() { - return "debug_fish"; - } - - @Override - public boolean isHidden() { - return true; + super(plugin, cmd, "debug_fish", true); } @Override public void onExecute(CommandSender sender, String[] args) { - if (sender instanceof Player && sender.isOp()) { - ((Player) sender).getInventory().addItem(SlimefunItems.DEBUG_FISH); + if (sender instanceof Player && sender.hasPermission("slimefun.debugging")) { + ((Player) sender).getInventory().addItem(SlimefunItems.DEBUG_FISH.clone()); } else { SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GiveCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GiveCommand.java index 8c9457845..eb9c8d131 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GiveCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GiveCommand.java @@ -22,17 +22,7 @@ class GiveCommand extends SubCommand { private static final String PLACEHOLDER_AMOUNT = "%amount%"; GiveCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { - super(plugin, cmd); - } - - @Override - public String getName() { - return "give"; - } - - @Override - public boolean isHidden() { - return false; + super(plugin, cmd, "give", false); } @Override diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GuideCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GuideCommand.java index a233cc3f5..19b6b40a2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GuideCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GuideCommand.java @@ -12,24 +12,15 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; class GuideCommand extends SubCommand { GuideCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { - super(plugin, cmd); - } - - @Override - public String getName() { - return "guide"; - } - - @Override - public boolean isHidden() { - return false; + super(plugin, cmd, "guide", false); } @Override public void onExecute(CommandSender sender, String[] args) { if (sender instanceof Player) { if (sender.hasPermission("slimefun.command.guide")) { - ((Player) sender).getInventory().addItem(SlimefunGuide.getItem(SlimefunPlugin.getCfg().getBoolean("guide.default-view-book") ? SlimefunGuideLayout.BOOK : SlimefunGuideLayout.CHEST)); + SlimefunGuideLayout design = SlimefunGuide.getDefaultLayout(); + ((Player) sender).getInventory().addItem(SlimefunGuide.getItem(design).clone()); } else { SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/HelpCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/HelpCommand.java index 1c241462d..43e43feb3 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/HelpCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/HelpCommand.java @@ -9,17 +9,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; class HelpCommand extends SubCommand { HelpCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { - super(plugin, cmd); - } - - @Override - public String getName() { - return "help"; - } - - @Override - public boolean isHidden() { - return false; + super(plugin, cmd, "help", false); } @Override diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/OpenGuideCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/OpenGuideCommand.java index a286db515..ab6e087b2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/OpenGuideCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/OpenGuideCommand.java @@ -12,17 +12,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; class OpenGuideCommand extends SubCommand { OpenGuideCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { - super(plugin, cmd); - } - - @Override - public String getName() { - return "open_guide"; - } - - @Override - public boolean isHidden() { - return false; + super(plugin, cmd, "open_guide", false); } @Override diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/ResearchCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/ResearchCommand.java index 1ea35f95b..bb230acda 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/ResearchCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/ResearchCommand.java @@ -19,17 +19,7 @@ class ResearchCommand extends SubCommand { private static final String PLACEHOLDER_RESEARCH = "%research%"; ResearchCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { - super(plugin, cmd); - } - - @Override - public String getName() { - return "research"; - } - - @Override - public boolean isHidden() { - return false; + super(plugin, cmd, "research", false); } @Override diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SearchCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SearchCommand.java index 60186e0c4..22169a7ae 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SearchCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SearchCommand.java @@ -14,17 +14,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; class SearchCommand extends SubCommand { SearchCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { - super(plugin, cmd); - } - - @Override - public String getName() { - return "search"; - } - - @Override - public boolean isHidden() { - return false; + super(plugin, cmd, "search", false); } @Override diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/StatsCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/StatsCommand.java index 29e3b861a..a2e9628b3 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/StatsCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/StatsCommand.java @@ -15,17 +15,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; class StatsCommand extends SubCommand { StatsCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { - super(plugin, cmd); - } - - @Override - public String getName() { - return "stats"; - } - - @Override - public boolean isHidden() { - return false; + super(plugin, cmd, "stats", false); } @Override diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/TeleporterCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/TeleporterCommand.java index 75437e35e..8031116ca 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/TeleporterCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/TeleporterCommand.java @@ -13,17 +13,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; class TeleporterCommand extends SubCommand { TeleporterCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { - super(plugin, cmd); - } - - @Override - public String getName() { - return "teleporter"; - } - - @Override - public boolean isHidden() { - return false; + super(plugin, cmd, "teleporter", false); } @Override diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/TimingsCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/TimingsCommand.java index 2b85e48aa..7b5e4b7e9 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/TimingsCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/TimingsCommand.java @@ -10,17 +10,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; class TimingsCommand extends SubCommand { TimingsCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { - super(plugin, cmd); - } - - @Override - public String getName() { - return "timings"; - } - - @Override - public boolean isHidden() { - return false; + super(plugin, cmd, "timings", false); } @Override diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java index 2ca581eff..505f29c62 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java @@ -2,32 +2,23 @@ package io.github.thebusybiscuit.slimefun4.core.commands.subcommands; import java.util.Collection; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.plugin.Plugin; + import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.reflection.ReflectionUtils; import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand; import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.plugin.Plugin; import io.papermc.lib.PaperLib; class VersionsCommand extends SubCommand { VersionsCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { - super(plugin, cmd); - } - - @Override - public String getName() { - return "versions"; - } - - @Override - public boolean isHidden() { - return false; + super(plugin, cmd, "versions", false); } @Override @@ -36,29 +27,33 @@ class VersionsCommand extends SubCommand { // After all these years... Spigot still displays as "CraftBukkit" // so we will just fix this inconsistency for them :) String serverSoftware = PaperLib.isSpigot() && !PaperLib.isPaper() ? "Spigot" : Bukkit.getName(); + + sender.sendMessage(ChatColor.GRAY + "This Server uses the following setup of Slimefun:"); sender.sendMessage(ChatColors.color("&a" + serverSoftware + " &2" + ReflectionUtils.getVersion())); - sender.sendMessage(""); sender.sendMessage(ChatColors.color("&aCS-CoreLib &2v" + SlimefunPlugin.getCSCoreLibVersion())); sender.sendMessage(ChatColors.color("&aSlimefun &2v" + SlimefunPlugin.getVersion())); - if (SlimefunPlugin.getMetricsService().getVersion() != null) - sender.sendMessage(ChatColors.color("&aMetrics: &2#" + SlimefunPlugin.getMetricsService().getVersion() + ')')); + if (SlimefunPlugin.getMetricsService().getVersion() != null) { + sender.sendMessage(ChatColors.color("&aMetrics build: &2#" + SlimefunPlugin.getMetricsService().getVersion())); + } if (SlimefunPlugin.getRegistry().isBackwardsCompatible()) { - sender.sendMessage(ChatColor.YELLOW + "Backwards compatibility enabled!"); + sender.sendMessage(ChatColor.RED + "Backwards compatibility enabled!"); } sender.sendMessage(""); Collection addons = SlimefunPlugin.getInstalledAddons(); - sender.sendMessage(ChatColors.color("&7Installed Addons &8(" + addons.size() + ")")); + sender.sendMessage(ChatColors.color("&7Installed Addons: &8(" + addons.size() + ")")); for (Plugin plugin : addons) { + String version = plugin.getDescription().getVersion(); + if (Bukkit.getPluginManager().isPluginEnabled(plugin)) { - sender.sendMessage(ChatColors.color(" &a" + plugin.getName() + " &2v" + plugin.getDescription().getVersion())); + sender.sendMessage(ChatColor.GREEN + " " + plugin.getName() + ChatColor.DARK_GREEN + " v" + version); } else { - sender.sendMessage(ChatColors.color(" &c" + plugin.getName() + " &4v" + plugin.getDescription().getVersion())); + sender.sendMessage(ChatColor.RED + " " + plugin.getName() + ChatColor.DARK_RED + " v" + version); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuide.java index 14ff02237..6760baae1 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuide.java @@ -1,16 +1,10 @@ package io.github.thebusybiscuit.slimefun4.core.guide; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; import java.util.Optional; -import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide; @@ -36,31 +30,7 @@ public final class SlimefunGuide { private SlimefunGuide() {} public static ItemStack getItem(SlimefunGuideLayout design) { - ItemStack item = new ItemStack(Material.ENCHANTED_BOOK); - ItemMeta meta = item.getItemMeta(); - List lore = new LinkedList<>(); - lore.addAll(Arrays.asList("", ChatColors.color("&eRight Click &8\u21E8 &7Browse Items"), ChatColors.color("&eShift + Right Click &8\u21E8 &7Open Settings / Credits"))); - - switch (design) { - case BOOK: - meta.setDisplayName(ChatColors.color("&aSlimefun Guide &7(Book GUI)")); - break; - case CHEAT_SHEET: - meta.setDisplayName(ChatColors.color("&cSlimefun Guide &4(Cheat Sheet)")); - lore.add(0, ChatColors.color("&4&lOnly openable by Admins")); - lore.add(0, ""); - break; - case CHEST: - meta.setDisplayName(ChatColors.color("&aSlimefun Guide &7(Chest GUI)")); - break; - default: - return null; - } - - meta.setLore(lore); - SlimefunPlugin.getItemTextureService().setTexture(meta, "SLIMEFUN_GUIDE"); - item.setItemMeta(meta); - return item; + return SlimefunPlugin.getRegistry().getGuideLayout(design).getItem(); } public static void openCheatMenu(Player p) { @@ -132,4 +102,13 @@ public final class SlimefunGuide { public static boolean isGuideItem(ItemStack item) { return SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideLayout.CHEST), true) || SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideLayout.BOOK), true) || SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideLayout.CHEAT_SHEET), true); } + + public static SlimefunGuideLayout getDefaultLayout() { + if (SlimefunPlugin.getCfg().getBoolean("guide.default-view-book")) { + return SlimefunGuideLayout.BOOK; + } + else { + return SlimefunGuideLayout.CHEST; + } + } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/ContributorsMenu.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/ContributorsMenu.java index 3b89ff019..df5d74cf0 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/ContributorsMenu.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/ContributorsMenu.java @@ -21,6 +21,12 @@ import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; +/** + * This menu shows a list of every {@link Contributor} to this project. + * + * @author TheBusyBiscuit + * + */ final class ContributorsMenu { private ContributorsMenu() {} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideLayoutOption.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideLayoutOption.java index e6fe73e3a..92379ac9b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideLayoutOption.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideLayoutOption.java @@ -102,7 +102,7 @@ class GuideLayoutOption implements SlimefunGuideOption { @Override public Optional getSelectedOption(Player p, ItemStack guide) { for (SlimefunGuideLayout layout : SlimefunGuideLayout.values()) { - if (SlimefunUtils.isItemSimilar(guide, SlimefunGuide.getItem(layout), true)) { + if (SlimefunUtils.isItemSimilar(guide, SlimefunGuide.getItem(layout), true, false)) { return Optional.of(layout); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/PlayerLanguageOption.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/PlayerLanguageOption.java index 6d55090a2..961ec32c9 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/PlayerLanguageOption.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/PlayerLanguageOption.java @@ -1,5 +1,7 @@ package io.github.thebusybiscuit.slimefun4.core.guide.options; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import org.bukkit.ChatColor; @@ -16,6 +18,7 @@ import io.github.thebusybiscuit.slimefun4.core.services.localization.Language; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; +import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; @@ -37,7 +40,16 @@ class PlayerLanguageOption implements SlimefunGuideOption { Language language = SlimefunPlugin.getLocalization().getLanguage(p); String languageName = language.isDefault() ? (SlimefunPlugin.getLocalization().getMessage(p, "languages.default") + ChatColor.DARK_GRAY + " (" + language.getName(p) + ")") : SlimefunPlugin.getLocalization().getMessage(p, "languages." + language.getId()); - return Optional.of(new CustomItem(language.getItem(), "&7" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.selected-language") + " &a" + languageName, "", "&7You now have the option to change", "&7the language in which Slimefun", "&7will send you messages.", "&7Note that this only translates", "&7some messages, not items.", "&7&oThis feature is still being worked on", "", "&7\u21E8 &eClick to change your language")); + List lore = new ArrayList<>(); + lore.add(""); + lore.add("&e&o" + SlimefunPlugin.getLocalization().getMessage(p, "guide.work-in-progress")); + lore.add(""); + lore.addAll(SlimefunPlugin.getLocalization().getMessages(p, "guide.languages.description", msg -> msg.replace("%contributors%", String.valueOf(SlimefunPlugin.getGitHubService().getContributors().size())))); + lore.add(""); + lore.add("&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.change")); + + ItemStack item = new CustomItem(language.getItem(), "&7" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.selected-language") + " &a" + languageName, lore.toArray(new String[0])); + return Optional.of(item); } else { return Optional.empty(); @@ -78,7 +90,7 @@ class PlayerLanguageOption implements SlimefunGuideOption { }); } else if (i == 7) { - menu.addItem(7, new CustomItem(SlimefunUtils.getCustomHead("3edd20be93520949e6ce789dc4f43efaeb28c717ee6bfcbbe02780142f716"), SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.translations.name"), "", "&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.translations.lore")), (pl, slot, item, action) -> { + menu.addItem(7, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.ADD_NEW_LANGUAGE.getTexture()), SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.translations.name"), "", "&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.translations.lore")), (pl, slot, item, action) -> { ChatUtils.sendURL(pl, "https://github.com/TheBusyBiscuit/Slimefun4/wiki/Translating-Slimefun"); pl.closeInventory(); return false; @@ -105,7 +117,7 @@ class PlayerLanguageOption implements SlimefunGuideOption { int slot = 10; for (Language language : SlimefunPlugin.getLocalization().getLanguages()) { - menu.addItem(slot, new CustomItem(language.getItem(), ChatColor.GREEN + language.getName(p), "&b" + SlimefunPlugin.getLocalization().getProgress(language) + '%', "", "&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.select")), (pl, i, item, action) -> { + menu.addItem(slot, new CustomItem(language.getItem(), ChatColor.GREEN + language.getName(p), "&b" + language.getTranslationProgress() + '%', "", "&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.select")), (pl, i, item, action) -> { SlimefunPlugin.instance().getServer().getPluginManager().callEvent(new PlayerLanguageChangeEvent(pl, SlimefunPlugin.getLocalization().getLanguage(pl), language)); setSelectedOption(pl, guide, language.getId()); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideOption.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideOption.java index a61f0d76a..a1318fedf 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideOption.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideOption.java @@ -19,6 +19,11 @@ import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; */ public interface SlimefunGuideOption extends Keyed { + /** + * This returns the {@link SlimefunAddon} which added this {@link SlimefunGuideOption}. + * + * @return The registering {@link SlimefunAddon} + */ SlimefunAddon getAddon(); Optional getDisplayItem(Player p, ItemStack guide); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideSettings.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideSettings.java index b65c52b8d..09c20cd1a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideSettings.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideSettings.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Optional; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; @@ -73,14 +74,21 @@ public final class SlimefunGuideSettings { return false; }); - menu.addItem(2, new CustomItem(SlimefunUtils.getCustomHead("e952d2b3f351a6b0487cc59db31bf5f2641133e5ba0006b18576e996a0293e52"), "&c" + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.credits"), "", "&7Contributors: &e" + SlimefunPlugin.getGitHubService().getContributors().size(), "", "&7Slimefun is an open-source project", "&7and maintained by a large community of people.", "&7Here you can see who helped shape the project.", "", "&7\u21E8 &eClick to see our contributors"), (pl, slot, action, item) -> { + List contributorsLore = new ArrayList<>(); + contributorsLore.add(""); + contributorsLore.addAll(SlimefunPlugin.getLocalization().getMessages(p, "guide.credits.description", msg -> msg.replace("%contributors%", String.valueOf(SlimefunPlugin.getGitHubService().getContributors().size())))); + contributorsLore.add(""); + contributorsLore.add("&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.credits.open")); + + menu.addItem(2, new CustomItem(SlimefunUtils.getCustomHead("e952d2b3f351a6b0487cc59db31bf5f2641133e5ba0006b18576e996a0293e52"), "&c" + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.credits"), contributorsLore.toArray(new String[0])), (pl, slot, action, item) -> { ContributorsMenu.open(pl, 0); return false; }); - menu.addItem(4, new CustomItem(Material.WRITABLE_BOOK, "&aSlimefun Version", "&7&o" + SlimefunPlugin.getLocalization().getMessage(p, "guide.tooltips.versions-notice"), "", "&fMinecraft Version: &a" + Bukkit.getBukkitVersion(), "&fSlimefun Version: &a" + SlimefunPlugin.getVersion(), "&fCS-CoreLib Version: &a" + SlimefunPlugin.getCSCoreLibVersion()), ChestMenuUtils.getEmptyClickHandler()); + menu.addItem(4, new CustomItem(Material.WRITABLE_BOOK, ChatColor.GREEN + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.versions"), "&7&o" + SlimefunPlugin.getLocalization().getMessage(p, "guide.tooltips.versions-notice"), "", "&fMinecraft: &a" + Bukkit.getBukkitVersion(), "&fSlimefun: &a" + SlimefunPlugin.getVersion(), "&fCS-CoreLib: &a" + SlimefunPlugin.getCSCoreLibVersion()), ChestMenuUtils.getEmptyClickHandler()); - menu.addItem(6, new CustomItem(Material.COMPARATOR, "&e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.source"), "", "&7Last Activity: &a" + NumberUtils.getElapsedTime(SlimefunPlugin.getGitHubService().getLastUpdate()) + " ago", "&7Forks: &e" + SlimefunPlugin.getGitHubService().getForks(), "&7Stars: &e" + SlimefunPlugin.getGitHubService().getStars(), "", "&7&oSlimefun 4 is a community project,", "&7&othe source code is available on GitHub", "&7&oand if you want to keep this Plugin alive,", "&7&othen please consider contributing to it", "", "&7\u21E8 &eClick to go to GitHub")); + menu.addItem(6, + new CustomItem(Material.COMPARATOR, "&e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.source"), "", "&7Last Activity: &a" + NumberUtils.getElapsedTime(SlimefunPlugin.getGitHubService().getLastUpdate()) + " ago", "&7Forks: &e" + SlimefunPlugin.getGitHubService().getForks(), "&7Stars: &e" + SlimefunPlugin.getGitHubService().getStars(), "", "&7&oSlimefun 4 is a community project,", "&7&othe source code is available on GitHub", "&7&oand if you want to keep this Plugin alive,", "&7&othen please consider contributing to it", "", "&7\u21E8 &eClick to go to GitHub")); menu.addMenuClickHandler(6, (pl, slot, item, action) -> { pl.closeInventory(); ChatUtils.sendURL(pl, "https://github.com/TheBusyBiscuit/Slimefun4"); @@ -110,7 +118,7 @@ public final class SlimefunGuideSettings { menu.addItem(49, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler()); } - menu.addItem(51, new CustomItem(Material.TOTEM_OF_UNDYING, "&cSoon", "", "&7Something will be added here later..."), (pl, slot, item, action) -> { + menu.addItem(51, new CustomItem(Material.TOTEM_OF_UNDYING, ChatColor.RED + SlimefunPlugin.getLocalization().getMessage(p, "guide.work-in-progress")), (pl, slot, item, action) -> { // Add something here return false; }); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/BlockPlaceHandler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/BlockPlaceHandler.java index cd4dccf81..c17dbd6a2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/BlockPlaceHandler.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/BlockPlaceHandler.java @@ -1,18 +1,62 @@ package io.github.thebusybiscuit.slimefun4.core.handlers; +import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent; +import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.BlockPlacer; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler; -@FunctionalInterface -public interface BlockPlaceHandler extends ItemHandler { +/** + * This {@link ItemHandler} is called whenever a {@link Block} was placed. + * This only listens to any {@link Block} of the same {@link SlimefunItem} this is assigned + * to. + * + * @author TheBusyBiscuit + * + */ +public abstract class BlockPlaceHandler implements ItemHandler { - boolean onBlockPlace(Player p, BlockPlaceEvent e, ItemStack item); + private final boolean allowBlockPlacers; + + public BlockPlaceHandler(boolean allowBlockPlacers) { + this.allowBlockPlacers = allowBlockPlacers; + } + + /** + * This method is called whenever a {@link Player} placed this {@link Block}. + * + * @param e + * The corresponding {@link BlockPlaceEvent} + */ + public abstract void onPlayerPlace(BlockPlaceEvent e); + + /** + * This method is called whenever a {@link BlockPlacer} places this {@link Block}. + * You cannot cancel the {@link BlockPlacerPlaceEvent} from within this method! + * Override the method {@link #isBlockPlacerAllowed()} instead if you want to disallow the + * {@link BlockPlacer} from placing this {@link Block}. + * + * @param e + * The corresponding {@link BlockPlacerPlaceEvent} + */ + public void onBlockPlacerPlace(BlockPlacerPlaceEvent e) { + // This can be overridden, if necessary + } + + /** + * This returns whether the {@link BlockPlacer} is allowed to place a {@link Block} of this type. + * + * @return Whether a {@link BlockPlacer} is allowed to place this + */ + public boolean isBlockPlacerAllowed() { + return allowBlockPlacers; + } @Override - default Class getIdentifier() { + public Class getIdentifier() { return BlockPlaceHandler.class; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/EntityInteractHandler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/EntityInteractHandler.java index 919275888..1d6507902 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/EntityInteractHandler.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/EntityInteractHandler.java @@ -3,10 +3,12 @@ package io.github.thebusybiscuit.slimefun4.core.handlers; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.EntityInteractionListener; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler; @@ -15,9 +17,9 @@ import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler; * * @author Linox * + * @see EntityInteractionListener * @see ItemHandler * @see SimpleSlimefunItem - * @see PlayerInteractAtEntityEvent * */ @FunctionalInterface @@ -27,16 +29,14 @@ public interface EntityInteractHandler extends ItemHandler { * This function is triggered when a {@link Player} right clicks with the assigned {@link SlimefunItem} * in his hand. * - * @param p - * The {@link Player} that right clicked - * @param entity - * The {@link Entity} that was right clicked on + * @param e + * The {@link PlayerInteractAtEntityEvent} which was called * @param item * The {@link ItemStack} that was held and used while triggering * @param offHand * true if the {@link EquipmentSlot} is off hand */ - void onInteract(Player p, Entity entity, ItemStack item, boolean offHand); + void onInteract(PlayerInteractEntityEvent e, ItemStack item, boolean offHand); @Override default Class getIdentifier() { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/RainbowTickHandler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/RainbowTickHandler.java index 70fa1ce35..5cd2867ea 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/RainbowTickHandler.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/RainbowTickHandler.java @@ -104,7 +104,7 @@ public class RainbowTickHandler extends BlockTicker { } }); - b.setBlockData(block); + b.setBlockData(block, false); return; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/ToolUseHandler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/ToolUseHandler.java new file mode 100644 index 000000000..df533811d --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/handlers/ToolUseHandler.java @@ -0,0 +1,45 @@ +package io.github.thebusybiscuit.slimefun4.core.handlers; + +import java.util.List; + +import org.bukkit.block.Block; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.inventory.ItemStack; + +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler; + +/** + * This {@link ItemHandler} is called when a {@link Block} is broken with a {@link SlimefunItem} + * as its tool. + * + * @author TheBusyBiscuit + * + * @see BlockBreakHandler + * + */ +@FunctionalInterface +public interface ToolUseHandler extends ItemHandler { + + /** + * This method is called whenever a {@link BlockBreakEvent} was fired when using this + * {@link SlimefunItem} to break a {@link Block}. + * + * @param e + * The {@link BlockBreakEvent} + * @param tool + * The tool that was used + * @param fortune + * The amount of bonus drops to be expected from the fortune {@link Enchantment}. + * @param drops + * The dropped items + * + */ + void onToolUse(BlockBreakEvent e, ItemStack tool, int fortune, List drops); + + @Override + default Class getIdentifier() { + return ToolUseHandler.class; + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java index f8df07d58..681fffaaa 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java @@ -175,7 +175,7 @@ public class CargoNet extends ChestTerminalNetwork { display(); } - SlimefunPlugin.getProfiler().scheduleEntries(1 + inputNodes.size()); + SlimefunPlugin.getProfiler().scheduleEntries((terminals.isEmpty() ? 1 : 2) + inputs.size()); CargoNetworkTask runnable = new CargoNetworkTask(this, inputs, outputs, chestTerminalInputs, chestTerminalOutputs); Slimefun.runSync(runnable); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNetworkTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNetworkTask.java index eec1652df..11b87f47e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNetworkTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNetworkTask.java @@ -16,6 +16,7 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; @@ -63,6 +64,7 @@ class CargoNetworkTask implements Runnable { // All operations happen here: Everything gets iterated from the Input Nodes. // (Apart from ChestTerminal Buses) + SlimefunItem inputNode = SlimefunItems.CARGO_INPUT_NODE.getItem(); for (Map.Entry entry : inputs.entrySet()) { long nodeTimestamp = System.nanoTime(); Location input = entry.getKey(); @@ -71,12 +73,13 @@ class CargoNetworkTask implements Runnable { attachedBlock.ifPresent(block -> routeItems(input, block, entry.getValue(), outputs)); // This will prevent this timings from showing up for the Cargo Manager - timestamp += SlimefunPlugin.getProfiler().closeEntry(entry.getKey(), SlimefunItems.CARGO_INPUT_NODE.getItem(), nodeTimestamp); + timestamp += SlimefunPlugin.getProfiler().closeEntry(entry.getKey(), inputNode, nodeTimestamp); } // Chest Terminal Code if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) { - network.updateTerminals(chestTerminalInputs); + // This will deduct any CT timings and attribute them towards the actual terminal + timestamp += network.updateTerminals(chestTerminalInputs); } // Submit a timings report diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java index b13b43d67..561cb30bc 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java @@ -409,18 +409,36 @@ final class CargoUtils { } private static boolean matchesFilterList(ItemStack item, BlockMenu menu, boolean respectLore, boolean defaultValue) { - ItemStackWrapper wrapper = null; + // Little performance optimization: + // First check if there is more than one item to compare, if so + // then we know we should create an ItemStackWrapper, otherwise it would + // be of no benefit to us and just be redundant + int itemsToCompare = 0; for (int slot : FILTER_SLOTS) { ItemStack stack = menu.getItemInSlot(slot); - if (stack != null) { - if (wrapper == null) { - // Only create this as needed to save performance - wrapper = new ItemStackWrapper(item); - } + if (stack != null && stack.getType() != Material.AIR) { + itemsToCompare++; - if (SlimefunUtils.isItemSimilar(stack, wrapper, respectLore, false)) { + if (itemsToCompare > 1) { + break; + } + } + } + + // Check if there are event non-air items + if (itemsToCompare > 0) { + // Only create the Wrapper if its worth it + if (itemsToCompare > 1) { + // Create an itemStackWrapper to save performance + item = new ItemStackWrapper(item); + } + + for (int slot : FILTER_SLOTS) { + ItemStack stack = menu.getItemInSlot(slot); + + if (SlimefunUtils.isItemSimilar(stack, item, respectLore, false)) { return !defaultValue; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ChestTerminalNetwork.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ChestTerminalNetwork.java index d7d1a0cfe..1a9fe1077 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ChestTerminalNetwork.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ChestTerminalNetwork.java @@ -274,37 +274,49 @@ abstract class ChestTerminalNetwork extends Network { * * @param providers * A {@link Set} of providers to this {@link ChestTerminalNetwork} + * + * @return The time it took to compute this operation */ - protected void updateTerminals(Set providers) { + protected long updateTerminals(Set providers) { if (terminals.isEmpty()) { // Performance improvement - We don't need to compute items for // Cargo networks without any Chest Terminals - return; + return 0; } - // Timings will be slightly inaccurate here but most often people are gonna - // use no more than one terminal anyway, so this might be fine - long timestamp = SlimefunPlugin.getProfiler().newEntry(); + // Timings will be slightly inaccurate here but most often people are not + // gonna use no more than one terminal anyway, so this might be fine + long timestamp = System.nanoTime(); + Location firstTerminal = null; SlimefunItem item = SlimefunItem.getByID("CHEST_TERMINAL"); List items = findAvailableItems(providers); - for (Location l : terminals) { - BlockMenu terminal = BlockStorage.getInventory(l); - int page = Integer.parseInt(BlockStorage.getLocationInfo(l, "page")); + try { + for (Location l : terminals) { + BlockMenu terminal = BlockStorage.getInventory(l); + int page = Integer.parseInt(BlockStorage.getLocationInfo(l, "page")); - if (!items.isEmpty() && items.size() < (page - 1) * TERMINAL_SLOTS.length + 1) { - page = 1; - BlockStorage.addBlockInfo(l, "page", String.valueOf(1)); + if (!items.isEmpty() && items.size() < (page - 1) * TERMINAL_SLOTS.length + 1) { + page = 1; + BlockStorage.addBlockInfo(l, "page", String.valueOf(1)); + } + + for (int i = 0; i < TERMINAL_SLOTS.length; i++) { + int slot = TERMINAL_SLOTS[i]; + int index = i + (TERMINAL_SLOTS.length * (page - 1)); + updateTerminal(l, terminal, slot, index, items); + } + + if (firstTerminal == null) { + firstTerminal = l; + } } - - for (int i = 0; i < TERMINAL_SLOTS.length; i++) { - int slot = TERMINAL_SLOTS[i]; - int index = i + (TERMINAL_SLOTS.length * (page - 1)); - updateTerminal(l, terminal, slot, index, items); - } - - SlimefunPlugin.getProfiler().closeEntry(l, item, timestamp); } + catch (Exception | LinkageError x) { + item.error("An Exception was caused while trying to tick Chest terminals", x); + } + + return SlimefunPlugin.getProfiler().closeEntry(firstTerminal, item, timestamp); } private void updateTerminal(Location l, BlockMenu terminal, int slot, int index, List items) { @@ -316,7 +328,7 @@ abstract class ChestTerminalNetwork extends Network { ItemMeta im = stack.getItemMeta(); List lore = new ArrayList<>(); lore.add(""); - lore.add(ChatColors.color("&7Stored Items: &r" + DoubleHandler.getFancyDouble(item.getInt()))); + lore.add(ChatColors.color("&7Stored Items: &f" + DoubleHandler.getFancyDouble(item.getInt()))); if (stack.getMaxStackSize() > 1) { int amount = item.getInt() > stack.getMaxStackSize() ? stack.getMaxStackSize() : item.getInt(); @@ -437,7 +449,7 @@ abstract class ChestTerminalNetwork extends Network { boolean add = true; for (ItemStackAndInteger item : items) { - if (SlimefunUtils.isItemSimilar(stack, item.getItemStackWrapper(), true)) { + if (SlimefunUtils.isItemSimilar(stack, item.getItemStackWrapper(), true, false)) { add = false; item.add(stack.getAmount()); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/energy/EnergyNet.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/energy/EnergyNet.java index 0faf773e8..cb450cabc 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/energy/EnergyNet.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/energy/EnergyNet.java @@ -20,11 +20,9 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor; import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.handlers.GeneratorTicker; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.energy.ChargableBlock; @@ -258,48 +256,6 @@ public class EnergyNet extends Network { long time = SlimefunPlugin.getProfiler().closeEntry(source, item, timestamp); timeCallback.accept(time); } - else if (item != null) { - try { - // This will be removed very very soon - // It is only here for temporary backwards compatibility - GeneratorTicker generator = item.getEnergyTicker(); - - Integer capacity = SlimefunPlugin.getRegistry().getEnergyCapacities().get(item.getID()); - - if (capacity != null && capacity.intValue() > 0) { - generatorsWithCapacity.put(source, capacity); - } - - if (generator != null) { - double energy = generator.generateEnergy(source, item, config); - - if (generator.explode(source)) { - exploded.add(source); - BlockStorage.clearBlockInfo(source); - Reactor.processing.remove(source); - Reactor.progress.remove(source); - - Slimefun.runSync(() -> { - source.getBlock().setType(Material.LAVA); - source.getWorld().createExplosion(source, 0F, false); - }); - } - else { - supply += energy; - } - } - else { - item.warn("This Item was marked as a 'GENERATOR' but has no 'GeneratorTicker' attached to it! This must be fixed."); - } - } - catch (Exception | LinkageError t) { - exploded.add(source); - new ErrorReport(t, source, item); - } - - long time = SlimefunPlugin.getProfiler().closeEntry(source, item, timestamp); - timeCallback.accept(time); - } else { // This block seems to be gone now, better remove it to be extra safe exploded.add(source); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java index adc353194..52d108b52 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java @@ -64,7 +64,7 @@ public class AutoSavingService { } if (players > 0) { - Slimefun.getLogger().log(Level.INFO, "Auto-Saved Player Data for {0} Player(s)!", players); + Slimefun.getLogger().log(Level.INFO, "Auto-saved all player data for {0} player(s)!", players); } } @@ -86,12 +86,14 @@ public class AutoSavingService { } if (!worlds.isEmpty()) { - Slimefun.getLogger().log(Level.INFO, "Auto-Saving Block Data... (Next Auto-Save: {0}m)", interval); + Slimefun.getLogger().log(Level.INFO, "Auto-saving block data... (Next auto-save: {0}m)", interval); for (BlockStorage storage : worlds) { - storage.save(false); + storage.save(); } } + + BlockStorage.saveChunks(); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BackupService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BackupService.java index 63630a648..dbe3487ee 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BackupService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BackupService.java @@ -37,7 +37,7 @@ public class BackupService implements Runnable { if (backups.size() > MAX_BACKUPS) { try { - deleteOldBackups(backups); + purgeBackups(backups); } catch (IOException e) { Slimefun.getLogger().log(Level.WARNING, "Could not delete an old backup", e); @@ -112,7 +112,16 @@ public class BackupService implements Runnable { } } - private void deleteOldBackups(List backups) throws IOException { + /** + * This method will delete old backups. + * + * @param backups + * The {@link List} of all backups + * + * @throws IOException + * An {@link IOException} is thrown if a {@link File} could not be deleted + */ + private void purgeBackups(List backups) throws IOException { Collections.sort(backups, (a, b) -> { LocalDateTime time1 = LocalDateTime.parse(a.getName().substring(0, a.getName().length() - 4), format); LocalDateTime time2 = LocalDateTime.parse(b.getName().substring(0, b.getName().length() - 4), format); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java index 42dfbbd6c..da0bf7809 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java @@ -5,11 +5,14 @@ import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.Collection; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.logging.Level; +import org.apache.commons.lang.Validate; import org.bukkit.NamespacedKey; import org.bukkit.Server; import org.bukkit.configuration.file.FileConfiguration; @@ -52,14 +55,17 @@ public class LocalizationService extends SlimefunLocalization implements Persist if (serverDefaultLanguage != null) { translationsEnabled = SlimefunPlugin.getCfg().getBoolean("options.enable-translations"); - + defaultLanguage = new Language(serverDefaultLanguage, "11b3188fd44902f72602bd7c2141f5a70673a411adb3d81862c69e536166b"); defaultLanguage.setMessagesFile(getConfig().getConfiguration()); loadEmbeddedLanguages(); String language = getConfig().getString(LANGUAGE_PATH); - if (language == null) language = serverDefaultLanguage; + + if (language == null) { + language = serverDefaultLanguage; + } if (hasLanguage(serverDefaultLanguage)) { setLanguage(serverDefaultLanguage, !serverDefaultLanguage.equals(language)); @@ -113,7 +119,16 @@ public class LocalizationService extends SlimefunLocalization implements Persist return containsResource("messages_" + language); } + /** + * This returns whether the given {@link Language} is loaded or not. + * + * @param id + * The id of that {@link Language} + * + * @return Whether or not this {@link Language} is loaded + */ public boolean isLanguageLoaded(String id) { + Validate.notNull(id, "The language id cannot be null!"); return languages.containsKey(id); } @@ -170,7 +185,10 @@ public class LocalizationService extends SlimefunLocalization implements Persist } @Override - protected void addLanguage(String id, String hash) { + protected void addLanguage(String id, String texture) { + Validate.notNull(id, "The language id cannot be null!"); + Validate.notNull(texture, "The language texture cannot be null"); + if (hasLanguage(id)) { FileConfiguration messages = streamConfigFile("messages_" + id + ".yml", getConfig().getConfiguration()); FileConfiguration researches = streamConfigFile("researches_" + id + ".yml", null); @@ -178,7 +196,7 @@ public class LocalizationService extends SlimefunLocalization implements Persist FileConfiguration categories = streamConfigFile("categories_" + id + ".yml", null); FileConfiguration recipes = streamConfigFile("recipes_" + id + ".yml", null); - Language language = new Language(id, hash); + Language language = new Language(id, texture); language.setMessagesFile(messages); language.setResearchesFile(researches); language.setResourcesFile(resources); @@ -199,25 +217,36 @@ public class LocalizationService extends SlimefunLocalization implements Persist * * @return A percentage {@code (0.0 - 100.0)} for the progress of translation of that {@link Language} */ - public double getProgress(Language lang) { - int defaultKeys = getTotalKeys(languages.get("en")); - - if (defaultKeys == 0) { + public double calculateProgress(Language lang) { + Validate.notNull(lang, "Cannot get the language progress of null"); + + Set defaultKeys = getTotalKeys(languages.get("en")); + + if (defaultKeys.isEmpty()) { return 0; } - return Math.min(DoubleHandler.fixDouble(100.0 * (getTotalKeys(lang) / (double) defaultKeys)), 100.0); + Set keys = getTotalKeys(lang); + int matches = 0; + + for (String key : defaultKeys) { + if (keys.contains(key)) { + matches++; + } + } + + return Math.min(DoubleHandler.fixDouble(100.0 * (matches / (double) defaultKeys.size())), 100.0); } - private int getTotalKeys(Language lang) { + private Set getTotalKeys(Language lang) { return getKeys(lang.getFiles()); } - private int getKeys(FileConfiguration... files) { - int keys = 0; + private Set getKeys(FileConfiguration... files) { + Set keys = new HashSet<>(); for (FileConfiguration cfg : files) { - keys += cfg != null ? cfg.getKeys(true).size() : 0; + keys.addAll(cfg.getKeys(true)); } return keys; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MetricsService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MetricsService.java index fef03a78a..930cede84 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MetricsService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MetricsService.java @@ -13,6 +13,7 @@ import java.util.logging.Level; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; +import kong.unirest.GetRequest; import kong.unirest.HttpResponse; import kong.unirest.JsonNode; import kong.unirest.Unirest; @@ -31,9 +32,11 @@ import org.bukkit.plugin.Plugin; */ public class MetricsService { + + private static final String API_URL = "https://api.github.com/"; private static final String REPO_NAME = "MetricsModule"; - private static final String GH_API = "https://api.github.com/repos/Slimefun/" + REPO_NAME; - private static final String GH_RELEASES = "https://github.com/Slimefun/" + REPO_NAME + "/releases/download"; + private static final String RELEASES_URL = API_URL + "repos/Slimefun/" + REPO_NAME + "/releases/latest"; + private static final String DOWNLOAD_URL = "https://github.com/Slimefun/" + REPO_NAME + "/releases/download"; private final SlimefunPlugin plugin; private final File parentFolder; @@ -79,38 +82,36 @@ public class MetricsService { try { // Load the jar file into a child class loader using the SF PluginClassLoader // as a parent. - moduleClassLoader = URLClassLoader.newInstance(new URL[] { metricsModuleFile.toURI().toURL() }, - plugin.getClass().getClassLoader()); - Class cl = moduleClassLoader.loadClass("dev.walshy.sfmetrics.MetricsModule"); + moduleClassLoader = URLClassLoader.newInstance(new URL[] { metricsModuleFile.toURI().toURL() }, plugin.getClass().getClassLoader()); + Class metricsClass = moduleClassLoader.loadClass("dev.walshy.sfmetrics.MetricsModule"); - metricVersion = cl.getPackage().getImplementationVersion(); + metricVersion = metricsClass.getPackage().getImplementationVersion(); // If it has not been newly downloaded, auto-updates are on AND there's a new version // then cleanup, download and start - if (!hasDownloadedUpdate && hasAutoUpdates() && checkForUpdate(metricVersion) - ) { - plugin.getLogger().info("Cleaning up and re-loading Metrics."); - cleanUp(); + if (!hasDownloadedUpdate && hasAutoUpdates() && checkForUpdate(metricVersion)) { + plugin.getLogger().info("Cleaned up, now re-loading Metrics-Module!"); start(); return; } // Finally, we're good to start this. - Method start = cl.getDeclaredMethod("start"); - String version = cl.getPackage().getImplementationVersion(); + Method start = metricsClass.getDeclaredMethod("start"); + String version = metricsClass.getPackage().getImplementationVersion(); // This is required to be sync due to bStats. Slimefun.runSync(() -> { try { start.invoke(null); plugin.getLogger().info("Metrics build #" + version + " started."); - } catch (Exception e) { + } + catch (Exception | LinkageError e) { plugin.getLogger().log(Level.WARNING, "Failed to start metrics.", e); } }); - } catch (Exception e) { - plugin.getLogger().log(Level.WARNING, - "Failed to load the metrics module. Maybe the jar is corrupt?", e); + } + catch (Exception | LinkageError e) { + plugin.getLogger().log(Level.WARNING, "Failed to load the metrics module. Maybe the jar is corrupt?", e); } } @@ -120,12 +121,12 @@ public class MetricsService { */ public void cleanUp() { try { - if (this.moduleClassLoader != null) { - this.moduleClassLoader.close(); + if (moduleClassLoader != null) { + moduleClassLoader.close(); } - } catch (IOException e) { - plugin.getLogger().log(Level.WARNING, - "Could not clean up module class loader. Some memory may have been leaked."); + } + catch (IOException e) { + plugin.getLogger().log(Level.WARNING, "Could not clean up module class loader. Some memory may have been leaked."); } } @@ -133,7 +134,8 @@ public class MetricsService { * Checks for a new update and compares it against the current version. * If there is a new version available then this returns true. * - * @param currentVersion The current version which is being used. + * @param currentVersion + * The current version which is being used. * @return True if there is an update available. */ public boolean checkForUpdate(String currentVersion) { @@ -160,17 +162,22 @@ public class MetricsService { */ private int getLatestVersion() { try { - HttpResponse response = Unirest.get(GH_API + "/releases/latest") - .asJson(); - if (!response.isSuccess()) return -1; + HttpResponse response = Unirest.get(RELEASES_URL).asJson(); + + if (!response.isSuccess()) { + return -1; + } JsonNode node = response.getBody(); - if (node == null) return -1; + if (node == null) { + return -1; + } return node.getObject().getInt("tag_name"); - } catch (UnirestException e) { - plugin.getLogger().log(Level.SEVERE, "Failed to fetch latest builds for SFMetrics"); + } + catch (UnirestException e) { + plugin.getLogger().log(Level.WARNING, "Failed to fetch latest builds for Metrics: {0}", e.getMessage()); return -1; } } @@ -178,49 +185,56 @@ public class MetricsService { /** * Downloads the version specified to Slimefun's data folder. * - * @param version The version to download. + * @param version + * The version to download. */ private boolean download(int version) { - File f = new File(parentFolder, "Metrics-" + version + ".jar"); + File file = new File(parentFolder, "Metrics-" + version + ".jar"); try { plugin.getLogger().log(Level.INFO, "# Starting download of MetricsModule build: #{0}", version); + if (file.exists()) { + // Delete the file in case we accidentally downloaded it before + Files.delete(file.toPath()); + } + AtomicInteger lastPercentPosted = new AtomicInteger(); - HttpResponse response = Unirest.get(GH_RELEASES + "/" + version - + "/" + REPO_NAME + ".jar") - .downloadMonitor((b, fileName, bytesWritten, totalBytes) -> { - int percent = (int) (20 * (Math.round((((double) bytesWritten / totalBytes) * 100) / 20))); + GetRequest request = Unirest.get(DOWNLOAD_URL + "/" + version + "/" + REPO_NAME + ".jar"); + + HttpResponse response = request.downloadMonitor((b, fileName, bytesWritten, totalBytes) -> { + int percent = (int) (20 * (Math.round((((double) bytesWritten / totalBytes) * 100) / 20))); + + if (percent != 0 && percent != lastPercentPosted.get()) { + plugin.getLogger().info("# Downloading... " + percent + "% " + "(" + bytesWritten + "/" + totalBytes + " bytes)"); + lastPercentPosted.set(percent); + } + }).asFile(file.getPath()); - if (percent != 0 && percent != lastPercentPosted.get()) { - plugin.getLogger().info("# Downloading... " + percent + "% " + - "(" + bytesWritten + "/" + totalBytes + " bytes)"); - lastPercentPosted.set(percent); - } - }) - .asFile(f.getPath()); if (response.isSuccess()) { - plugin.getLogger().log(Level.INFO, "Successfully downloaded {0} build: #{1}", new Object[] {REPO_NAME, version}); + plugin.getLogger().log(Level.INFO, "Successfully downloaded {0} build: #{1}", new Object[] { REPO_NAME, version }); // Replace the metric file with the new one - Files.move(f.toPath(), metricsModuleFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + cleanUp(); + Files.move(file.toPath(), metricsModuleFile.toPath(), StandardCopyOption.REPLACE_EXISTING); metricVersion = String.valueOf(version); hasDownloadedUpdate = true; return true; } - } catch (UnirestException e) { - plugin.getLogger().log(Level.WARNING, "Failed to fetch the latest jar file from the" + - " builds page. Perhaps GitHub is down."); - } catch (IOException e) { - plugin.getLogger().log(Level.WARNING, "Failed to replace the old metric file with the " + - "new one. Please do this manually! Error: {0}", e.getMessage()); } + catch (UnirestException e) { + plugin.getLogger().log(Level.WARNING, "Failed to fetch the latest jar file from the builds page. Perhaps GitHub is down?"); + } + catch (IOException e) { + plugin.getLogger().log(Level.WARNING, "Failed to replace the old metric file with the new one. Please do this manually! Error: {0}", e.getMessage()); + } + return false; } /** - * Returns the currently downloaded metrics version. + * Returns the currently downloaded metrics version. * This can change! It may be null or an * older version before it has downloaded a newer one. * diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Contributor.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Contributor.java index 9c1be58d5..7f87b6e2b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Contributor.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Contributor.java @@ -133,8 +133,15 @@ public class Contributor { */ public String getTexture() { if (!headTexture.isComputed() || !headTexture.isPresent()) { - String cached = SlimefunPlugin.getGitHubService().getCachedTexture(githubUsername); - return cached != null ? cached : HeadTexture.UNKNOWN.getTexture(); + GitHubService github = SlimefunPlugin.getGitHubService(); + + if (github != null) { + String cached = github.getCachedTexture(githubUsername); + return cached != null ? cached : HeadTexture.UNKNOWN.getTexture(); + } + else { + return HeadTexture.UNKNOWN.getTexture(); + } } else { return headTexture.get(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java index 1ab1b4149..922355172 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java @@ -17,6 +17,8 @@ import kong.unirest.json.JSONException; import me.mrCookieSlime.Slimefun.api.Slimefun; abstract class GitHubConnector { + + private static final String API_URL = "https://api.github.com/"; protected File file; protected String repository; @@ -45,7 +47,7 @@ abstract class GitHubConnector { } try { - HttpResponse resp = Unirest.get("https://api.github.com/repos/" + repository + getURLSuffix()) + HttpResponse resp = Unirest.get(API_URL + "repos/" + repository + getURLSuffix()) .header("User-Agent", "Slimefun4 (https://github.com/Slimefun)") .asJson(); @@ -54,7 +56,18 @@ abstract class GitHubConnector { writeCacheFile(resp.getBody()); } else { - Slimefun.getLogger().log(Level.WARNING, "Failed to fetch {0}", repository + getURLSuffix()); + if (github.isLoggingEnabled()) { + Slimefun.getLogger().log(Level.WARNING, "Failed to fetch {0}: {1} - {2}", new Object[] {repository + getURLSuffix(), resp.getStatus(), resp.getBody()}); + } + + // It has the cached file, let's just read that then + if (file.exists()) { + JsonNode cache = readCacheFile(); + + if (cache != null) { + onSuccess(cache); + } + } } } catch (UnirestException e) { @@ -78,21 +91,21 @@ abstract class GitHubConnector { } private JsonNode readCacheFile() { - try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) { - return new JsonNode(br.readLine()); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) { + return new JsonNode(reader.readLine()); } catch (IOException | JSONException e) { - Slimefun.getLogger().log(Level.WARNING, "Failed to read Github cache file: {0}", file.getName()); + Slimefun.getLogger().log(Level.WARNING, "Failed to read Github cache file: {0} - {1}: {2}", new Object[] {file.getName(), e.getClass().getSimpleName(), e.getMessage()}); return null; } } private void writeCacheFile(JsonNode node) { - try (FileOutputStream fos = new FileOutputStream(file)) { - fos.write(node.toString().getBytes(StandardCharsets.UTF_8)); + try (FileOutputStream output = new FileOutputStream(file)) { + output.write(node.toString().getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { - Slimefun.getLogger().log(Level.WARNING, "Failed to populate GitHub cache"); + Slimefun.getLogger().log(Level.WARNING, "Failed to populate GitHub cache: {0} - {1}", new Object[] {e.getClass().getSimpleName(), e.getMessage()}); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Language.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Language.java index 0a7ecaa8b..a37bb397b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Language.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Language.java @@ -25,6 +25,7 @@ public final class Language { private final String id; private final ItemStack item; + private double progress = -1; private FileConfiguration messages; private FileConfiguration researches; @@ -60,6 +61,26 @@ public final class Language { return id; } + /** + * This method returns the progress of translation for this {@link Language}. + * The progress is determined by the amount of translated strings divided by the amount + * of strings in the english {@link Language} file and multiplied by 100.0 + * + * @return A percentage {@code (0.0 - 100.0)} for the progress of translation of this {@link Language} + */ + public double getTranslationProgress() { + if (id.equals("en")) { + return 100.0; + } + else { + if (progress < 0) { + progress = SlimefunPlugin.getLocalization().calculateProgress(this); + } + + return progress; + } + } + FileConfiguration getMessagesFile() { return messages; } @@ -145,7 +166,7 @@ public final class Language { @Override public String toString() { - return "Language [ id= " + id + " | default=" + isDefault() + " ]"; + return "Language {id= " + id + ", default=" + isDefault() + " }"; } public FileConfiguration[] getFiles() { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SlimefunLocalization.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SlimefunLocalization.java index e287a2de0..4a09fc340 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SlimefunLocalization.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SlimefunLocalization.java @@ -87,25 +87,62 @@ public abstract class SlimefunLocalization extends Localization implements Keyed public String getMessage(Player p, String key) { Language language = getLanguage(p); - if (language == null) return "NO LANGUAGE FOUND"; - return language.getMessagesFile().getString(key); + + if (language == null) { + return "NO LANGUAGE FOUND"; + } + + String message = language.getMessagesFile().getString(key); + + if (message == null) { + Language fallback = getLanguage(SupportedLanguage.ENGLISH.getLanguageId()); + return fallback.getMessagesFile().getString(key); + } + + return message; } public List getMessages(Player p, String key) { Language language = getLanguage(p); - if (language == null) return Arrays.asList("NO LANGUAGE FOUND"); - return language.getMessagesFile().getStringList(key); + + if (language == null) { + return Arrays.asList("NO LANGUAGE FOUND"); + } + + List messages = language.getMessagesFile().getStringList(key); + + if (messages.isEmpty()) { + Language fallback = getLanguage(SupportedLanguage.ENGLISH.getLanguageId()); + return fallback.getMessagesFile().getStringList(key); + } + + return messages; + } + + public List getMessages(Player p, String key, UnaryOperator function) { + List messages = getMessages(p, key); + messages.replaceAll(function); + + return messages; } public String getResearchName(Player p, NamespacedKey key) { Language language = getLanguage(p); - if (language.getResearchesFile() == null) return null; + + if (language.getResearchesFile() == null) { + return null; + } + return language.getResearchesFile().getString(key.getNamespace() + "." + key.getKey()); } public String getCategoryName(Player p, NamespacedKey key) { Language language = getLanguage(p); - if (language.getCategoriesFile() == null) return null; + + if (language.getCategoriesFile() == null) { + return null; + } + return language.getCategoriesFile().getString(key.getNamespace() + "." + key.getKey()); } @@ -118,7 +155,8 @@ public abstract class SlimefunLocalization extends Localization implements Keyed return value; } else { - return getLanguage("en").getResourcesFile().getString(key); + Language fallback = getLanguage(SupportedLanguage.ENGLISH.getLanguageId()); + return fallback.getResourcesFile().getString(key); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SupportedLanguage.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SupportedLanguage.java index b7231eaa1..8630567ec 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SupportedLanguage.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SupportedLanguage.java @@ -43,7 +43,7 @@ enum SupportedLanguage { CHINESE_CHINA("zh-CN", true, "7f9bc035cdc80f1ab5e1198f29f3ad3fdd2b42d9a69aeb64de990681800b98dc"), CHINESE_TAIWAN("zh-TW", true, "702a4afb2e1e2e3a1894a8b74272f95cfa994ce53907f9ac140bd3c932f9f"), JAPANESE("ja", true, "d640ae466162a47d3ee33c4076df1cab96f11860f07edb1f0832c525a9e33323"), - KOREAN("ko", false, "fc1be5f12f45e413eda56f3de94e08d90ede8e339c7b1e8f32797390e9a5f"), + KOREAN("ko", true, "fc1be5f12f45e413eda56f3de94e08d90ede8e339c7b1e8f32797390e9a5f"), HEBREW("he", false, "1ba086a2cc7272cf5ba49c80248546c22e5ef1bab54120e8a8e5d9e75b6a"), ARABIC("ar", true, "a4be759a9cf7f0a19a7e8e62f23789ad1d21cebae38af9d9541676a3db001572"), TURKISH("tr", true, "9852b9aba3482348514c1034d0affe73545c9de679ae4647f99562b5e5f47d09"), diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Translators.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Translators.java index 088856ec1..27006d207 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Translators.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Translators.java @@ -38,6 +38,7 @@ public class Translators { addTranslator("ThatsCube", SupportedLanguage.ITALIAN, true); addTranslator("alessandrobasi", SupportedLanguage.ITALIAN, true); addTranslator("dracrus", SupportedLanguage.ITALIAN, true); + addTranslator("prolletto64", SupportedLanguage.ITALIAN, true); // Translators - Latvian addTranslator("AgnisT", "NIKNAIZ", SupportedLanguage.LATVIAN, true); @@ -127,6 +128,7 @@ public class Translators { addTranslator("yumjunstar", SupportedLanguage.KOREAN, true); addTranslator("BlWon", SupportedLanguage.KOREAN, true); addTranslator("20181241", SupportedLanguage.KOREAN, true); + addTranslator("kudansul", SupportedLanguage.KOREAN, true); // Translators - Indonesian addTranslator("diradho", SupportedLanguage.INDONESIAN, false); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/PlaceholderAPIHook.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/PlaceholderAPIHook.java index 457068e97..425fd9e8a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/PlaceholderAPIHook.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/PlaceholderAPIHook.java @@ -14,9 +14,12 @@ import me.clip.placeholderapi.expansion.PlaceholderExpansion; class PlaceholderAPIHook extends PlaceholderExpansion { - @Override - public String getAuthor() { - return SlimefunPlugin.instance().getDescription().getAuthors().toString(); + private final String version; + private final String author; + + public PlaceholderAPIHook(SlimefunPlugin plugin) { + this.version = plugin.getDescription().getVersion(); + this.author = plugin.getDescription().getAuthors().toString(); } @Override @@ -26,7 +29,12 @@ class PlaceholderAPIHook extends PlaceholderExpansion { @Override public String getVersion() { - return SlimefunPlugin.instance().getDescription().getVersion(); + return version; + } + + @Override + public String getAuthor() { + return author; } @Override diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ThirdPartyPluginService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ThirdPartyPluginService.java index 47d881cef..65c285540 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ThirdPartyPluginService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ThirdPartyPluginService.java @@ -44,8 +44,17 @@ public class ThirdPartyPluginService { public void start() { if (isPluginInstalled("PlaceholderAPI")) { - isPlaceholderAPIInstalled = true; - new PlaceholderAPIHook().register(); + try { + PlaceholderAPIHook hook = new PlaceholderAPIHook(plugin); + hook.register(); + isPlaceholderAPIInstalled = true; + } + catch (Exception | LinkageError x) { + String version = plugin.getServer().getPluginManager().getPlugin("PlaceholderAPI").getDescription().getVersion(); + + Slimefun.getLogger().log(Level.WARNING, "Maybe consider updating PlaceholderAPI or Slimefun?"); + Slimefun.getLogger().log(Level.WARNING, x, () -> "Failed to hook into PlaceholderAPI v" + version); + } } if (isPluginInstalled("EmeraldEnchants")) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java index fad49ad33..98b012e59 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java @@ -44,7 +44,7 @@ public class SlimefunProfiler { // two ticks (sync and async blocks), so we use 100ms as a reference here private static final int MAX_TICK_DURATION = 100; - private final ExecutorService executor = Executors.newFixedThreadPool(4); + private final ExecutorService executor = Executors.newFixedThreadPool(5); private final AtomicBoolean running = new AtomicBoolean(false); private final AtomicInteger queued = new AtomicInteger(0); @@ -118,7 +118,8 @@ public class SlimefunProfiler { executor.execute(() -> { ProfiledBlock block = new ProfiledBlock(l, item); - timings.putIfAbsent(block, elapsedTime); + // Merge (if we have multiple samples for whatever reason) + timings.merge(block, elapsedTime, Long::sum); queued.decrementAndGet(); }); @@ -143,7 +144,7 @@ public class SlimefunProfiler { private void finishReport() { // We will only wait for a maximum of this many 1ms sleeps - int iterations = 1000; + int iterations = 4000; // Wait for all timing results to come in while (!running.get() && queued.get() > 0) { @@ -153,6 +154,12 @@ public class SlimefunProfiler { // If we waited for too long, then we should just abort if (iterations <= 0) { + Iterator iterator = requests.iterator(); + + while (iterator.hasNext()) { + iterator.next().sendMessage("Your timings report has timed out, we were still waiting for " + queued.get() + " samples to be collected :/"); + iterator.remove(); + } return; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java index e384a3767..24a591203 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java @@ -145,11 +145,11 @@ public final class SlimefunItems { public static final SlimefunItemStack DIET_COOKIE = new SlimefunItemStack("DIET_COOKIE", Material.COOKIE, "&6Diet Cookie", "", "&aA very &olightweight &f&acookie."); public static final SlimefunItemStack MAGIC_SUGAR = new SlimefunItemStack("MAGIC_SUGAR", Material.SUGAR, "&6Magic Sugar", "", "&a&oFeel the Power of Hermes!"); public static final SlimefunItemStack MONSTER_JERKY = new SlimefunItemStack("MONSTER_JERKY", Material.ROTTEN_FLESH, "&6Monster Jerky", "", "&a&oNo longer hungry"); - public static final SlimefunItemStack APPLE_JUICE = new SlimefunItemStack("APPLE_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 6, 0), "&cApple Juice", "", "&7&oRestores &b&o" + "3.0" + " &7&oHunger"); - public static final SlimefunItemStack MELON_JUICE = new SlimefunItemStack("MELON_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 6, 0), "&cMelon Juice", "", "&7&oRestores &b&o" + "3.0" + " &7&oHunger"); - public static final SlimefunItemStack CARROT_JUICE = new SlimefunItemStack("CARROT_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 6, 0), "&6Carrot Juice", "", "&7&oRestores &b&o" + "3.0" + " &7&oHunger"); - public static final SlimefunItemStack PUMPKIN_JUICE = new SlimefunItemStack("PUMPKIN_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 6, 0), "&6Pumpkin Juice", "", "&7&oRestores &b&o" + "3.0" + " &7&oHunger"); - public static final SlimefunItemStack SWEET_BERRY_JUICE = new SlimefunItemStack("SWEET_BERRY_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 6, 0), "&cSweet Berry Juice", "", "&7&oRestores &b&o" + "3.0" + " &7&oHunger"); + public static final SlimefunItemStack APPLE_JUICE = new SlimefunItemStack("APPLE_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&cApple Juice", "", LoreBuilder.hunger(3)); + public static final SlimefunItemStack MELON_JUICE = new SlimefunItemStack("MELON_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&cMelon Juice", "", LoreBuilder.hunger(3)); + public static final SlimefunItemStack CARROT_JUICE = new SlimefunItemStack("CARROT_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Carrot Juice", "", LoreBuilder.hunger(3)); + public static final SlimefunItemStack PUMPKIN_JUICE = new SlimefunItemStack("PUMPKIN_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Pumpkin Juice", "", LoreBuilder.hunger(3)); + public static final SlimefunItemStack SWEET_BERRY_JUICE = new SlimefunItemStack("SWEET_BERRY_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&cSweet Berry Juice", "", LoreBuilder.hunger(3)); public static final SlimefunItemStack GOLDEN_APPLE_JUICE = new SlimefunItemStack("GOLDEN_APPLE_JUICE", Color.YELLOW, new PotionEffect(PotionEffectType.ABSORPTION, 20 * 20, 0), "&bGolden Apple Juice"); public static final SlimefunItemStack BEEF_JERKY = new SlimefunItemStack("BEEF_JERKY", Material.COOKED_BEEF, "&6Beef Jerky", "", "&fExtra saturating!"); @@ -162,14 +162,14 @@ public final class SlimefunItems { public static final SlimefunItemStack KELP_COOKIE = new SlimefunItemStack("KELP_COOKIE", Material.COOKIE, "&2Kelp Cookie"); /* Christmas */ - public static final SlimefunItemStack CHRISTMAS_MILK = new SlimefunItemStack("CHRISTMAS_MILK", Color.WHITE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Glass of Milk", "", "&7&oRestores &b&o" + "2.5" + " &7&oHunger"); - public static final SlimefunItemStack CHRISTMAS_CHOCOLATE_MILK = new SlimefunItemStack("CHRISTMAS_CHOCOLATE_MILK", Color.MAROON, new PotionEffect(PotionEffectType.SATURATION, 12, 0), "&6Chocolate Milk", "", "&7&oRestores &b&o" + "6.0" + " &7&oHunger"); - public static final SlimefunItemStack CHRISTMAS_EGG_NOG = new SlimefunItemStack("CHRISTMAS_EGG_NOG", Color.GRAY, new PotionEffect(PotionEffectType.SATURATION, 7, 0), "&aEgg Nog", "", "&7&oRestores &b&o" + "3.5" + " &7&oHunger"); - public static final SlimefunItemStack CHRISTMAS_APPLE_CIDER = new SlimefunItemStack("CHRISTMAS_APPLE_CIDER", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 14, 0), "&cApple Cider", "", "&7&oRestores &b&o" + "7.0" + " &7&oHunger"); + public static final SlimefunItemStack CHRISTMAS_MILK = new SlimefunItemStack("CHRISTMAS_MILK", Color.WHITE, new PotionEffect(PotionEffectType.SATURATION, 4, 0), "&6Glass of Milk", "", LoreBuilder.hunger(2.5)); + public static final SlimefunItemStack CHRISTMAS_CHOCOLATE_MILK = new SlimefunItemStack("CHRISTMAS_CHOCOLATE_MILK", Color.MAROON, new PotionEffect(PotionEffectType.SATURATION, 11, 0), "&6Chocolate Milk", "", LoreBuilder.hunger(6)); + public static final SlimefunItemStack CHRISTMAS_EGG_NOG = new SlimefunItemStack("CHRISTMAS_EGG_NOG", Color.GRAY, new PotionEffect(PotionEffectType.SATURATION, 6, 0), "&aEgg Nog", "", LoreBuilder.hunger(3.5)); + public static final SlimefunItemStack CHRISTMAS_APPLE_CIDER = new SlimefunItemStack("CHRISTMAS_APPLE_CIDER", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 13, 0), "&cApple Cider", "", LoreBuilder.hunger(7)); public static final SlimefunItemStack CHRISTMAS_COOKIE = new SlimefunItemStack("CHRISTMAS_COOKIE", Material.COOKIE, ChatUtils.christmas("Christmas Cookie")); public static final SlimefunItemStack CHRISTMAS_FRUIT_CAKE = new SlimefunItemStack("CHRISTMAS_FRUIT_CAKE", Material.PUMPKIN_PIE, ChatUtils.christmas("Fruit Cake")); public static final SlimefunItemStack CHRISTMAS_APPLE_PIE = new SlimefunItemStack("CHRISTMAS_APPLE_PIE", Material.PUMPKIN_PIE, "&fApple Pie"); - public static final SlimefunItemStack CHRISTMAS_HOT_CHOCOLATE = new SlimefunItemStack("CHRISTMAS_HOT_CHOCOLATE", Color.MAROON, new PotionEffect(PotionEffectType.SATURATION, 14, 0), "&6Hot Chocolate", "", "&7&oRestores &b&o" + "7.0" + " &7&oHunger"); + public static final SlimefunItemStack CHRISTMAS_HOT_CHOCOLATE = new SlimefunItemStack("CHRISTMAS_HOT_CHOCOLATE", Color.MAROON, new PotionEffect(PotionEffectType.SATURATION, 13, 0), "&6Hot Chocolate", "", LoreBuilder.hunger(7)); public static final SlimefunItemStack CHRISTMAS_CAKE = new SlimefunItemStack("CHRISTMAS_CAKE", Material.PUMPKIN_PIE, ChatUtils.christmas("Christmas Cake")); public static final SlimefunItemStack CHRISTMAS_CARAMEL = new SlimefunItemStack("CHRISTMAS_CARAMEL", Material.BRICK, "&6Caramel"); public static final SlimefunItemStack CHRISTMAS_CARAMEL_APPLE = new SlimefunItemStack("CHRISTMAS_CARAMEL_APPLE", Material.APPLE, "&6Caramel Apple"); @@ -256,7 +256,7 @@ public final class SlimefunItems { static { hazmatLore.add(""); hazmatLore.add(ChatColor.GOLD + "Full set effects:"); - hazmatLore.add(ChatColor.YELLOW + "- Radioation immunity"); + hazmatLore.add(ChatColor.YELLOW + "- Radiation immunity"); if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_15)) { hazmatLore.add(ChatColor.YELLOW + "- Bee Sting protection"); @@ -287,10 +287,10 @@ public final class SlimefunItems { public static final SlimefunItemStack GILDED_IRON_LEGGINGS = new SlimefunItemStack("GILDED_IRON_LEGGINGS", Material.GOLDEN_LEGGINGS, "&6Gilded Iron Leggings"); public static final SlimefunItemStack GILDED_IRON_BOOTS = new SlimefunItemStack("GILDED_IRON_BOOTS", Material.GOLDEN_BOOTS, "&6Gilded Iron Boots"); - public static final SlimefunItemStack GOLD_HELMET = new SlimefunItemStack("GOLD_12K_HELMET", Material.GOLDEN_HELMET, "&6Gold Helmet", "&912-Carat"); - public static final SlimefunItemStack GOLD_CHESTPLATE = new SlimefunItemStack("GOLD_12K_CHESTPLATE", Material.GOLDEN_CHESTPLATE, "&6Gold Chestplate", "&912-Carat"); - public static final SlimefunItemStack GOLD_LEGGINGS = new SlimefunItemStack("GOLD_12K_LEGGINGS", Material.GOLDEN_LEGGINGS, "&6Gold Leggings", "&912-Carat"); - public static final SlimefunItemStack GOLD_BOOTS = new SlimefunItemStack("GOLD_12K_BOOTS", Material.GOLDEN_BOOTS, "&6Gold Boots", "&912-Carat"); + public static final SlimefunItemStack GOLDEN_HELMET_12K = new SlimefunItemStack("GOLD_12K_HELMET", Material.GOLDEN_HELMET, "&6Golden Helmet &7(12-Carat)"); + public static final SlimefunItemStack GOLDEN_CHESTPLATE_12K = new SlimefunItemStack("GOLD_12K_CHESTPLATE", Material.GOLDEN_CHESTPLATE, "&6Golden Chestplate &7(12-Carat)"); + public static final SlimefunItemStack GOLDEN_LEGGINGS_12K = new SlimefunItemStack("GOLD_12K_LEGGINGS", Material.GOLDEN_LEGGINGS, "&6Golden Leggings &7(12-Carat)"); + public static final SlimefunItemStack GOLDEN_BOOTS_12K = new SlimefunItemStack("GOLD_12K_BOOTS", Material.GOLDEN_BOOTS, "&6Golden Boots &7(12-Carat)"); public static final SlimefunItemStack SLIME_HELMET_STEEL = new SlimefunItemStack("SLIME_STEEL_HELMET", Material.IRON_HELMET, "&a&lSlime Helmet", "&7&oReinforced", "", "&a&oBouncy Feeling"); public static final SlimefunItemStack SLIME_CHESTPLATE_STEEL = new SlimefunItemStack("SLIME_STEEL_CHESTPLATE", Material.IRON_CHESTPLATE, "&a&lSlime Chestplate", "&7&oReinforced", "", "&a&oBouncy Feeling"); @@ -336,10 +336,10 @@ public final class SlimefunItems { GILDED_IRON_LEGGINGS.addUnsafeEnchantments(gilded); GILDED_IRON_BOOTS.addUnsafeEnchantments(gilded); - GOLD_HELMET.addUnsafeEnchantment(Enchantment.DURABILITY, 10); - GOLD_CHESTPLATE.addUnsafeEnchantment(Enchantment.DURABILITY, 10); - GOLD_LEGGINGS.addUnsafeEnchantment(Enchantment.DURABILITY, 10); - GOLD_BOOTS.addUnsafeEnchantment(Enchantment.DURABILITY, 10); + GOLDEN_HELMET_12K.addUnsafeEnchantment(Enchantment.DURABILITY, 10); + GOLDEN_CHESTPLATE_12K.addUnsafeEnchantment(Enchantment.DURABILITY, 10); + GOLDEN_LEGGINGS_12K.addUnsafeEnchantment(Enchantment.DURABILITY, 10); + GOLDEN_BOOTS_12K.addUnsafeEnchantment(Enchantment.DURABILITY, 10); Map slime = new HashMap<>(); slime.put(Enchantment.DURABILITY, 4); @@ -409,12 +409,13 @@ public final class SlimefunItems { public static final SlimefunItemStack ANCIENT_ALTAR = new SlimefunItemStack("ANCIENT_ALTAR", Material.ENCHANTING_TABLE, "&dAncient Altar", "", "&5Multi-Block Altar for", "&5magical Crafting Processes"); public static final SlimefunItemStack COPPER_WIRE = new SlimefunItemStack("COPPER_WIRE", Material.STRING, "&6Copper Wire", "", "&6Crucial component in electric modules"); - public static final SlimefunItemStack RAINBOW_WOOL = new SlimefunItemStack("RAINBOW_WOOL", Material.WHITE_WOOL, "&5Rainbow Wool", "", "&dCycles through all Colors of the Rainbow!"); - public static final SlimefunItemStack RAINBOW_GLASS = new SlimefunItemStack("RAINBOW_GLASS", Material.WHITE_STAINED_GLASS, "&5Rainbow Glass", "", "&dCycles through all Colors of the Rainbow!"); - public static final SlimefunItemStack RAINBOW_CLAY = new SlimefunItemStack("RAINBOW_CLAY", Material.WHITE_TERRACOTTA, "&5Rainbow Clay", "", "&dCycles through all Colors of the Rainbow!"); - public static final SlimefunItemStack RAINBOW_GLASS_PANE = new SlimefunItemStack("RAINBOW_GLASS_PANE", Material.WHITE_STAINED_GLASS_PANE, "&5Rainbow Glass Pane", "", "&dCycles through all Colors of the Rainbow!"); - public static final SlimefunItemStack RAINBOW_CONCRETE = new SlimefunItemStack("RAINBOW_CONCRETE", Material.WHITE_CONCRETE, "&5Rainbow Concrete", "", "&dCycles through all Colors of the Rainbow!"); - public static final SlimefunItemStack RAINBOW_GLAZED_TERRACOTTA = new SlimefunItemStack("RAINBOW_GLAZED_TERRACOTTA", Material.WHITE_GLAZED_TERRACOTTA, "&5Rainbow Glazed Terracotta", "", "&dCycles through all Colors of the Rainbow!"); + private static final String RAINBOW = "&dCycles through all Colors of the Rainbow!"; + public static final SlimefunItemStack RAINBOW_WOOL = new SlimefunItemStack("RAINBOW_WOOL", Material.WHITE_WOOL, "&5Rainbow Wool", "", RAINBOW); + public static final SlimefunItemStack RAINBOW_GLASS = new SlimefunItemStack("RAINBOW_GLASS", Material.WHITE_STAINED_GLASS, "&5Rainbow Glass", "", RAINBOW); + public static final SlimefunItemStack RAINBOW_CLAY = new SlimefunItemStack("RAINBOW_CLAY", Material.WHITE_TERRACOTTA, "&5Rainbow Clay", "", RAINBOW); + public static final SlimefunItemStack RAINBOW_GLASS_PANE = new SlimefunItemStack("RAINBOW_GLASS_PANE", Material.WHITE_STAINED_GLASS_PANE, "&5Rainbow Glass Pane", "", RAINBOW); + public static final SlimefunItemStack RAINBOW_CONCRETE = new SlimefunItemStack("RAINBOW_CONCRETE", Material.WHITE_CONCRETE, "&5Rainbow Concrete", "", RAINBOW); + public static final SlimefunItemStack RAINBOW_GLAZED_TERRACOTTA = new SlimefunItemStack("RAINBOW_GLAZED_TERRACOTTA", Material.WHITE_GLAZED_TERRACOTTA, "&5Rainbow Glazed Terracotta", "", RAINBOW); /* Seasonal */ private static final String CHRISTMAS = ChatUtils.christmas("[Christmas Edition]"); @@ -758,28 +759,28 @@ public final class SlimefunItems { public static final SlimefunItemStack AUTO_BREEDER = new SlimefunItemStack("AUTO_BREEDER", Material.HAY_BLOCK, "&eAuto-Breeder", "", "&fRuns on &aOrganic Food", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), LoreBuilder.powerBuffer(1024), "&8\u21E8 &e\u26A1 &760 J/Animal"); public static final SlimefunItemStack ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD", HeadTexture.FILLED_CAN, "&aOrganic Food", "&7Content: &9???"); - public static final SlimefunItemStack WHEAT_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_WHEAT", HeadTexture.FILLED_CAN, "&aOrganic Food", "&7Content: &9Wheat"); - public static final SlimefunItemStack CARROT_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_CARROT", HeadTexture.FILLED_CAN, "&aOrganic Food", "&7Content: &9Carrots"); - public static final SlimefunItemStack POTATO_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_POTATO", HeadTexture.FILLED_CAN, "&aOrganic Food", "&7Content: &9Potatoes"); - public static final SlimefunItemStack SEEDS_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_SEEDS", HeadTexture.FILLED_CAN, "&aOrganic Food", "&7Content: &9Seeds"); - public static final SlimefunItemStack BEETROOT_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_BEETROOT", HeadTexture.FILLED_CAN, "&aOrganic Food", "&7Content: &9Beetroot"); - public static final SlimefunItemStack MELON_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_MELON", HeadTexture.FILLED_CAN, "&aOrganic Food", "&7Content: &9Melon"); - public static final SlimefunItemStack APPLE_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_APPLE", HeadTexture.FILLED_CAN, "&aOrganic Food", "&7Content: &9Apple"); - public static final SlimefunItemStack SWEET_BERRIES_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_SWEET_BERRIES", HeadTexture.FILLED_CAN, "&aOrganic Food", "&7Content: &9Sweet Berries"); - public static final SlimefunItemStack KELP_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_KELP", HeadTexture.FILLED_CAN, "&aOrganic Food", "&7Content: &9Dried Kelp"); - public static final SlimefunItemStack COCOA_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_COCOA", HeadTexture.FILLED_CAN, "&aOrganic Food", "&7Content: &9Cocoa Beans"); + public static final SlimefunItemStack WHEAT_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_WHEAT", HeadTexture.FILLED_CAN, ORGANIC_FOOD.getDisplayName(), "&7Content: &9Wheat"); + public static final SlimefunItemStack CARROT_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_CARROT", HeadTexture.FILLED_CAN, ORGANIC_FOOD.getDisplayName(), "&7Content: &9Carrots"); + public static final SlimefunItemStack POTATO_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_POTATO", HeadTexture.FILLED_CAN, ORGANIC_FOOD.getDisplayName(), "&7Content: &9Potatoes"); + public static final SlimefunItemStack SEEDS_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_SEEDS", HeadTexture.FILLED_CAN, ORGANIC_FOOD.getDisplayName(), "&7Content: &9Seeds"); + public static final SlimefunItemStack BEETROOT_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_BEETROOT", HeadTexture.FILLED_CAN, ORGANIC_FOOD.getDisplayName(), "&7Content: &9Beetroot"); + public static final SlimefunItemStack MELON_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_MELON", HeadTexture.FILLED_CAN, ORGANIC_FOOD.getDisplayName(), "&7Content: &9Melon"); + public static final SlimefunItemStack APPLE_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_APPLE", HeadTexture.FILLED_CAN, ORGANIC_FOOD.getDisplayName(), "&7Content: &9Apple"); + public static final SlimefunItemStack SWEET_BERRIES_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_SWEET_BERRIES", HeadTexture.FILLED_CAN, ORGANIC_FOOD.getDisplayName(), "&7Content: &9Sweet Berries"); + public static final SlimefunItemStack KELP_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_KELP", HeadTexture.FILLED_CAN, ORGANIC_FOOD.getDisplayName(), "&7Content: &9Dried Kelp"); + public static final SlimefunItemStack COCOA_ORGANIC_FOOD = new SlimefunItemStack("ORGANIC_FOOD_COCOA", HeadTexture.FILLED_CAN, ORGANIC_FOOD.getDisplayName(), "&7Content: &9Cocoa Beans"); public static final SlimefunItemStack FERTILIZER = new SlimefunItemStack("FERTILIZER", HeadTexture.FILLED_CAN, "&aOrganic Fertilizer", "&7Content: &9???"); - public static final SlimefunItemStack WHEAT_FERTILIZER = new SlimefunItemStack("FERTILIZER_WHEAT", HeadTexture.FILLED_CAN, "&aOrganic Fertilizer", "&7Content: &9Wheat"); - public static final SlimefunItemStack CARROT_FERTILIZER = new SlimefunItemStack("FERTILIZER_CARROT", HeadTexture.FILLED_CAN, "&aOrganic Fertilizer", "&7Content: &9Carrots"); - public static final SlimefunItemStack POTATO_FERTILIZER = new SlimefunItemStack("FERTILIZER_POTATO", HeadTexture.FILLED_CAN, "&aOrganic Fertilizer", "&7Content: &9Potatoes"); - public static final SlimefunItemStack SEEDS_FERTILIZER = new SlimefunItemStack("FERTILIZER_SEEDS", HeadTexture.FILLED_CAN, "&aOrganic Fertilizer", "&7Content: &9Seeds"); - public static final SlimefunItemStack BEETROOT_FERTILIZER = new SlimefunItemStack("FERTILIZER_BEETROOT", HeadTexture.FILLED_CAN, "&aOrganic Fertilizer", "&7Content: &9Beetroot"); - public static final SlimefunItemStack MELON_FERTILIZER = new SlimefunItemStack("FERTILIZER_MELON", HeadTexture.FILLED_CAN, "&aOrganic Fertilizer", "&7Content: &9Melon"); - public static final SlimefunItemStack APPLE_FERTILIZER = new SlimefunItemStack("FERTILIZER_APPLE", HeadTexture.FILLED_CAN, "&aOrganic Fertilizer", "&7Content: &9Apple"); - public static final SlimefunItemStack SWEET_BERRIES_FERTILIZER = new SlimefunItemStack("FERTILIZER_SWEET_BERRIES", HeadTexture.FILLED_CAN, "&aOrganic Fertilizer", "&7Content: &9Sweet Berries"); - public static final SlimefunItemStack KELP_FERTILIZER = new SlimefunItemStack("FERTILIZER_KELP", HeadTexture.FILLED_CAN, "&aOrganic Fertilizer", "&7Content: &9Dried Kelp"); - public static final SlimefunItemStack COCOA_FERTILIZER = new SlimefunItemStack("FERTILIZER_COCOA", HeadTexture.FILLED_CAN, "&aOrganic Fertilizer", "&7Content: &9Cocoa beans"); + public static final SlimefunItemStack WHEAT_FERTILIZER = new SlimefunItemStack("FERTILIZER_WHEAT", HeadTexture.FILLED_CAN, FERTILIZER.getDisplayName(), "&7Content: &9Wheat"); + public static final SlimefunItemStack CARROT_FERTILIZER = new SlimefunItemStack("FERTILIZER_CARROT", HeadTexture.FILLED_CAN, FERTILIZER.getDisplayName(), "&7Content: &9Carrots"); + public static final SlimefunItemStack POTATO_FERTILIZER = new SlimefunItemStack("FERTILIZER_POTATO", HeadTexture.FILLED_CAN, FERTILIZER.getDisplayName(), "&7Content: &9Potatoes"); + public static final SlimefunItemStack SEEDS_FERTILIZER = new SlimefunItemStack("FERTILIZER_SEEDS", HeadTexture.FILLED_CAN, FERTILIZER.getDisplayName(), "&7Content: &9Seeds"); + public static final SlimefunItemStack BEETROOT_FERTILIZER = new SlimefunItemStack("FERTILIZER_BEETROOT", HeadTexture.FILLED_CAN, FERTILIZER.getDisplayName(), "&7Content: &9Beetroot"); + public static final SlimefunItemStack MELON_FERTILIZER = new SlimefunItemStack("FERTILIZER_MELON", HeadTexture.FILLED_CAN, FERTILIZER.getDisplayName(), "&7Content: &9Melon"); + public static final SlimefunItemStack APPLE_FERTILIZER = new SlimefunItemStack("FERTILIZER_APPLE", HeadTexture.FILLED_CAN, FERTILIZER.getDisplayName(), "&7Content: &9Apple"); + public static final SlimefunItemStack SWEET_BERRIES_FERTILIZER = new SlimefunItemStack("FERTILIZER_SWEET_BERRIES", HeadTexture.FILLED_CAN, FERTILIZER.getDisplayName(), "&7Content: &9Sweet Berries"); + public static final SlimefunItemStack KELP_FERTILIZER = new SlimefunItemStack("FERTILIZER_KELP", HeadTexture.FILLED_CAN, FERTILIZER.getDisplayName(), "&7Content: &9Dried Kelp"); + public static final SlimefunItemStack COCOA_FERTILIZER = new SlimefunItemStack("FERTILIZER_COCOA", HeadTexture.FILLED_CAN, FERTILIZER.getDisplayName(), "&7Content: &9Cocoa beans"); public static final SlimefunItemStack ANIMAL_GROWTH_ACCELERATOR = new SlimefunItemStack("ANIMAL_GROWTH_ACCELERATOR", Material.HAY_BLOCK, "&bAnimal Growth Accelerator", "", "&fRuns on &aOrganic Food", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), LoreBuilder.powerBuffer(1024), LoreBuilder.powerPerSecond(28)); public static final SlimefunItemStack CROP_GROWTH_ACCELERATOR = new SlimefunItemStack("CROP_GROWTH_ACCELERATOR", Material.LIME_TERRACOTTA, "&aCrop Growth Accelerator", "", "&fRuns on &aOrganic Fertilizer", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), "&8\u21E8 &7Radius: 7x7", "&8\u21E8 &7Speed: &a3/time", LoreBuilder.powerBuffer(1024), LoreBuilder.powerPerSecond(50)); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java index b46b45f22..cab5348c2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java @@ -36,12 +36,12 @@ import io.github.thebusybiscuit.slimefun4.core.services.BlockDataService; import io.github.thebusybiscuit.slimefun4.core.services.CustomItemDataService; import io.github.thebusybiscuit.slimefun4.core.services.CustomTextureService; import io.github.thebusybiscuit.slimefun4.core.services.LocalizationService; +import io.github.thebusybiscuit.slimefun4.core.services.MetricsService; import io.github.thebusybiscuit.slimefun4.core.services.MinecraftRecipeService; import io.github.thebusybiscuit.slimefun4.core.services.PerWorldSettingsService; import io.github.thebusybiscuit.slimefun4.core.services.PermissionsService; import io.github.thebusybiscuit.slimefun4.core.services.UpdaterService; import io.github.thebusybiscuit.slimefun4.core.services.github.GitHubService; -import io.github.thebusybiscuit.slimefun4.core.services.MetricsService; import io.github.thebusybiscuit.slimefun4.core.services.plugins.ThirdPartyPluginService; import io.github.thebusybiscuit.slimefun4.core.services.profiler.SlimefunProfiler; import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar; @@ -61,6 +61,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.DeathpointLis import io.github.thebusybiscuit.slimefun4.implementation.listeners.DebugFishListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.DispenserListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.EnhancedFurnaceListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.EntityInteractionListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.ExplosionsListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.FireworksListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.GadgetsListener; @@ -69,7 +70,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.IronGolemList import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.MobDropListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener; -import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerInteractEntityListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.PiglinListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerProfileListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SeismicAxeListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBootsListener; @@ -81,6 +82,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.SoulboundList import io.github.thebusybiscuit.slimefun4.implementation.listeners.TalismanListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.VampireBladeListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.VanillaMachinesListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.VillagerTradingListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.WitherListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.WorldListener; import io.github.thebusybiscuit.slimefun4.implementation.resources.GEOResourcesSetup; @@ -110,6 +112,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { private static SlimefunPlugin instance; private MinecraftVersion minecraftVersion = MinecraftVersion.UNKNOWN; + private boolean isNewlyInstalled = false; private final SlimefunRegistry registry = new SlimefunRegistry(); private final TickerTask ticker = new TickerTask(); @@ -163,10 +166,11 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { local = new LocalizationService(this, "", null); gpsNetwork = new GPSNetwork(); command.register(); + registry.load(config); } else if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) { long timestamp = System.nanoTime(); - + PaperLib.suggestPaper(this); // We wanna ensure that the Server uses a compatible version of Minecraft @@ -175,6 +179,14 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { return; } + // Disabling backwards-compatibility for fresh Slimefun installs + if (!new File("data-storage/Slimefun").exists()) { + config.setValue("options.backwards-compatibility", false); + config.save(); + + isNewlyInstalled = true; + } + // Creating all necessary Folders getLogger().log(Level.INFO, "Creating directories..."); createDirectories(); @@ -245,7 +257,8 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { // Armor Update Task if (config.getBoolean("options.enable-armor-effects")) { - getServer().getScheduler().runTaskTimerAsynchronously(this, new ArmorTask(), 0L, config.getInt("options.armor-update-interval") * 20L); + boolean radioactiveFire = config.getBoolean("options.burn-players-when-radioactive"); + getServer().getScheduler().runTaskTimerAsynchronously(this, new ArmorTask(radioactiveFire), 0L, config.getInt("options.armor-update-interval") * 20L); } autoSavingService.start(this, config.getInt("options.auto-save-delay-in-minutes")); @@ -354,7 +367,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { // Save all registered Worlds for (Map.Entry entry : getRegistry().getWorlds().entrySet()) { try { - entry.getValue().save(true); + entry.getValue().saveAndRemove(); } catch (Exception x) { getLogger().log(Level.SEVERE, x, () -> "An Error occurred while saving Slimefun-Blocks in World '" + entry.getKey() + "' for Slimefun " + getVersion()); @@ -430,13 +443,17 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { new FireworksListener(this); new WitherListener(this); new IronGolemListener(this); - new PlayerInteractEntityListener(this); + new EntityInteractionListener(this); + new MobDropListener(this); + new VillagerTradingListener(this); if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) { new BeeListener(this); } - new MobDropListener(this); + if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_16)) { + new PiglinListener(this); + } // Item-specific Listeners new VampireBladeListener(this, (VampireBlade) SlimefunItems.BLADE_OF_VAMPIRES.getItem()); @@ -488,6 +505,12 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } } + /** + * This returns the global instance of {@link SlimefunPlugin}. + * This may return null if the {@link Plugin} was disabled. + * + * @return The {@link SlimefunPlugin} instance + */ public static SlimefunPlugin instance() { return instance; } @@ -637,6 +660,12 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { return instance.command; } + /** + * This returns our instance of the {@link SlimefunProfiler}, a tool that is used + * to analyse performance and lag. + * + * @return The {@link SlimefunProfiler} + */ public static SlimefunProfiler getProfiler() { return instance.profiler; } @@ -650,6 +679,16 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { return instance.minecraftVersion; } + /** + * This method returns whether this version of Slimefun was newly installed. + * It will return true if this {@link Server} uses Slimefun for the very first time. + * + * @return Whether this is a new installation of Slimefun + */ + public static boolean isNewlyInstalled() { + return instance.isNewlyInstalled; + } + public static String getCSCoreLibVersion() { return CSCoreLib.getLib().getDescription().getVersion(); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/BookSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/BookSlimefunGuide.java index afaa464d4..90cfc8234 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/BookSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/BookSlimefunGuide.java @@ -10,6 +10,7 @@ import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.chat.ChatInput; @@ -18,7 +19,6 @@ import io.github.thebusybiscuit.cscorelib2.chat.json.ClickEvent; import io.github.thebusybiscuit.cscorelib2.chat.json.CustomBookInterface; import io.github.thebusybiscuit.cscorelib2.chat.json.HoverEvent; import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; -import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory; import io.github.thebusybiscuit.slimefun4.core.categories.LockedCategory; @@ -36,6 +36,24 @@ import me.mrCookieSlime.Slimefun.api.Slimefun; public class BookSlimefunGuide implements SlimefunGuideImplementation { private final NamespacedKey guideSearch = new NamespacedKey(SlimefunPlugin.instance(), "search"); + private final ItemStack item; + + public BookSlimefunGuide() { + item = new ItemStack(Material.ENCHANTED_BOOK); + ItemMeta meta = item.getItemMeta(); + + meta.setDisplayName(ChatColors.color("&aSlimefun Guide &7(Book GUI)")); + + List lore = new LinkedList<>(); + + lore.add(""); + lore.add(ChatColors.color("&eRight Click &8\u21E8 &7Browse Items")); + lore.add(ChatColors.color("&eShift + Right Click &8\u21E8 &7Open Settings / Credits")); + + meta.setLore(lore); + SlimefunPlugin.getItemTextureService().setTexture(meta, "SLIMEFUN_GUIDE"); + item.setItemMeta(meta); + } @Override public SlimefunGuideLayout getLayout() { @@ -49,7 +67,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation { @Override public ItemStack getItem() { - return new CustomItem(new ItemStack(Material.ENCHANTED_BOOK), "&aSlimefun Guide &7(Book GUI)", "", "&eRight Click &8\u21E8 &7Browse Items", "&eShift + Right Click &8\u21E8 &7Open Settings / Credits"); + return item; } private void openBook(Player p, PlayerProfile profile, List lines, boolean backButton) { @@ -112,37 +130,41 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation { lines.add(new ChatComponent(ChatColor.DARK_GRAY + "\u21E8" + ChatColor.DARK_BLUE + " Tier " + tier + "\n")); } - if (category instanceof LockedCategory && !((LockedCategory) category).hasUnlocked(p, profile)) { - List lore = new LinkedList<>(); - lore.add(ChatColor.DARK_RED + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked") + " " + ChatColor.GRAY + "- " + ChatColor.RESET + category.getItem(p).getItemMeta().getDisplayName()); - lore.add(""); - - for (String line : SlimefunPlugin.getLocalization().getMessages(p, "guide.locked-category")) { - lore.add(ChatColor.RESET + line); - } - - lore.add(""); - - for (Category parent : ((LockedCategory) category).getParents()) { - lore.add(parent.getItem(p).getItemMeta().getDisplayName()); - } - - ChatComponent chatComponent = new ChatComponent(ChatUtils.crop(ChatColor.RED, ItemUtils.getItemName(category.getItem(p))) + "\n"); - chatComponent.setHoverEvent(new HoverEvent(lore)); - lines.add(chatComponent); - } - else { - ChatComponent chatComponent = new ChatComponent(ChatUtils.crop(ChatColor.DARK_GREEN, ItemUtils.getItemName(category.getItem(p))) + "\n"); - chatComponent.setHoverEvent(new HoverEvent(ItemUtils.getItemName(category.getItem(p)), "", ChatColor.GRAY + "\u21E8 " + ChatColor.GREEN + SlimefunPlugin.getLocalization().getMessage(p, "guide.tooltips.open-category"))); - chatComponent.setClickEvent(new ClickEvent(category.getKey(), pl -> openCategory(profile, category, 1))); - lines.add(chatComponent); - } + addCategory(p, profile, category, lines); } } openBook(p, profile, lines, false); } + private void addCategory(Player p, PlayerProfile profile, Category category, List lines) { + if (category instanceof LockedCategory && !((LockedCategory) category).hasUnlocked(p, profile)) { + List lore = new LinkedList<>(); + lore.add(ChatColor.DARK_RED + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked") + " " + ChatColor.GRAY + "- " + ChatColor.RESET + category.getItem(p).getItemMeta().getDisplayName()); + lore.add(""); + + for (String line : SlimefunPlugin.getLocalization().getMessages(p, "guide.locked-category")) { + lore.add(ChatColor.RESET + line); + } + + lore.add(""); + + for (Category parent : ((LockedCategory) category).getParents()) { + lore.add(parent.getItem(p).getItemMeta().getDisplayName()); + } + + ChatComponent chatComponent = new ChatComponent(ChatUtils.crop(ChatColor.RED, ItemUtils.getItemName(category.getItem(p))) + "\n"); + chatComponent.setHoverEvent(new HoverEvent(lore)); + lines.add(chatComponent); + } + else { + ChatComponent chatComponent = new ChatComponent(ChatUtils.crop(ChatColor.DARK_GREEN, ItemUtils.getItemName(category.getItem(p))) + "\n"); + chatComponent.setHoverEvent(new HoverEvent(ItemUtils.getItemName(category.getItem(p)), "", ChatColor.GRAY + "\u21E8 " + ChatColor.GREEN + SlimefunPlugin.getLocalization().getMessage(p, "guide.tooltips.open-category"))); + chatComponent.setClickEvent(new ClickEvent(category.getKey(), pl -> openCategory(profile, category, 1))); + lines.add(chatComponent); + } + } + @Override public void openCategory(PlayerProfile profile, Category category, int page) { Player p = profile.getPlayer(); @@ -159,20 +181,20 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation { List items = new LinkedList<>(); - for (SlimefunItem item : category.getItems()) { - if (Slimefun.hasPermission(p, item, false)) { - if (Slimefun.isEnabled(p, item, false)) { - appendSlimefunItem(category, page, p, profile, item, items); + for (SlimefunItem slimefunItem : category.getItems()) { + if (Slimefun.hasPermission(p, slimefunItem, false)) { + if (Slimefun.isEnabled(p, slimefunItem, false)) { + addSlimefunItem(category, page, p, profile, slimefunItem, items); } } else { - ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.DARK_RED, ItemUtils.getItemName(item.getItem())) + "\n"); + ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.DARK_RED, ItemUtils.getItemName(slimefunItem.getItem())) + "\n"); List lore = new ArrayList<>(); - lore.add(ChatColor.DARK_RED + ChatColor.stripColor(ItemUtils.getItemName(item.getItem()))); + lore.add(ChatColor.DARK_RED + ChatColor.stripColor(ItemUtils.getItemName(slimefunItem.getItem()))); lore.add(""); - for (String line : SlimefunPlugin.getPermissionsService().getLore(item)) { + for (String line : SlimefunPlugin.getPermissionsService().getLore(slimefunItem)) { lore.add(ChatColors.color(line)); } @@ -188,7 +210,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation { } } - private void appendSlimefunItem(Category category, int page, Player p, PlayerProfile profile, SlimefunItem item, List items) { + private void addSlimefunItem(Category category, int page, Player p, PlayerProfile profile, SlimefunItem item, List items) { NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), item.getID().toLowerCase(Locale.ROOT)); if (!Slimefun.hasUnlocked(p, item, false) && item.getResearch() != null) { @@ -196,21 +218,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation { ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.RED, item.getItemName()) + "\n"); component.setHoverEvent(new HoverEvent(ChatColor.RESET + item.getItemName(), ChatColor.DARK_RED.toString() + ChatColor.BOLD + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked"), "", ChatColor.GREEN + "> Click to unlock", "", ChatColor.GRAY + "Cost: " + ChatColor.AQUA.toString() + research.getCost() + " Level(s)")); - component.setClickEvent(new ClickEvent(key, player -> Slimefun.runSync(() -> { - if (!SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().contains(p.getUniqueId())) { - if (research.canUnlock(p)) { - if (profile.hasUnlocked(research)) { - openCategory(profile, category, page); - } - else { - unlockItem(p, item, pl -> openCategory(profile, category, page)); - } - } - else { - SlimefunPlugin.getLocalization().sendMessage(p, "messages.not-enough-xp", true); - } - } - }))); + component.setClickEvent(new ClickEvent(key, player -> research(player, profile, item, research, category, page))); items.add(component); } @@ -230,6 +238,24 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation { } } + private void research(Player p, PlayerProfile profile, SlimefunItem item, Research research, Category category, int page) { + Slimefun.runSync(() -> { + if (!SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().contains(p.getUniqueId())) { + if (research.canUnlock(p)) { + if (profile.hasUnlocked(research)) { + openCategory(profile, category, page); + } + else { + unlockItem(p, item, pl -> openCategory(profile, category, page)); + } + } + else { + SlimefunPlugin.getLocalization().sendMessage(p, "messages.not-enough-xp", true); + } + } + }); + } + @Override public void openSearch(PlayerProfile profile, String input, boolean addToHistory) { // We need to write a book implementation for this at some point diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java index d8d17c262..b115cc54b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java @@ -1,16 +1,41 @@ package io.github.thebusybiscuit.slimefun4.implementation.guide; -import org.bukkit.entity.Player; +import java.util.LinkedList; +import java.util.List; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; public class CheatSheetSlimefunGuide extends ChestSlimefunGuide { + private final ItemStack item; + public CheatSheetSlimefunGuide() { super(false); + + item = new ItemStack(Material.ENCHANTED_BOOK); + ItemMeta meta = item.getItemMeta(); + + meta.setDisplayName(ChatColors.color("&cSlimefun Guide &4(Cheat Sheet)")); + + List lore = new LinkedList<>(); + + lore.add(ChatColors.color("&4&lOnly openable by Admins")); + lore.add(ChatColors.color("&eRight Click &8\u21E8 &7Browse Items")); + lore.add(ChatColors.color("&eShift + Right Click &8\u21E8 &7Open Settings / Credits")); + + meta.setLore(lore); + SlimefunPlugin.getItemTextureService().setTexture(meta, "SLIMEFUN_GUIDE"); + item.setItemMeta(meta); } @Override @@ -23,6 +48,11 @@ public class CheatSheetSlimefunGuide extends ChestSlimefunGuide { return SlimefunGuideLayout.CHEAT_SHEET; } + @Override + public ItemStack getItem() { + return item; + } + @Override protected void createHeader(Player p, PlayerProfile profile, ChestMenu menu) { super.createHeader(p, profile, menu); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java index 52b3670ed..48f97598d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java @@ -18,7 +18,9 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; import org.bukkit.inventory.RecipeChoice; import org.bukkit.inventory.RecipeChoice.MaterialChoice; +import org.bukkit.inventory.meta.ItemMeta; +import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.chat.ChatInput; import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; @@ -50,6 +52,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { private static final int CATEGORY_SIZE = 36; + private final ItemStack item; private final int[] recipeSlots = { 3, 4, 5, 12, 13, 14, 21, 22, 23 }; private final Sound sound; private final boolean showVanillaRecipes; @@ -63,6 +66,21 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { else { sound = Sound.ENTITY_BAT_TAKEOFF; } + + item = new ItemStack(Material.ENCHANTED_BOOK); + ItemMeta meta = item.getItemMeta(); + + meta.setDisplayName(ChatColors.color("&aSlimefun Guide &7(Chest GUI)")); + + List lore = new LinkedList<>(); + + lore.add(""); + lore.add(ChatColors.color("&eRight Click &8\u21E8 &7Browse Items")); + lore.add(ChatColors.color("&eShift + Right Click &8\u21E8 &7Open Settings / Credits")); + + meta.setLore(lore); + SlimefunPlugin.getItemTextureService().setTexture(meta, "SLIMEFUN_GUIDE"); + item.setItemMeta(meta); } @Override @@ -72,7 +90,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { @Override public ItemStack getItem() { - return new CustomItem(new ItemStack(Material.ENCHANTED_BOOK), "&aSlimefun Guide &7(Chest GUI)", "", "&eRight Click &8\u21E8 &7Browse Items", "&eShift + Right Click &8\u21E8 &7Open Settings / Credits"); + return item; } @Override @@ -313,17 +331,17 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { int index = 9; // Find items and add them - for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) { - String itemName = ChatColor.stripColor(item.getItemName()).toLowerCase(Locale.ROOT); + for (SlimefunItem slimefunItem : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) { + String itemName = ChatColor.stripColor(slimefunItem.getItemName()).toLowerCase(Locale.ROOT); if (index == 44) { break; } if (!itemName.isEmpty() && (itemName.equals(searchTerm) || itemName.contains(searchTerm))) { - ItemStack itemstack = new CustomItem(item.getItem(), meta -> { + ItemStack itemstack = new CustomItem(slimefunItem.getItem(), meta -> { List lore = null; - Category category = item.getCategory(); + Category category = slimefunItem.getCategory(); if (category != null) { ItemStack categoryItem = category.getItem(p); @@ -341,10 +359,10 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { menu.addMenuClickHandler(index, (pl, slot, itm, action) -> { try { if (!isSurvivalMode()) { - pl.getInventory().addItem(item.getItem().clone()); + pl.getInventory().addItem(slimefunItem.getItem().clone()); } else { - displayItem(profile, item, true); + displayItem(profile, slimefunItem, true); } } catch (Exception | LinkageError x) { @@ -400,30 +418,9 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { RecipeChoiceTask task = new RecipeChoiceTask(); if (optional.isPresent()) { - MinecraftRecipe mcRecipe = optional.get(); + showRecipeChoices(recipe, recipeItems, task); - RecipeChoice[] choices = SlimefunPlugin.getMinecraftRecipeService().getRecipeShape(recipe); - - if (choices.length == 1 && choices[0] instanceof MaterialChoice) { - recipeItems[4] = new ItemStack(((MaterialChoice) choices[0]).getChoices().get(0)); - - if (((MaterialChoice) choices[0]).getChoices().size() > 1) { - task.add(recipeSlots[4], (MaterialChoice) choices[0]); - } - } - else { - for (int i = 0; i < choices.length; i++) { - if (choices[i] instanceof MaterialChoice) { - recipeItems[i] = new ItemStack(((MaterialChoice) choices[i]).getChoices().get(0)); - - if (((MaterialChoice) choices[i]).getChoices().size() > 1) { - task.add(recipeSlots[i], (MaterialChoice) choices[i]); - } - } - } - } - - recipeType = new RecipeType(mcRecipe); + recipeType = new RecipeType(optional.get()); result = recipe.getResult(); } else { @@ -465,6 +462,29 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { } } + private void showRecipeChoices(T recipe, ItemStack[] recipeItems, RecipeChoiceTask task) { + RecipeChoice[] choices = SlimefunPlugin.getMinecraftRecipeService().getRecipeShape(recipe); + + if (choices.length == 1 && choices[0] instanceof MaterialChoice) { + recipeItems[4] = new ItemStack(((MaterialChoice) choices[0]).getChoices().get(0)); + + if (((MaterialChoice) choices[0]).getChoices().size() > 1) { + task.add(recipeSlots[4], (MaterialChoice) choices[0]); + } + } + else { + for (int i = 0; i < choices.length; i++) { + if (choices[i] instanceof MaterialChoice) { + recipeItems[i] = new ItemStack(((MaterialChoice) choices[i]).getChoices().get(0)); + + if (((MaterialChoice) choices[i]).getChoices().size() > 1) { + task.add(recipeSlots[i], (MaterialChoice) choices[i]); + } + } + } + } + } + @Override public void displayItem(PlayerProfile profile, SlimefunItem item, boolean addToHistory) { Player p = profile.getPlayer(); @@ -670,15 +690,15 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { private void addDisplayRecipe(ChestMenu menu, PlayerProfile profile, List recipes, int slot, int i, int page) { if ((i + (page * 18)) < recipes.size()) { - ItemStack item = recipes.get(i + (page * 18)); + ItemStack displayItem = recipes.get(i + (page * 18)); // We want to clone this item to avoid corrupting the original // but we wanna make sure no stupid addon creator sneaked some nulls in here - if (item != null) { - item = item.clone(); + if (displayItem != null) { + displayItem = displayItem.clone(); } - menu.replaceExistingItem(slot, item); + menu.replaceExistingItem(slot, displayItem); if (page == 0) { menu.addMenuClickHandler(slot, (pl, s, itemstack, action) -> { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/RadioactiveItem.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/RadioactiveItem.java index 3135ee83c..54f5d83e0 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/RadioactiveItem.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/RadioactiveItem.java @@ -15,6 +15,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; /** * A quick and easy implementation of {@link SlimefunItem} that also implements the * interface {@link Radioactive}. + * This implementation is {@link NotPlaceable}! * * Simply specify a level of {@link Radioactivity} in the constructor. * @@ -43,10 +44,29 @@ public class RadioactiveItem extends SlimefunItem implements Radioactive, NotPla * The recipe of how to craft this {@link SlimefunItem} */ public RadioactiveItem(Category category, Radioactivity radioactivity, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { - super(category, item, recipeType, recipe); + this(category, radioactivity, item, recipeType, recipe, null); + } + + /** + * This will create a new {@link RadioactiveItem} with the given level of {@link Radioactivity} + * + * @param category + * The {@link Category} of this {@link SlimefunItem} + * @param radioactivity + * the level of {@link Radioactivity} + * @param item + * the {@link SlimefunItemStack} this {@link SlimefunItem} represents + * @param recipeType + * The {@link RecipeType} for this item + * @param recipe + * The recipe of how to craft this {@link SlimefunItem} + * @param recipeOutput + * The recipe output + */ + public RadioactiveItem(Category category, Radioactivity radioactivity, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { + super(category, item, recipeType, recipe, recipeOutput); this.radioactivity = radioactivity; - addItemHandler(onRightClick()); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidFuelSource.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidFuelSource.java index eec39eb1d..47bbb6724 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidFuelSource.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidFuelSource.java @@ -16,17 +16,17 @@ public enum AndroidFuelSource { /** * This {@link ProgrammableAndroid} runs on solid fuel, e.g. Wood or coal */ - SOLID("", "&rThis Android runs on solid Fuel", "&re.g. Coal, Wood, etc..."), + SOLID("", "&fThis Android runs on solid Fuel", "&fe.g. Coal, Wood, etc..."), /** * This {@link ProgrammableAndroid} runs on liquid fuel, e.g. Fuel, Oil or Lava */ - LIQUID("", "&rThis Android runs on liquid Fuel", "&re.g. Lava, Oil, Fuel, etc..."), + LIQUID("", "&fThis Android runs on liquid Fuel", "&fe.g. Lava, Oil, Fuel, etc..."), /** * This {@link ProgrammableAndroid} runs on nuclear fuel, e.g. Uranium */ - NUCLEAR("", "&rThis Android runs on radioactive Fuel", "&re.g. Uranium, Neptunium or Boosted Uranium"); + NUCLEAR("", "&fThis Android runs on radioactive Fuel", "&fe.g. Uranium, Neptunium or Boosted Uranium"); private final String[] lore; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/MinerAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/MinerAndroid.java index 2553ba4d8..f475995fe 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/MinerAndroid.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/MinerAndroid.java @@ -6,6 +6,7 @@ import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.Effect; import org.bukkit.Material; +import org.bukkit.OfflinePlayer; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.inventory.ItemStack; @@ -39,24 +40,28 @@ public abstract class MinerAndroid extends ProgrammableAndroid { protected void dig(Block b, BlockMenu menu, Block block) { Collection drops = block.getDrops(effectivePickaxe); - if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty() && SlimefunPlugin.getProtectionManager().hasPermission(Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"))), block.getLocation(), ProtectableAction.BREAK_BLOCK)) { + if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty()) { + OfflinePlayer owner = Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"))); - AndroidMineEvent event = new AndroidMineEvent(block, new AndroidInstance(this, b)); - Bukkit.getPluginManager().callEvent(event); + if (SlimefunPlugin.getProtectionManager().hasPermission(owner, block.getLocation(), ProtectableAction.BREAK_BLOCK)) { + AndroidMineEvent event = new AndroidMineEvent(block, new AndroidInstance(this, b)); + Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } + if (event.isCancelled()) { + return; + } - // We only want to break non-Slimefun blocks - String blockId = BlockStorage.checkID(block); - if (blockId == null) { - for (ItemStack drop : drops) { - if (menu.fits(drop, getOutputSlots())) { - menu.pushItem(drop, getOutputSlots()); - block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType()); - block.setType(Material.AIR); + // We only want to break non-Slimefun blocks + String blockId = BlockStorage.checkID(block); + if (blockId == null) { + for (ItemStack drop : drops) { + if (menu.fits(drop, getOutputSlots())) { + menu.pushItem(drop, getOutputSlots()); + } } + + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType()); + block.setType(Material.AIR); } } } @@ -66,30 +71,34 @@ public abstract class MinerAndroid extends ProgrammableAndroid { protected void moveAndDig(Block b, BlockMenu menu, BlockFace face, Block block) { Collection drops = block.getDrops(effectivePickaxe); - if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty() && SlimefunPlugin.getProtectionManager().hasPermission(Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"))), block.getLocation(), ProtectableAction.BREAK_BLOCK)) { + if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty()) { + OfflinePlayer owner = Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"))); - AndroidMineEvent event = new AndroidMineEvent(block, new AndroidInstance(this, b)); - Bukkit.getPluginManager().callEvent(event); + if (SlimefunPlugin.getProtectionManager().hasPermission(owner, block.getLocation(), ProtectableAction.BREAK_BLOCK)) { + AndroidMineEvent event = new AndroidMineEvent(block, new AndroidInstance(this, b)); + Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - - // We only want to break non-Slimefun blocks - SlimefunItem blockId = BlockStorage.check(block); - if (blockId == null) { - for (ItemStack drop : drops) { - if (menu.fits(drop, getOutputSlots())) { - menu.pushItem(drop, getOutputSlots()); - block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType()); - - block.setType(Material.AIR); - move(b, face, block); - - b.setType(Material.AIR); - BlockStorage.moveBlockInfo(b.getLocation(), block.getLocation()); - } + if (event.isCancelled()) { + return; } + + // We only want to break non-Slimefun blocks + SlimefunItem blockId = BlockStorage.check(block); + if (blockId == null) { + for (ItemStack drop : drops) { + if (menu.fits(drop, getOutputSlots())) { + menu.pushItem(drop, getOutputSlots()); + } + } + + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType()); + + block.setType(Material.AIR); + move(b, face, block); + } + } + else { + move(b, face, block); } } else { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java index 149614e11..4bd2b00e5 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java @@ -20,6 +20,7 @@ import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Rotatable; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -31,6 +32,7 @@ import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.skull.SkullBlock; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; @@ -44,12 +46,12 @@ import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenu import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; +import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; @@ -123,48 +125,48 @@ public abstract class ProgrammableAndroid extends SlimefunItem implements Invent } }; - registerBlockHandler(getID(), new SlimefunBlockHandler() { + registerBlockHandler(getID(), (p, b, stack, reason) -> { + boolean allow = reason == UnregisterReason.PLAYER_BREAK && (BlockStorage.getLocationInfo(b.getLocation(), "owner").equals(p.getUniqueId().toString()) || p.hasPermission("slimefun.android.bypass")); + + if (allow) { + BlockMenu inv = BlockStorage.getInventory(b); + + if (inv != null) { + inv.dropItems(b.getLocation(), 43); + inv.dropItems(b.getLocation(), getOutputSlots()); + } + } + + return allow; + }); + + addItemHandler(onPlace()); + } + + private ItemHandler onPlace() { + return new BlockPlaceHandler(false) { @Override - public void onPlace(Player p, Block b, SlimefunItem item) { + public void onPlayerPlace(BlockPlaceEvent e) { + Player p = e.getPlayer(); + Block b = e.getBlock(); + BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString()); BlockStorage.addBlockInfo(b, "script", DEFAULT_SCRIPT); BlockStorage.addBlockInfo(b, "index", "0"); BlockStorage.addBlockInfo(b, "fuel", "0"); BlockStorage.addBlockInfo(b, "rotation", p.getFacing().getOppositeFace().toString()); BlockStorage.addBlockInfo(b, "paused", "true"); - b.setType(Material.PLAYER_HEAD); - Rotatable blockData = (Rotatable) b.getBlockData(); - blockData.setRotation(p.getFacing()); + BlockData blockData = Material.PLAYER_HEAD.createBlockData(data -> { + if (data instanceof Rotatable) { + ((Rotatable) data).setRotation(p.getFacing()); + } + }); + b.setBlockData(blockData); } - - @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - boolean allow = reason == UnregisterReason.PLAYER_BREAK && (BlockStorage.getLocationInfo(b.getLocation(), "owner").equals(p.getUniqueId().toString()) || p.hasPermission("slimefun.android.bypass")); - - if (allow) { - BlockMenu inv = BlockStorage.getInventory(b); - - if (inv != null) { - if (inv.getItemInSlot(43) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(43)); - inv.replaceExistingItem(43, null); - } - - for (int slot : getOutputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - } - } - - return allow; - } - }); + }; } /** @@ -172,7 +174,9 @@ public abstract class ProgrammableAndroid extends SlimefunItem implements Invent * * @return The type of this {@link ProgrammableAndroid} */ - public abstract AndroidType getAndroidType(); + public AndroidType getAndroidType() { + return AndroidType.NONE; + } /** * This returns the {@link AndroidFuelSource} for this {@link ProgrammableAndroid}. @@ -500,7 +504,7 @@ public abstract class ProgrammableAndroid extends SlimefunItem implements Invent ChestMenu menu = new ChestMenu(ChatColor.DARK_AQUA + SlimefunPlugin.getLocalization().getMessage(p, "android.scripts.editor")); ChestMenuUtils.drawBackground(menu, 0, 1, 2, 3, 4, 5, 6, 7, 8); - menu.addItem(9, new CustomItem(SlimefunUtils.getCustomHead("16139fd1c5654e56e9e4e2c8be7eb2bd5b499d633616663feee99b74352ad64"), "&rDo nothing"), (pl, slot, item, action) -> { + menu.addItem(9, new CustomItem(SlimefunUtils.getCustomHead("16139fd1c5654e56e9e4e2c8be7eb2bd5b499d633616663feee99b74352ad64"), "&fDo nothing"), (pl, slot, item, action) -> { String code = deleteInstruction(script, index); setScript(b.getLocation(), code); openScript(p, b, code); @@ -683,9 +687,14 @@ public abstract class ProgrammableAndroid extends SlimefunItem implements Invent BlockFace rotation = POSSIBLE_ROTATIONS.get(index); - Rotatable rotatatable = (Rotatable) b.getBlockData(); - rotatatable.setRotation(rotation.getOppositeFace()); - b.setBlockData(rotatatable); + BlockData blockData = Material.PLAYER_HEAD.createBlockData(data -> { + if (data instanceof Rotatable) { + Rotatable rotatable = ((Rotatable) data); + rotatable.setRotation(rotation.getOppositeFace()); + } + }); + + b.setBlockData(blockData); BlockStorage.addBlockInfo(b, "rotation", rotation.name()); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/BlockPlacer.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/BlockPlacer.java index 096941e03..225af96dd 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/BlockPlacer.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/BlockPlacer.java @@ -1,27 +1,33 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.blocks; import java.util.List; -import java.util.Optional; +import java.util.UUID; import java.util.stream.Collectors; +import org.bukkit.Bukkit; import org.bukkit.Effect; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Nameable; +import org.bukkit.OfflinePlayer; import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.CreatureSpawner; import org.bukkit.block.Dispenser; -import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections; +import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; +import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockDispenseHandler; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; +import io.papermc.lib.PaperLib; +import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; @@ -29,7 +35,18 @@ import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -public class BlockPlacer extends SimpleSlimefunItem { +/** + * The {@link BlockPlacer} is a machine which can place {@link Block Blocks}, as the name + * would suggest. + * It really just is a special type of {@link Dispenser} which places items instead of + * shooting them. + * + * @author TheBusyBiscuit + * + * @see BlockPlacerPlaceEvent + * + */ +public class BlockPlacer extends SlimefunItem { private final ItemSetting> blacklist = new ItemSetting<>("unplaceable-blocks", MaterialCollections.getAllUnbreakableBlocks().stream().map(Material::name).collect(Collectors.toList())); @@ -37,11 +54,28 @@ public class BlockPlacer extends SimpleSlimefunItem { super(category, item, recipeType, recipe); addItemSetting(blacklist); + addItemHandler(onPlace(), onBlockDispense()); } - @Override - public BlockDispenseHandler getItemHandler() { + private BlockPlaceHandler onPlace() { + return new BlockPlaceHandler(false) { + + @Override + public void onPlayerPlace(BlockPlaceEvent e) { + Player p = e.getPlayer(); + Block b = e.getBlock(); + + BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString()); + } + }; + } + + private BlockDispenseHandler onBlockDispense() { return (e, dispenser, facedBlock, machine) -> { + if (!hasPermission(dispenser, facedBlock)) { + return; + } + if (isShulkerBox(e.getItem().getType())) { // Since vanilla Dispensers can already place Shulker boxes, we // simply fallback to the vanilla behaviour. @@ -50,12 +84,12 @@ public class BlockPlacer extends SimpleSlimefunItem { e.setCancelled(true); - if ((facedBlock.getType() == null || facedBlock.getType() == Material.AIR) && e.getItem().getType().isBlock() && !isBlacklisted(e.getItem().getType())) { + if (facedBlock.isEmpty() && e.getItem().getType().isBlock() && !isBlacklisted(e.getItem().getType())) { SlimefunItem item = SlimefunItem.getByItem(e.getItem()); if (item != null) { // Check if this Item can even be placed down - if (!(item instanceof NotPlaceable) && !SlimefunPlugin.getRegistry().getBlockHandlers().containsKey(item.getID())) { + if (!(item instanceof NotPlaceable)) { placeSlimefunBlock(item, e.getItem(), facedBlock, dispenser); } } @@ -66,6 +100,31 @@ public class BlockPlacer extends SimpleSlimefunItem { }; } + /** + * This checks whether the {@link Player} who placed down this {@link BlockPlacer} has + * building permissions at that {@link Location}. + * + * @param dispenser + * The {@link Dispenser} who represents our {@link BlockPlacer} + * @param target + * The {@link Block} where it should be placed + * + * @return Whether this action is permitted or not + */ + private boolean hasPermission(Dispenser dispenser, Block target) { + String owner = BlockStorage.getLocationInfo(dispenser.getLocation(), "owner"); + + if (owner == null) { + // If no owner was set, then we will fallback to the previous behaviour: + // Allowing block placers to bypass protection, newly placed Block placers + // will respect protection plugins. + return true; + } + + OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(owner)); + return SlimefunPlugin.getProtectionManager().hasPermission(player, target, ProtectableAction.PLACE_BLOCK); + } + private boolean isShulkerBox(Material type) { return type == Material.SHULKER_BOX || type.name().endsWith("_SHULKER_BOX"); } @@ -81,54 +140,77 @@ public class BlockPlacer extends SimpleSlimefunItem { } private void placeSlimefunBlock(SlimefunItem sfItem, ItemStack item, Block block, Dispenser dispenser) { - block.setType(item.getType()); - BlockStorage.store(block, sfItem.getID()); - block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, item.getType()); + BlockPlacerPlaceEvent e = new BlockPlacerPlaceEvent(dispenser.getBlock(), item, block); + Bukkit.getPluginManager().callEvent(e); - if (item.getType() == Material.SPAWNER && sfItem instanceof RepairedSpawner) { - Optional entity = ((RepairedSpawner) sfItem).getEntityType(item); + if (!e.isCancelled()) { + boolean hasItemHandler = sfItem.callItemHandler(BlockPlaceHandler.class, handler -> { + if (handler.isBlockPlacerAllowed()) { + block.setType(item.getType()); + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, item.getType()); - if (entity.isPresent()) { - CreatureSpawner spawner = (CreatureSpawner) block.getState(); - spawner.setSpawnedType(entity.get()); - spawner.update(true, false); + BlockStorage.store(block, sfItem.getID()); + handler.onBlockPlacerPlace(e); + + if (dispenser.getInventory().containsAtLeast(item, 2)) { + dispenser.getInventory().removeItem(new CustomItem(item, 1)); + } + else { + Slimefun.runSync(() -> dispenser.getInventory().removeItem(item), 2L); + } + } + }); + + if (!hasItemHandler) { + block.setType(item.getType()); + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, item.getType()); + + BlockStorage.store(block, sfItem.getID()); + + if (dispenser.getInventory().containsAtLeast(item, 2)) { + dispenser.getInventory().removeItem(new CustomItem(item, 1)); + } + else { + Slimefun.runSync(() -> dispenser.getInventory().removeItem(item), 2L); + } } } - - if (dispenser.getInventory().containsAtLeast(item, 2)) { - dispenser.getInventory().removeItem(new CustomItem(item, 1)); - } - else { - Slimefun.runSync(() -> dispenser.getInventory().removeItem(item), 2L); - } } private void placeBlock(ItemStack item, Block facedBlock, Dispenser dispenser) { - facedBlock.setType(item.getType()); + BlockPlacerPlaceEvent e = new BlockPlacerPlaceEvent(dispenser.getBlock(), item, facedBlock); + Bukkit.getPluginManager().callEvent(e); - if (item.hasItemMeta()) { - ItemMeta meta = item.getItemMeta(); + if (!e.isCancelled()) { + facedBlock.setType(item.getType()); - if (meta.hasDisplayName()) { - BlockState blockState = facedBlock.getState(); + if (item.hasItemMeta()) { + ItemMeta meta = item.getItemMeta(); - if ((blockState instanceof Nameable)) { - ((Nameable) blockState).setCustomName(meta.getDisplayName()); + if (meta.hasDisplayName()) { + BlockStateSnapshotResult blockState = PaperLib.getBlockState(facedBlock, false); + + if ((blockState.getState() instanceof Nameable)) { + Nameable nameable = ((Nameable) blockState.getState()); + nameable.setCustomName(meta.getDisplayName()); + + if (blockState.isSnapshot()) { + // Update block state after changing name + blockState.getState().update(true, false); + } + } } - // Update block state after changing name - blockState.update(); } - } + facedBlock.getWorld().playEffect(facedBlock.getLocation(), Effect.STEP_SOUND, item.getType()); - facedBlock.getWorld().playEffect(facedBlock.getLocation(), Effect.STEP_SOUND, item.getType()); - - if (dispenser.getInventory().containsAtLeast(item, 2)) { - dispenser.getInventory().removeItem(new CustomItem(item, 1)); - } - else { - Slimefun.runSync(() -> dispenser.getInventory().removeItem(item), 2L); + if (dispenser.getInventory().containsAtLeast(item, 2)) { + dispenser.getInventory().removeItem(new CustomItem(item, 1)); + } + else { + Slimefun.runSync(() -> dispenser.getInventory().removeItem(item), 2L); + } } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/EnhancedFurnace.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/EnhancedFurnace.java index a57ea975c..bfdc7464b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/EnhancedFurnace.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/EnhancedFurnace.java @@ -4,10 +4,13 @@ import java.util.concurrent.ThreadLocalRandom; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.BlockState; import org.bukkit.block.Furnace; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; +import io.papermc.lib.PaperLib; +import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; @@ -40,15 +43,26 @@ public class EnhancedFurnace extends SimpleSlimefunItem { this.fortuneLevel = fortune - 1; } - public int getSpeed() { + /** + * This returns the processing speed of this {@link EnhancedFurnace}. + * + * @return The processing speed + */ + public int getProcessingSpeed() { return speed; } + /** + * This returns the fuel efficiency of this {@link EnhancedFurnace}. + * The fuel efficiency is a multiplier that is applied to any fuel burnt in this {@link EnhancedFurnace}. + * + * @return The fuel multiplier + */ public int getFuelEfficiency() { return efficiency; } - public int getOutput() { + public int getRandomOutputAmount() { int bonus = ThreadLocalRandom.current().nextInt(fortuneLevel + 2); return 1 + bonus; } @@ -64,20 +78,32 @@ public class EnhancedFurnace extends SimpleSlimefunItem { BlockStorage.clearBlockInfo(b); } else { - Furnace furnace = (Furnace) b.getState(); + BlockStateSnapshotResult result = PaperLib.getBlockState(b, false); + BlockState state = result.getState(); - if (furnace.getCookTime() > 0) { - int cookTime = furnace.getCookTime() + getSpeed() * 10; - furnace.setCookTime((short) Math.min(cookTime, furnace.getCookTimeTotal() - 1)); - furnace.update(true, false); + // Check if the BlockState is a Furnace and cooking something + if (state instanceof Furnace && ((Furnace) state).getCookTime() > 0) { + setProgress((Furnace) state); + + // Only update if necessary + if (result.isSnapshot()) { + state.update(true, false); + } } } } @Override public boolean isSynchronized() { + // This messes with BlockStates, so it needs to be synchronized return true; } }; } + + private void setProgress(Furnace furnace) { + // Update the cooktime + int cookTime = furnace.getCookTime() + getProcessingSpeed() * 10; + furnace.setCookTime((short) Math.min(cookTime, furnace.getCookTimeTotal() - 1)); + } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/HologramProjector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/HologramProjector.java index c030eee2d..5fd261af5 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/HologramProjector.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/HologramProjector.java @@ -6,51 +6,57 @@ import org.bukkit.block.Block; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -public class HologramProjector extends SimpleSlimefunItem { +public class HologramProjector extends SlimefunItem { public HologramProjector(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { super(category, item, recipeType, recipe, recipeOutput); - SlimefunItem.registerBlockHandler(getID(), new SlimefunBlockHandler() { + addItemHandler(onPlace(), onRightClick(), onBreak()); + } + + private BlockPlaceHandler onPlace() { + return new BlockPlaceHandler(false) { @Override - public void onPlace(Player p, Block b, SlimefunItem item) { + public void onPlayerPlace(BlockPlaceEvent e) { + Block b = e.getBlockPlaced(); BlockStorage.addBlockInfo(b, "text", "Edit me via the Projector"); BlockStorage.addBlockInfo(b, "offset", "0.5"); - BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString()); + BlockStorage.addBlockInfo(b, "owner", e.getPlayer().getUniqueId().toString()); getArmorStand(b, true); } - @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - remove(b); - return true; - } - }); + }; } - @Override - public BlockUseHandler getItemHandler() { + private BlockBreakHandler onBreak() { + return (e, item, fortune, drops) -> { + remove(e.getBlock()); + return true; + }; + } + + public BlockUseHandler onRightClick() { return e -> { e.cancel(); @@ -77,10 +83,11 @@ public class HologramProjector extends SimpleSlimefunItem { BlockStorage.addBlockInfo(projector, "text", hologram.getCustomName()); openEditor(pl, projector); }); + return false; }); - menu.addItem(1, new CustomItem(new ItemStack(Material.CLOCK), "&7Offset: &e" + DoubleHandler.fixDouble(Double.valueOf(BlockStorage.getLocationInfo(projector.getLocation(), "offset")) + 1.0D), "", "&rLeft Click: &7+0.1", "&rRight Click: &7-0.1")); + menu.addItem(1, new CustomItem(Material.CLOCK, "&7Offset: &e" + DoubleHandler.fixDouble(Double.valueOf(BlockStorage.getLocationInfo(projector.getLocation(), "offset")) + 1.0D), "", "&rLeft Click: &7+0.1", "&rRight Click: &7-0.1")); menu.addMenuClickHandler(1, (pl, slot, item, action) -> { double offset = DoubleHandler.fixDouble(Double.valueOf(BlockStorage.getLocationInfo(projector.getLocation(), "offset")) + (action.isRightClicked() ? -0.1F : 0.1F)); ArmorStand hologram = getArmorStand(projector, true); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/RepairedSpawner.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/RepairedSpawner.java index 6155cbd97..66fef9d18 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/RepairedSpawner.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/RepairedSpawner.java @@ -4,18 +4,28 @@ import java.util.Locale; import java.util.Optional; import org.bukkit.ChatColor; +import org.bukkit.Material; import org.bukkit.block.CreatureSpawner; import org.bukkit.entity.EntityType; +import org.bukkit.event.block.BlockEvent; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; -import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +/** + * A {@link RepairedSpawner} is the repaired variant of a {@link BrokenSpawner}. + * + * @author TheBusyBiscuit + * + * @see BrokenSpawner + * + */ public class RepairedSpawner extends SimpleSlimefunItem { public RepairedSpawner(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { @@ -24,21 +34,26 @@ public class RepairedSpawner extends SimpleSlimefunItem { @Override public BlockPlaceHandler getItemHandler() { - return (p, e, item) -> { - // We need to explicitly ignore the lore here - if (SlimefunUtils.isItemSimilar(item, SlimefunItems.REPAIRED_SPAWNER, false, false)) { + return new BlockPlaceHandler(true) { + + @Override + public void onPlayerPlace(BlockPlaceEvent e) { + onPlace(e.getItemInHand(), e); + } + + @Override + public void onBlockPlacerPlace(BlockPlacerPlaceEvent e) { + onPlace(e.getItemStack(), e); + } + + private void onPlace(ItemStack item, BlockEvent e) { Optional entity = getEntityType(item); - if (entity.isPresent()) { + if (entity.isPresent() && e.getBlock().getType() == Material.SPAWNER) { CreatureSpawner spawner = (CreatureSpawner) e.getBlock().getState(); spawner.setSpawnedType(entity.get()); spawner.update(true, false); } - - return true; - } - else { - return false; } }; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractCargoNode.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractCargoNode.java index 79f38daa7..fac303f2f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractCargoNode.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractCargoNode.java @@ -2,19 +2,33 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.cargo; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.cscorelib2.item.CustomItem; +import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; +import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; +import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow; +/** + * This abstract class is the super class of all cargo nodes. + * + * @author TheBusyBiscuit + * + */ abstract class AbstractCargoNode extends SlimefunItem { protected static final String FREQUENCY = "frequency"; @@ -22,6 +36,21 @@ abstract class AbstractCargoNode extends SlimefunItem { public AbstractCargoNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { super(category, item, recipeType, recipe, recipeOutput); + addItemHandler(new BlockPlaceHandler(false) { + + @Override + public void onPlayerPlace(BlockPlaceEvent e) { + Block b = e.getBlock(); + + // The owner and frequency are required by every node + BlockStorage.addBlockInfo(b, "owner", e.getPlayer().getUniqueId().toString()); + BlockStorage.addBlockInfo(b, FREQUENCY, "0"); + + onPlace(e); + } + + }); + new BlockMenuPreset(getID(), ChatUtils.removeColorCodes(item.getItemMeta().getDisplayName())) { @Override @@ -46,6 +75,59 @@ abstract class AbstractCargoNode extends SlimefunItem { }; } + protected void addChannelSelector(Block b, BlockMenu menu, int slotPrev, int slotCurrent, int slotNext) { + boolean isChestTerminalInstalled = SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled(); + + menu.replaceExistingItem(slotPrev, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.CARGO_ARROW_LEFT.getTexture()), "&bPrevious Channel", "", "&e> Click to decrease the Channel ID by 1")); + menu.addMenuClickHandler(slotPrev, (p, slot, item, action) -> { + int channel = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) - 1; + + if (channel < 0) { + if (isChestTerminalInstalled) { + channel = 16; + } + else { + channel = 15; + } + } + + BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channel)); + updateBlockMenu(menu, b); + return false; + }); + + int channel = ((!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY) == null) ? 0 : (Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)))); + + if (channel == 16) { + menu.replaceExistingItem(slotCurrent, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.CHEST_TERMINAL.getTexture()), "&bChannel ID: &3" + (channel + 1))); + menu.addMenuClickHandler(slotCurrent, ChestMenuUtils.getEmptyClickHandler()); + } + else { + menu.replaceExistingItem(slotCurrent, new CustomItem(MaterialCollections.getAllWoolColors().get(channel), "&bChannel ID: &3" + (channel + 1))); + menu.addMenuClickHandler(slotCurrent, ChestMenuUtils.getEmptyClickHandler()); + } + + menu.replaceExistingItem(slotNext, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.CARGO_ARROW_RIGHT.getTexture()), "&bNext Channel", "", "&e> Click to increase the Channel ID by 1")); + menu.addMenuClickHandler(slotNext, (p, slot, item, action) -> { + int channeln = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) + 1; + + if (isChestTerminalInstalled) { + if (channeln > 16) { + channeln = 0; + } + } + else if (channeln > 15) { + channeln = 0; + } + + BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channeln)); + updateBlockMenu(menu, b); + return false; + }); + } + + protected abstract void onPlace(BlockPlaceEvent e); + protected abstract void createBorder(BlockMenuPreset preset); protected abstract void updateBlockMenu(BlockMenu menu, Block b); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractFilterNode.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractFilterNode.java new file mode 100644 index 000000000..c93b1b37e --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractFilterNode.java @@ -0,0 +1,140 @@ +package io.github.thebusybiscuit.slimefun4.implementation.items.cargo; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.Damageable; +import org.bukkit.inventory.meta.ItemMeta; + +import io.github.thebusybiscuit.cscorelib2.item.CustomItem; +import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; +import me.mrCookieSlime.Slimefun.Lists.RecipeType; +import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.api.BlockStorage; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; +import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; + +/** + * This abstract super class represents all filtered Cargo nodes. + * + * @author TheBusyBiscuit + * + * @see CargoInputNode + * @see AdvancedCargoOutputNode + * + */ +abstract class AbstractFilterNode extends AbstractCargoNode { + + protected static final int[] SLOTS = { 19, 20, 21, 28, 29, 30, 37, 38, 39 }; + + public AbstractFilterNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { + super(category, item, recipeType, recipe, recipeOutput); + + registerBlockHandler(getID(), (p, b, stack, reason) -> { + BlockMenu inv = BlockStorage.getInventory(b); + + if (inv != null) { + inv.dropItems(b.getLocation(), SLOTS); + } + + return true; + }); + } + + protected abstract int[] getBorder(); + + @Override + protected void onPlace(BlockPlaceEvent e) { + Block b = e.getBlock(); + BlockStorage.addBlockInfo(b, "index", "0"); + BlockStorage.addBlockInfo(b, "filter-type", "whitelist"); + BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(true)); + BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(false)); + } + + @Override + protected void createBorder(BlockMenuPreset preset) { + for (int i : getBorder()) { + preset.addItem(i, new CustomItem(Material.CYAN_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler()); + } + + preset.addItem(2, new CustomItem(Material.PAPER, "&3Items", "", "&bPut in all Items you want to", "&bblacklist/whitelist"), ChestMenuUtils.getEmptyClickHandler()); + } + + @Override + protected void updateBlockMenu(BlockMenu menu, Block b) { + String filterType = BlockStorage.getLocationInfo(b.getLocation(), "filter-type"); + + if (!BlockStorage.hasBlockInfo(b) || filterType == null || filterType.equals("whitelist")) { + menu.replaceExistingItem(15, new CustomItem(Material.WHITE_WOOL, "&7Type: &rWhitelist", "", "&e> Click to change it to Blacklist")); + menu.addMenuClickHandler(15, (p, slot, item, action) -> { + BlockStorage.addBlockInfo(b, "filter-type", "blacklist"); + updateBlockMenu(menu, b); + return false; + }); + } + else { + menu.replaceExistingItem(15, new CustomItem(Material.BLACK_WOOL, "&7Type: &8Blacklist", "", "&e> Click to change it to Whitelist")); + menu.addMenuClickHandler(15, (p, slot, item, action) -> { + BlockStorage.addBlockInfo(b, "filter-type", "whitelist"); + updateBlockMenu(menu, b); + return false; + }); + } + + String durability = BlockStorage.getLocationInfo(b.getLocation(), "filter-durability"); + + if (!BlockStorage.hasBlockInfo(b) || durability == null || durability.equals(String.valueOf(false))) { + ItemStack is = new ItemStack(Material.STONE_SWORD); + ItemMeta meta = is.getItemMeta(); + meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + is.setItemMeta(meta); + + menu.replaceExistingItem(16, new CustomItem(is, "&7Include Sub-IDs/Durability: &4\u2718", "", "&e> Click to toggle whether the Durability has to match")); + menu.addMenuClickHandler(16, (p, slot, item, action) -> { + BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(true)); + updateBlockMenu(menu, b); + return false; + }); + } + else { + ItemStack is = new ItemStack(Material.GOLDEN_SWORD); + ItemMeta meta = is.getItemMeta(); + meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + ((Damageable) meta).setDamage(20); + is.setItemMeta(meta); + + menu.replaceExistingItem(16, new CustomItem(is, "&7Include Sub-IDs/Durability: &2\u2714", "", "&e> Click to toggle whether the Durability has to match")); + menu.addMenuClickHandler(16, (p, slot, item, action) -> { + BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(false)); + updateBlockMenu(menu, b); + return false; + }); + } + + String lore = BlockStorage.getLocationInfo(b.getLocation(), "filter-lore"); + + if (!BlockStorage.hasBlockInfo(b) || lore == null || lore.equals(String.valueOf(true))) { + menu.replaceExistingItem(25, new CustomItem(Material.MAP, "&7Include Lore: &2\u2714", "", "&e> Click to toggle whether the Lore has to match")); + menu.addMenuClickHandler(25, (p, slot, item, action) -> { + BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(false)); + updateBlockMenu(menu, b); + return false; + }); + } + else { + menu.replaceExistingItem(25, new CustomItem(Material.MAP, "&7Include Lore: &4\u2718", "", "&e> Click to toggle whether the Lore has to match")); + menu.addMenuClickHandler(25, (p, slot, item, action) -> { + BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(true)); + updateBlockMenu(menu, b); + return false; + }); + } + + addChannelSelector(b, menu, 41, 42, 43); + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AdvancedCargoOutputNode.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AdvancedCargoOutputNode.java index 49694f7fe..667ee068d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AdvancedCargoOutputNode.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AdvancedCargoOutputNode.java @@ -1,169 +1,22 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.cargo; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.Damageable; -import org.bukkit.inventory.meta.ItemMeta; -import io.github.thebusybiscuit.cscorelib2.item.CustomItem; -import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections; -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; -import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; -import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; -import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; -public class AdvancedCargoOutputNode extends AbstractCargoNode { +public class AdvancedCargoOutputNode extends AbstractFilterNode { private static final int[] BORDER = { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 22, 23, 24, 26, 27, 31, 32, 33, 34, 35, 36, 40, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 }; - private static final int[] SLOTS = { 19, 20, 21, 28, 29, 30, 37, 38, 39 }; - public AdvancedCargoOutputNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { - super(category, item, recipeType, recipe, recipeOutput); - - registerBlockHandler(getID(), new SlimefunBlockHandler() { - - @Override - public void onPlace(Player p, Block b, SlimefunItem item) { - BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString()); - BlockStorage.addBlockInfo(b, "index", "0"); - BlockStorage.addBlockInfo(b, FREQUENCY, "0"); - BlockStorage.addBlockInfo(b, "filter-type", "whitelist"); - BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(true)); - BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(false)); - } - - @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - BlockMenu inv = BlockStorage.getInventory(b); - - if (inv != null) { - for (int slot : SLOTS) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - } - return true; - } - }); + public AdvancedCargoOutputNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { + super(category, item, recipeType, recipe, null); } @Override - protected void createBorder(BlockMenuPreset preset) { - for (int i : BORDER) { - preset.addItem(i, new CustomItem(Material.CYAN_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler()); - } - - preset.addItem(2, new CustomItem(Material.PAPER, "&3Items", "", "&bPut in all Items you want to", "&bblacklist/whitelist"), ChestMenuUtils.getEmptyClickHandler()); - } - - @Override - protected void updateBlockMenu(BlockMenu menu, Block b) { - if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "filter-type") == null || BlockStorage.getLocationInfo(b.getLocation(), "filter-type").equals("whitelist")) { - menu.replaceExistingItem(15, new CustomItem(Material.WHITE_WOOL, "&7Type: &rWhitelist", "", "&e> Click to change it to Blacklist")); - menu.addMenuClickHandler(15, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "filter-type", "blacklist"); - updateBlockMenu(menu, b); - return false; - }); - } - else { - menu.replaceExistingItem(15, new CustomItem(Material.BLACK_WOOL, "&7Type: &8Blacklist", "", "&e> Click to change it to Whitelist")); - menu.addMenuClickHandler(15, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "filter-type", "whitelist"); - updateBlockMenu(menu, b); - return false; - }); - } - - if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "filter-durability") == null || BlockStorage.getLocationInfo(b.getLocation(), "filter-durability").equals(String.valueOf(false))) { - menu.replaceExistingItem(16, new CustomItem(Material.STONE_SWORD, "&7Include Sub-IDs/Durability: &4\u2718", "", "&e> Click to toggle whether the Durability has to match")); - menu.addMenuClickHandler(16, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(true)); - updateBlockMenu(menu, b); - return false; - }); - } - else { - ItemStack is = new ItemStack(Material.GOLDEN_SWORD); - Damageable dmg = (Damageable) is.getItemMeta(); - dmg.setDamage(20); - is.setItemMeta((ItemMeta) dmg); - - menu.replaceExistingItem(16, new CustomItem(is, "&7Include Sub-IDs/Durability: &2\u2714", "", "&e> Click to toggle whether the Durability has to match")); - menu.addMenuClickHandler(16, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(false)); - updateBlockMenu(menu, b); - return false; - }); - } - - if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "filter-lore") == null || BlockStorage.getLocationInfo(b.getLocation(), "filter-lore").equals(String.valueOf(true))) { - menu.replaceExistingItem(25, new CustomItem(Material.MAP, "&7Include Lore: &2\u2714", "", "&e> Click to toggle whether the Lore has to match")); - menu.addMenuClickHandler(25, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(false)); - updateBlockMenu(menu, b); - return false; - }); - } - else { - menu.replaceExistingItem(25, new CustomItem(Material.MAP, "&7Include Lore: &4\u2718", "", "&e> Click to toggle whether the Lore has to match")); - menu.addMenuClickHandler(25, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(true)); - updateBlockMenu(menu, b); - return false; - }); - } - - menu.replaceExistingItem(41, new CustomItem(SlimefunUtils.getCustomHead("f2599bd986659b8ce2c4988525c94e19ddd39fad08a38284a197f1b70675acc"), "&bChannel", "", "&e> Click to decrease the Channel ID by 1")); - menu.addMenuClickHandler(41, (p, slot, item, action) -> { - int channel = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) - 1; - if (channel < 0) { - if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) channel = 16; - else channel = 15; - } - BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channel)); - updateBlockMenu(menu, b); - return false; - }); - - int channel = ((!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY) == null) ? 0 : (Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)))); - - if (channel == 16) { - menu.replaceExistingItem(42, new CustomItem(SlimefunUtils.getCustomHead("7a44ff3a5f49c69cab676bad8d98a063fa78cfa61916fdef3e267557fec18283"), "&bChannel ID: &3" + (channel + 1))); - menu.addMenuClickHandler(42, ChestMenuUtils.getEmptyClickHandler()); - } - else { - menu.replaceExistingItem(42, new CustomItem(MaterialCollections.getAllWoolColors().get(channel), "&bChannel ID: &3" + (channel + 1))); - menu.addMenuClickHandler(42, ChestMenuUtils.getEmptyClickHandler()); - } - - menu.replaceExistingItem(43, new CustomItem(SlimefunUtils.getCustomHead("c2f910c47da042e4aa28af6cc81cf48ac6caf37dab35f88db993accb9dfe516"), "&bChannel", "", "&e> Click to increase the Channel ID by 1")); - menu.addMenuClickHandler(43, (p, slot, item, action) -> { - int channeln = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) + 1; - - if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) { - if (channeln > 16) channeln = 0; - } - else { - if (channeln > 15) channeln = 0; - } - - BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channeln)); - updateBlockMenu(menu, b); - return false; - }); + protected int[] getBorder() { + return BORDER; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoInputNode.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoInputNode.java index 3d576c435..f0876b835 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoInputNode.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoInputNode.java @@ -1,117 +1,44 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.cargo; -import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.Damageable; -import org.bukkit.inventory.meta.ItemMeta; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; -import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections; -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; +import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; -import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; -public class CargoInputNode extends AbstractCargoNode { +public class CargoInputNode extends AbstractFilterNode { private static final int[] BORDER = { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 22, 23, 26, 27, 31, 32, 33, 34, 35, 36, 40, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 }; - private static final int[] SLOTS = { 19, 20, 21, 28, 29, 30, 37, 38, 39 }; public CargoInputNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { super(category, item, recipeType, recipe, recipeOutput); - - registerBlockHandler(getID(), new SlimefunBlockHandler() { - - @Override - public void onPlace(Player p, Block b, SlimefunItem item) { - BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString()); - BlockStorage.addBlockInfo(b, "index", "0"); - BlockStorage.addBlockInfo(b, FREQUENCY, "0"); - BlockStorage.addBlockInfo(b, "filter-type", "whitelist"); - BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(true)); - BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(false)); - BlockStorage.addBlockInfo(b, "round-robin", String.valueOf(false)); - } - - @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - BlockMenu inv = BlockStorage.getInventory(b); - - if (inv != null) { - for (int slot : SLOTS) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - } - return true; - } - }); } @Override - protected void createBorder(BlockMenuPreset preset) { - for (int i : BORDER) { - preset.addItem(i, new CustomItem(Material.CYAN_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler()); - } + protected int[] getBorder() { + return BORDER; + } - preset.addItem(2, new CustomItem(Material.PAPER, "&3Items", "", "&bPut in all Items you want to", "&bblacklist/whitelist"), ChestMenuUtils.getEmptyClickHandler()); + @Override + protected void onPlace(BlockPlaceEvent e) { + super.onPlace(e); + BlockStorage.addBlockInfo(e.getBlock(), "round-robin", String.valueOf(false)); } @Override protected void updateBlockMenu(BlockMenu menu, Block b) { - if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "filter-type") == null || BlockStorage.getLocationInfo(b.getLocation(), "filter-type").equals("whitelist")) { - menu.replaceExistingItem(15, new CustomItem(Material.WHITE_WOOL, "&7Type: &rWhitelist", "", "&e> Click to change it to Blacklist")); - menu.addMenuClickHandler(15, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "filter-type", "blacklist"); - updateBlockMenu(menu, b); - return false; - }); - } - else { - menu.replaceExistingItem(15, new CustomItem(Material.BLACK_WOOL, "&7Type: &8Blacklist", "", "&e> Click to change it to Whitelist")); - menu.addMenuClickHandler(15, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "filter-type", "whitelist"); - updateBlockMenu(menu, b); - return false; - }); - } + super.updateBlockMenu(menu, b); - if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "filter-durability") == null || BlockStorage.getLocationInfo(b.getLocation(), "filter-durability").equals(String.valueOf(false))) { - menu.replaceExistingItem(16, new CustomItem(Material.STONE_SWORD, "&7Include Sub-IDs/Durability: &4\u2718", "", "&e> Click to toggle whether the Durability has to match")); - menu.addMenuClickHandler(16, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(true)); - updateBlockMenu(menu, b); - return false; - }); - } - else { - ItemStack is = new ItemStack(Material.GOLDEN_SWORD); - Damageable dmg = (Damageable) is.getItemMeta(); - dmg.setDamage(20); - is.setItemMeta((ItemMeta) dmg); - - menu.replaceExistingItem(16, new CustomItem(is, "&7Include Sub-IDs/Durability: &2\u2714", "", "&e> Click to toggle whether the Durability has to match")); - menu.addMenuClickHandler(16, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(false)); - updateBlockMenu(menu, b); - return false; - }); - } - - if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "round-robin") == null || BlockStorage.getLocationInfo(b.getLocation(), "round-robin").equals(String.valueOf(false))) { - menu.replaceExistingItem(24, new CustomItem(SlimefunUtils.getCustomHead("d78f2b7e5e75639ea7fb796c35d364c4df28b4243e66b76277aadcd6261337"), "&7Round-Robin Mode: &4\u2718", "", "&e> Click to enable Round Robin Mode", "&e(Items will be equally distributed on the Channel)")); + String roundRobinMode = BlockStorage.getLocationInfo(b.getLocation(), "round-robin"); + if (!BlockStorage.hasBlockInfo(b) || roundRobinMode == null || roundRobinMode.equals(String.valueOf(false))) { + menu.replaceExistingItem(24, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.ENERGY_REGULATOR.getTexture()), "&7Round-Robin Mode: &4\u2718", "", "&e> Click to enable Round Robin Mode", "&e(Items will be equally distributed on the Channel)")); menu.addMenuClickHandler(24, (p, slot, item, action) -> { BlockStorage.addBlockInfo(b, "round-robin", String.valueOf(true)); updateBlockMenu(menu, b); @@ -119,69 +46,13 @@ public class CargoInputNode extends AbstractCargoNode { }); } else { - menu.replaceExistingItem(24, new CustomItem(SlimefunUtils.getCustomHead("d78f2b7e5e75639ea7fb796c35d364c4df28b4243e66b76277aadcd6261337"), "&7Round-Robin Mode: &2\u2714", "", "&e> Click to disable Round Robin Mode", "&e(Items will be equally distributed on the Channel)")); + menu.replaceExistingItem(24, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.ENERGY_REGULATOR.getTexture()), "&7Round-Robin Mode: &2\u2714", "", "&e> Click to disable Round Robin Mode", "&e(Items will be equally distributed on the Channel)")); menu.addMenuClickHandler(24, (p, slot, item, action) -> { BlockStorage.addBlockInfo(b, "round-robin", String.valueOf(false)); updateBlockMenu(menu, b); return false; }); } - - if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "filter-lore") == null || BlockStorage.getLocationInfo(b.getLocation(), "filter-lore").equals(String.valueOf(true))) { - menu.replaceExistingItem(25, new CustomItem(Material.MAP, "&7Include Lore: &2\u2714", "", "&e> Click to toggle whether the Lore has to match")); - menu.addMenuClickHandler(25, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(false)); - updateBlockMenu(menu, b); - return false; - }); - } - else { - menu.replaceExistingItem(25, new CustomItem(Material.MAP, "&7Include Lore: &4\u2718", "", "&e> Click to toggle whether the Lore has to match")); - menu.addMenuClickHandler(25, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(true)); - updateBlockMenu(menu, b); - return false; - }); - } - - menu.replaceExistingItem(41, new CustomItem(SlimefunUtils.getCustomHead("f2599bd986659b8ce2c4988525c94e19ddd39fad08a38284a197f1b70675acc"), "&bChannel", "", "&e> Click to decrease the Channel ID by 1")); - menu.addMenuClickHandler(41, (p, slot, item, action) -> { - int channel = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) - 1; - if (channel < 0) { - if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) channel = 16; - else channel = 15; - } - BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channel)); - updateBlockMenu(menu, b); - return false; - }); - - int channel = ((!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY) == null) ? 0 : (Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)))); - - if (channel == 16) { - menu.replaceExistingItem(42, new CustomItem(SlimefunUtils.getCustomHead("7a44ff3a5f49c69cab676bad8d98a063fa78cfa61916fdef3e267557fec18283"), "&bChannel ID: &3" + (channel + 1))); - menu.addMenuClickHandler(42, ChestMenuUtils.getEmptyClickHandler()); - } - else { - menu.replaceExistingItem(42, new CustomItem(new ItemStack(MaterialCollections.getAllWoolColors().get(channel)), "&bChannel ID: &3" + (channel + 1))); - menu.addMenuClickHandler(42, ChestMenuUtils.getEmptyClickHandler()); - } - - menu.replaceExistingItem(43, new CustomItem(SlimefunUtils.getCustomHead("c2f910c47da042e4aa28af6cc81cf48ac6caf37dab35f88db993accb9dfe516"), "&bChannel", "", "&e> Click to increase the Channel ID by 1")); - menu.addMenuClickHandler(43, (p, slot, item, action) -> { - int channeln = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) + 1; - - if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) { - if (channeln > 16) channeln = 0; - } - else { - if (channeln > 15) channeln = 0; - } - - BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channeln)); - updateBlockMenu(menu, b); - return false; - }); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoOutputNode.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoOutputNode.java index 668d55141..31ea4dcd8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoOutputNode.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoOutputNode.java @@ -2,20 +2,13 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.cargo; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; -import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections; -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; -import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; -import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; @@ -26,20 +19,11 @@ public class CargoOutputNode extends AbstractCargoNode { public CargoOutputNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { super(category, item, recipeType, recipe, recipeOutput); + } - registerBlockHandler(getID(), new SlimefunBlockHandler() { - - @Override - public void onPlace(Player p, Block b, SlimefunItem item) { - BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString()); - BlockStorage.addBlockInfo(b, FREQUENCY, "0"); - } - - @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - return true; - } - }); + @Override + protected void onPlace(BlockPlaceEvent e) { + // We only require the default values } @Override @@ -51,46 +35,7 @@ public class CargoOutputNode extends AbstractCargoNode { @Override protected void updateBlockMenu(BlockMenu menu, Block b) { - menu.replaceExistingItem(12, new CustomItem(SlimefunUtils.getCustomHead("f2599bd986659b8ce2c4988525c94e19ddd39fad08a38284a197f1b70675acc"), "&bChannel", "", "&e> Click to decrease the Channel ID by 1")); - menu.addMenuClickHandler(12, (p, slot, item, action) -> { - int channel = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) - 1; - - if (channel < 0) { - if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) channel = 16; - else channel = 15; - } - - BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channel)); - updateBlockMenu(menu, b); - return false; - }); - - int channel = ((!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY) == null) ? 0 : (Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)))); - - if (channel == 16) { - menu.replaceExistingItem(13, new CustomItem(SlimefunUtils.getCustomHead("7a44ff3a5f49c69cab676bad8d98a063fa78cfa61916fdef3e267557fec18283"), "&bChannel ID: &3" + (channel + 1))); - menu.addMenuClickHandler(13, ChestMenuUtils.getEmptyClickHandler()); - } - else { - menu.replaceExistingItem(13, new CustomItem(MaterialCollections.getAllWoolColors().get(channel), "&bChannel ID: &3" + (channel + 1))); - menu.addMenuClickHandler(13, ChestMenuUtils.getEmptyClickHandler()); - } - - menu.replaceExistingItem(14, new CustomItem(SlimefunUtils.getCustomHead("c2f910c47da042e4aa28af6cc81cf48ac6caf37dab35f88db993accb9dfe516"), "&bChannel", "", "&e> Click to increase the Channel ID by 1")); - menu.addMenuClickHandler(14, (p, slot, item, action) -> { - int channeln = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) + 1; - - if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) { - if (channeln > 16) channeln = 0; - } - else { - if (channeln > 15) channeln = 0; - } - - BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channeln)); - updateBlockMenu(menu, b); - return false; - }); + addChannelSelector(b, menu, 12, 13, 14); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/ReactorAccessPort.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/ReactorAccessPort.java index 899b8b937..22420ca5a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/ReactorAccessPort.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/ReactorAccessPort.java @@ -102,27 +102,11 @@ public class ReactorAccessPort extends SlimefunItem { BlockMenu inv = BlockStorage.getInventory(b); if (inv != null) { - for (int slot : getFuelSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - - for (int slot : getCoolantSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - - for (int slot : getOutputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } + inv.dropItems(b.getLocation(), getFuelSlots()); + inv.dropItems(b.getLocation(), getCoolantSlots()); + inv.dropItems(b.getLocation(), getOutputSlots()); } + return true; }); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/AbstractEnergyProvider.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/AbstractEnergyProvider.java index b6f9252b5..f797578c2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/AbstractEnergyProvider.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/AbstractEnergyProvider.java @@ -5,7 +5,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.bukkit.Location; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -17,14 +16,12 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor; import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; -import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock; -import me.mrCookieSlime.Slimefun.Objects.handlers.GeneratorTicker; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; /** @@ -32,6 +29,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; * * @author TheBusyBiscuit * + * @see EnergyNetProvider * @see AGenerator * @see Reactor * @@ -81,56 +79,12 @@ public abstract class AbstractEnergyProvider extends SlimefunItem implements Inv return EnergyNetComponentType.GENERATOR; } - /** - * @deprecated Please implement the methods - * {@link #getGeneratedOutput(org.bukkit.Location, me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config)} - * and {@link #willExplode(org.bukkit.Location, me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config)} - * instead - * - * @return A {@link GeneratorTicker} - */ - @Deprecated - protected GeneratorTicker onTick() { - return null; - } - - @Override - public int getGeneratedOutput(Location l, Config data) { - if (generatorTicker != null) { - return (int) generatorTicker.generateEnergy(l, this, data); - } - else { - return 0; - } - } - - @Override - public boolean willExplode(Location l, Config data) { - if (generatorTicker != null) { - return generatorTicker.explode(l); - } - else { - return false; - } - } - - @Override - public void preRegister() { - super.preRegister(); - - GeneratorTicker ticker = onTick(); - - if (ticker != null) { - addItemHandler(ticker); - } - } - public void registerFuel(MachineFuel fuel) { fuelTypes.add(fuel); } public Set getFuelTypes() { - return this.fuelTypes; + return fuelTypes; } @Override diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyRegulator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyRegulator.java index 0926180f2..f11334f97 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyRegulator.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyRegulator.java @@ -1,18 +1,17 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric; import org.bukkit.block.Block; -import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet; import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; @@ -31,24 +30,26 @@ public class EnergyRegulator extends SlimefunItem { public EnergyRegulator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); - SlimefunItem.registerBlockHandler(getID(), new SlimefunBlockHandler() { - - @Override - public void onPlace(Player p, Block b, SlimefunItem item) { - // Spawn the hologram - SimpleHologram.update(b, "&7Connecting..."); - } - - @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - SimpleHologram.remove(b); - return true; - } + SlimefunItem.registerBlockHandler(getID(), (p, b, stack, reason) -> { + SimpleHologram.remove(b); + return true; }); } + private BlockPlaceHandler onPlace() { + return new BlockPlaceHandler(false) { + + @Override + public void onPlayerPlace(BlockPlaceEvent e) { + SimpleHologram.update(e.getBlock(), "&7Connecting..."); + } + + }; + } + @Override public void preRegister() { + addItemHandler(onPlace()); addItemHandler(new BlockTicker() { @Override @@ -58,9 +59,13 @@ public class EnergyRegulator extends SlimefunItem { @Override public void tick(Block b, SlimefunItem item, Config data) { - EnergyNet.getNetworkFromLocationOrCreate(b.getLocation()).tick(b); + EnergyRegulator.this.tick(b); } }); } + private void tick(Block b) { + EnergyNet.getNetworkFromLocationOrCreate(b.getLocation()).tick(b); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiTool.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiTool.java index 4f73938a6..b9cd1696b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiTool.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiTool.java @@ -11,8 +11,9 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable; -import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; +import io.github.thebusybiscuit.slimefun4.core.handlers.EntityInteractHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; +import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; @@ -42,6 +43,21 @@ public class MultiTool extends SlimefunItem implements Rechargeable { return capacity; } + private int nextIndex(int i) { + int index = i; + + do { + index++; + + if (index >= modes.size()) { + index = 0; + } + } + while (index != i && !modes.get(index).isEnabled()); + + return index; + } + protected ItemUseHandler getItemUseHandler() { return e -> { Player p = e.getPlayer(); @@ -64,35 +80,32 @@ public class MultiTool extends SlimefunItem implements Rechargeable { SlimefunItem selectedItem = modes.get(index).getItem(); String itemName = selectedItem != null ? selectedItem.getItemName() : "Unknown"; - SlimefunPlugin.getLocalization().sendMessage(p, "messages.mode-change", true, msg -> msg.replace("%device%", "Multi Tool").replace("%mode%", ChatColor.stripColor(itemName))); + SlimefunPlugin.getLocalization().sendMessage(p, "messages.multi-tool.mode-change", true, msg -> msg.replace("%device%", "Multi Tool").replace("%mode%", ChatColor.stripColor(itemName))); selectedMode.put(p.getUniqueId(), index); } }; } - private int nextIndex(int i) { - int index = i; - - do { - index++; - - if (index >= modes.size()) { - index = 0; - } - } - while (index != i && !modes.get(index).isEnabled()); - - return index; + private ToolUseHandler getToolUseHandler() { + return (e, tool, fortune, drops) -> { + SlimefunPlugin.getLocalization().sendMessage(e.getPlayer(), "messages.multi-tool.not-shears"); + e.setCancelled(true); + }; } - private BlockBreakHandler getBlockBreakHandler() { - return (e, item, fortune, drops) -> { - if (isItem(item)) { + private EntityInteractHandler getEntityInteractionHandler() { + return (e, item, offhand) -> { + // Fixes #2217 - Prevent them from being used to shear entities + switch (e.getRightClicked().getType()) { + case MUSHROOM_COW: + case SHEEP: + case SNOWMAN: + SlimefunPlugin.getLocalization().sendMessage(e.getPlayer(), "messages.multi-tool.not-shears"); e.setCancelled(true); - return true; + break; + default: + break; } - - return false; }; } @@ -101,7 +114,8 @@ public class MultiTool extends SlimefunItem implements Rechargeable { super.preRegister(); addItemHandler(getItemUseHandler()); - addItemHandler(getBlockBreakHandler()); + addItemHandler(getToolUseHandler()); + addItemHandler(getEntityInteractionHandler()); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/LavaGenerator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/LavaGenerator.java index 8d7f5df9e..89470aa34 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/LavaGenerator.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/LavaGenerator.java @@ -11,23 +11,23 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; public abstract class LavaGenerator extends AGenerator { - public LavaGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { - super(category, item, recipeType, recipe); - } - + public LavaGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { + super(category, item, recipeType, recipe); + } + @Override protected void registerDefaultFuelTypes() { - registerFuel(new MachineFuel(40, new ItemStack(Material.LAVA_BUCKET))); - } + registerFuel(new MachineFuel(40, new ItemStack(Material.LAVA_BUCKET))); + } - @Override - public ItemStack getProgressBar() { - return new ItemStack(Material.FLINT_AND_STEEL); - } + @Override + public ItemStack getProgressBar() { + return new ItemStack(Material.FLINT_AND_STEEL); + } - @Override - public String getInventoryTitle() { - return "&4Lava Generator"; - } + @Override + public String getInventoryTitle() { + return "&4Lava Generator"; + } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AbstractEntityAssembler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AbstractEntityAssembler.java index 083d9a741..8b5080df7 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AbstractEntityAssembler.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AbstractEntityAssembler.java @@ -1,16 +1,21 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines; +import org.bukkit.Effect; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.entity.EntityType; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockEvent; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; +import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; @@ -19,7 +24,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; @@ -41,7 +45,10 @@ import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow; * @see IronGolemAssembler * */ -public abstract class AbstractEntityAssembler extends SimpleSlimefunItem implements EnergyNetComponent { +public abstract class AbstractEntityAssembler extends SimpleSlimefunItem implements EnergyNetComponent { + + private static final String KEY_ENABLED = "enabled"; + private static final String KEY_OFFSET = "offset"; private final int[] border = { 0, 2, 3, 4, 5, 6, 8, 12, 14, 21, 23, 30, 32, 39, 40, 41 }; private final int[] inputSlots = { 19, 28, 25, 34 }; @@ -78,32 +85,7 @@ public abstract class AbstractEntityAssembler extends SimpleSlimefunItem Click to enable this Machine")); - menu.addMenuClickHandler(22, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "enabled", String.valueOf(true)); - newInstance(menu, b); - return false; - }); - } - else { - menu.replaceExistingItem(22, new CustomItem(Material.REDSTONE, "&7Enabled: &2\u2714", "", "&e> Click to disable this Machine")); - menu.addMenuClickHandler(22, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, "enabled", String.valueOf(false)); - newInstance(menu, b); - return false; - }); - } - - double offset = (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "offset") == null) ? 3.0F : Double.valueOf(BlockStorage.getLocationInfo(b.getLocation(), "offset")); - - menu.replaceExistingItem(31, new CustomItem(Material.PISTON, "&7Offset: &3" + offset + " Block(s)", "", "&rLeft Click: &7+0.1", "&rRight Click: &7-0.1")); - menu.addMenuClickHandler(31, (p, slot, item, action) -> { - double offsetv = DoubleHandler.fixDouble(Double.valueOf(BlockStorage.getLocationInfo(b.getLocation(), "offset")) + (action.isRightClicked() ? -0.1F : 0.1F)); - BlockStorage.addBlockInfo(b, "offset", String.valueOf(offsetv)); - newInstance(menu, b); - return false; - }); + updateBlockInventory(menu, b); } @Override @@ -137,40 +119,69 @@ public abstract class AbstractEntityAssembler extends SimpleSlimefunItem { + if (reason == UnregisterReason.EXPLODE) { + return false; + } + + BlockMenu inv = BlockStorage.getInventory(b); + + if (inv != null) { + inv.dropItems(b.getLocation(), headSlots); + inv.dropItems(b.getLocation(), bodySlots); + } + + return true; + }); + } + + private BlockPlaceHandler onPlace() { + return new BlockPlaceHandler(true) { @Override - public void onPlace(Player p, Block b, SlimefunItem item) { - BlockStorage.addBlockInfo(b, "offset", "3.0"); - BlockStorage.addBlockInfo(b, "enabled", String.valueOf(false)); + public void onPlayerPlace(BlockPlaceEvent e) { + onPlace(e); } @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - if (reason == UnregisterReason.EXPLODE) { - return false; - } - - BlockMenu inv = BlockStorage.getInventory(b); - - if (inv != null) { - for (int slot : bodySlots) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - - for (int slot : headSlots) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - } - - return true; + public void onBlockPlacerPlace(BlockPlacerPlaceEvent e) { + onPlace(e); } + + private void onPlace(BlockEvent e) { + BlockStorage.addBlockInfo(e.getBlock(), KEY_OFFSET, "3.0"); + BlockStorage.addBlockInfo(e.getBlock(), KEY_ENABLED, String.valueOf(false)); + } + }; + } + + private void updateBlockInventory(BlockMenu menu, Block b) { + if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), KEY_ENABLED) == null || BlockStorage.getLocationInfo(b.getLocation(), KEY_ENABLED).equals(String.valueOf(false))) { + menu.replaceExistingItem(22, new CustomItem(Material.GUNPOWDER, "&7Enabled: &4\u2718", "", "&e> Click to enable this Machine")); + menu.addMenuClickHandler(22, (p, slot, item, action) -> { + BlockStorage.addBlockInfo(b, KEY_ENABLED, String.valueOf(true)); + updateBlockInventory(menu, b); + return false; + }); + } + else { + menu.replaceExistingItem(22, new CustomItem(Material.REDSTONE, "&7Enabled: &2\u2714", "", "&e> Click to disable this Machine")); + menu.addMenuClickHandler(22, (p, slot, item, action) -> { + BlockStorage.addBlockInfo(b, KEY_ENABLED, String.valueOf(false)); + updateBlockInventory(menu, b); + return false; + }); + } + + double offset = (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), KEY_OFFSET) == null) ? 3.0F : Double.valueOf(BlockStorage.getLocationInfo(b.getLocation(), KEY_OFFSET)); + + menu.replaceExistingItem(31, new CustomItem(Material.PISTON, "&7Offset: &3" + offset + " Block(s)", "", "&fLeft Click: &7+0.1", "&fRight Click: &7-0.1")); + menu.addMenuClickHandler(31, (p, slot, item, action) -> { + double offsetv = DoubleHandler.fixDouble(Double.valueOf(BlockStorage.getLocationInfo(b.getLocation(), KEY_OFFSET)) + (action.isRightClicked() ? -0.1F : 0.1F)); + BlockStorage.addBlockInfo(b, KEY_OFFSET, String.valueOf(offsetv)); + updateBlockInventory(menu, b); + return false; }); } @@ -180,7 +191,7 @@ public abstract class AbstractEntityAssembler extends SimpleSlimefunItem { Location loc = new Location(b.getWorld(), b.getX() + 0.5D, b.getY() + offset, b.getZ() + 0.5D); - b.getWorld().spawnEntity(loc, EntityType.WITHER); + spawnEntity(loc); + + b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, getHead().getType()); }); } } @@ -217,15 +230,13 @@ public abstract class AbstractEntityAssembler extends SimpleSlimefunItem required) { + if (found >= item.getAmount()) { return true; } } @@ -239,7 +250,7 @@ public abstract class AbstractEntityAssembler extends SimpleSlimefunItem= bodyCount) { @@ -254,7 +265,7 @@ public abstract class AbstractEntityAssembler extends SimpleSlimefunItem= headCount) { @@ -270,9 +281,9 @@ public abstract class AbstractEntityAssembler extends SimpleSlimefunItem recipeList = new ArrayList<>(); + private List recipeList; public AutoDrier(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); + } + @Override + protected void registerDefaultRecipes() { + recipeList = new ArrayList<>(); recipeList.add(new ItemStack(Material.ROTTEN_FLESH)); recipeList.add(new ItemStack(Material.LEATHER)); @@ -49,11 +45,11 @@ public class AutoDrier extends AContainer implements RecipeDisplayItem { recipeList.add(new ItemStack(Material.POTION)); recipeList.add(new ItemStack(Material.GLASS_BOTTLE)); - recipeList.add(new ItemStack(Material.OAK_SAPLING)); - recipeList.add(new ItemStack(Material.STICK, 2)); + recipeList.add(new ItemStack(Material.SPLASH_POTION)); + recipeList.add(new ItemStack(Material.GLASS_BOTTLE)); - recipeList.add(new ItemStack(Material.OAK_LEAVES)); - recipeList.add(new ItemStack(Material.STICK)); + recipeList.add(new ItemStack(Material.LINGERING_POTION)); + recipeList.add(new ItemStack(Material.GLASS_BOTTLE)); recipeList.add(new ItemStack(Material.WATER_BUCKET)); recipeList.add(new ItemStack(Material.BUCKET)); @@ -78,6 +74,21 @@ public class AutoDrier extends AContainer implements RecipeDisplayItem { recipeList.add(new ItemStack(Material.COOKED_SALMON)); recipeList.add(SlimefunItems.FISH_JERKY); + + for (Material sapling : Tag.SAPLINGS.getValues()) { + recipeList.add(new ItemStack(sapling)); + recipeList.add(new ItemStack(Material.STICK, 2)); + } + + for (Material leaves : Tag.LEAVES.getValues()) { + recipeList.add(new ItemStack(leaves)); + recipeList.add(new ItemStack(Material.STICK)); + } + + // Now convert them to machine recipes + for (int i = 0; i < recipeList.size(); i += 2) { + registerRecipe(6, recipeList.get(i), recipeList.get(i + 1)); + } } @Override @@ -95,78 +106,6 @@ public class AutoDrier extends AContainer implements RecipeDisplayItem { return recipeList; } - @Override - protected void tick(Block b) { - BlockMenu menu = BlockStorage.getInventory(b); - - if (isProcessing(b)) { - int timeleft = progress.get(b); - if (timeleft > 0) { - ChestMenuUtils.updateProgressbar(menu, 22, timeleft, processing.get(b).getTicks(), getProgressBar()); - - if (ChargableBlock.getCharge(b) < getEnergyConsumption()) { - return; - } - - ChargableBlock.addCharge(b, -getEnergyConsumption()); - progress.put(b, timeleft - 1); - } - else { - menu.replaceExistingItem(22, new CustomItem(new ItemStack(Material.BLACK_STAINED_GLASS_PANE), " ")); - menu.pushItem(processing.get(b).getOutput()[0], getOutputSlots()); - - progress.remove(b); - processing.remove(b); - } - } - else { - MachineRecipe r = null; - int inputSlot = -1; - - for (int slot : getInputSlots()) { - ItemStack item = menu.getItemInSlot(slot); - if (item != null) { - ItemStack output = getOutput(item); - - if (output != null) { - r = new MachineRecipe(6, new ItemStack[] { item }, new ItemStack[] { output.clone() }); - inputSlot = slot; - break; - } - } - } - - if (r != null) { - if (inputSlot == -1) return; - if (!menu.fits(r.getOutput()[0], getOutputSlots())) return; - - menu.consumeItem(inputSlot); - processing.put(b, r); - progress.put(b, r.getTicks()); - } - } - } - - private ItemStack getOutput(ItemStack item) { - for (int i = 0; i < recipeList.size(); i += 2) { - if (SlimefunUtils.isItemSimilar(item, recipeList.get(i), true)) { - return recipeList.get(i + 1); - } - } - - if (Tag.SAPLINGS.isTagged(item.getType())) { - return new ItemStack(Material.STICK, 2); - } - else if (Tag.LEAVES.isTagged(item.getType())) { - return new ItemStack(Material.STICK, 1); - } - else if (item.getType() == Material.SPLASH_POTION || item.getType() == Material.LINGERING_POTION) { - return new ItemStack(Material.GLASS_BOTTLE); - } - - return null; - } - @Override public int getEnergyConsumption() { return 5; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutomatedCraftingChamber.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutomatedCraftingChamber.java index 43348e0aa..13d61ab95 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutomatedCraftingChamber.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutomatedCraftingChamber.java @@ -8,12 +8,15 @@ import java.util.List; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; +import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; @@ -23,9 +26,7 @@ import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.Item.CustomItemSeriali import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.Item.CustomItemSerializer.ItemFlag; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.api.BlockStorage; @@ -113,38 +114,34 @@ public abstract class AutomatedCraftingChamber extends SlimefunItem implements I } }; - registerBlockHandler(getID(), new SlimefunBlockHandler() { + addItemHandler(onPlace()); + registerBlockHandler(getID(), (p, b, stack, reason) -> { + BlockMenu inv = BlockStorage.getInventory(b); - @Override - public void onPlace(Player p, Block b, SlimefunItem item) { - BlockStorage.addBlockInfo(b, "enabled", String.valueOf(false)); + if (inv != null) { + inv.dropItems(b.getLocation(), getInputSlots()); + inv.dropItems(b.getLocation(), getOutputSlots()); } - @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - BlockMenu inv = BlockStorage.getInventory(b); - - if (inv != null) { - for (int slot : getInputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - - for (int slot : getOutputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - } - - return true; - } + return true; }); } + private BlockPlaceHandler onPlace() { + return new BlockPlaceHandler(true) { + + @Override + public void onPlayerPlace(BlockPlaceEvent e) { + BlockStorage.addBlockInfo(e.getBlock(), "enabled", String.valueOf(false)); + } + + @Override + public void onBlockPlacerPlace(BlockPlacerPlaceEvent e) { + BlockStorage.addBlockInfo(e.getBlock(), "enabled", String.valueOf(false)); + } + }; + } + private Comparator compareSlots(DirtyChestMenu menu) { return (slot1, slot2) -> menu.getItemInSlot(slot1).getAmount() - menu.getItemInSlot(slot2).getAmount(); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/CropGrowthAccelerator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/CropGrowthAccelerator.java index dc5bab316..f48be3bc8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/CropGrowthAccelerator.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/CropGrowthAccelerator.java @@ -1,6 +1,6 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines; -import java.util.HashSet; +import java.util.EnumSet; import java.util.Set; import org.bukkit.Material; @@ -33,7 +33,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; public abstract class CropGrowthAccelerator extends SlimefunItem implements InventoryBlock, EnergyNetComponent { private final int[] border = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }; - private final Set crops = new HashSet<>(); + private final Set crops = EnumSet.noneOf(Material.class); // We wanna strip the Slimefun Item id here private static final ItemStack organicFertilizer = new ItemStackWrapper(SlimefunItems.FERTILIZER); @@ -58,13 +58,9 @@ public abstract class CropGrowthAccelerator extends SlimefunItem implements Inve BlockMenu inv = BlockStorage.getInventory(b); if (inv != null) { - for (int slot : getInputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } + inv.dropItems(b.getLocation(), getInputSlots()); } + return true; }); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricPress.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricPress.java index 94a1c3858..a945983cc 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricPress.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricPress.java @@ -48,7 +48,9 @@ public abstract class ElectricPress extends AContainer implements RecipeDisplayI addRecipe(4, new ItemStack(Material.IRON_NUGGET, 9), new ItemStack(Material.IRON_INGOT)); addRecipe(4, new ItemStack(Material.GOLD_NUGGET, 9), new ItemStack(Material.GOLD_INGOT)); addRecipe(4, new ItemStack(Material.COAL, 9), new ItemStack(Material.COAL_BLOCK)); - + addRecipe(4, new ItemStack(Material.SAND, 4), new ItemStack(Material.SANDSTONE)); + addRecipe(4, new ItemStack(Material.RED_SAND, 4), new ItemStack(Material.RED_SANDSTONE)); + addRecipe(5, new ItemStack(Material.IRON_INGOT, 9), new ItemStack(Material.IRON_BLOCK)); addRecipe(5, new ItemStack(Material.GOLD_INGOT, 9), new ItemStack(Material.GOLD_BLOCK)); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java index ee61a684a..df30e46ca 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java @@ -98,19 +98,8 @@ public abstract class ElectricSmeltery extends AContainer { BlockMenu inv = BlockStorage.getInventory(b); if (inv != null) { - for (int slot : getInputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - - for (int slot : getOutputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } + inv.dropItems(b.getLocation(), getInputSlots()); + inv.dropItems(b.getLocation(), getOutputSlots()); } progress.remove(b); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java index 242e4fd75..6fe0a343b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java @@ -44,6 +44,17 @@ public class FluidPump extends SimpleSlimefunItem implements Invent super(category, item, recipeType, recipe); createPreset(this, this::constructMenu); + + registerBlockHandler(getID(), (p, b, stack, reason) -> { + BlockMenu inv = BlockStorage.getInventory(b); + + if (inv != null) { + inv.dropItems(b.getLocation(), getInputSlots()); + inv.dropItems(b.getLocation(), getOutputSlots()); + } + + return true; + }); } private void constructMenu(BlockMenuPreset preset) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/IronGolemAssembler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/IronGolemAssembler.java index d5532cd3b..71426fc7d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/IronGolemAssembler.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/IronGolemAssembler.java @@ -1,10 +1,14 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines; +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.entity.IronGolem; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; +import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; @@ -20,7 +24,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; * @see WitherAssembler * */ -public class IronGolemAssembler extends AbstractEntityAssembler { +public class IronGolemAssembler extends AbstractEntityAssembler { public IronGolemAssembler(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); @@ -38,7 +42,7 @@ public class IronGolemAssembler extends AbstractEntityAssembler { @Override public ItemStack getHead() { - return new ItemStack(Material.PUMPKIN); + return new ItemStack(Material.CARVED_PUMPKIN); } @Override @@ -58,9 +62,19 @@ public class IronGolemAssembler extends AbstractEntityAssembler { @Override protected void constructMenu(BlockMenuPreset preset) { - preset.addItem(1, new CustomItem(getHead(), "&7Pumpkin Slot", "", "&rThis Slot accepts Pumpkins"), ChestMenuUtils.getEmptyClickHandler()); - preset.addItem(7, new CustomItem(getBody(), "&7Iron Block Slot", "", "&rThis Slot accepts Iron Blocks"), ChestMenuUtils.getEmptyClickHandler()); - preset.addItem(13, new CustomItem(Material.CLOCK, "&7Cooldown: &b30 Seconds", "", "&rThis Machine takes up to half a Minute to operate", "&rso give it some Time!"), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(1, new CustomItem(getHead(), "&7Pumpkin Slot", "", "&fThis Slot accepts Pumpkins"), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(7, new CustomItem(getBody(), "&7Iron Block Slot", "", "&fThis Slot accepts Iron Blocks"), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(13, new CustomItem(Material.CLOCK, "&7Cooldown: &b30 Seconds", "", "&fThis Machine takes up to half a Minute to operate", "&fso give it some Time!"), ChestMenuUtils.getEmptyClickHandler()); + } + + @Override + public IronGolem spawnEntity(Location l) { + if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_15)) { + // This sound doesn't exist in 1.14 and earlier :/ + l.getWorld().playSound(l, Sound.ENTITY_IRON_GOLEM_REPAIR, 0.5F, 1); + } + + return l.getWorld().spawn(l, IronGolem.class); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/TreeGrowthAccelerator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/TreeGrowthAccelerator.java index 2f3bee95f..875657a6d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/TreeGrowthAccelerator.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/TreeGrowthAccelerator.java @@ -55,12 +55,7 @@ public class TreeGrowthAccelerator extends SlimefunItem implements InventoryBloc BlockMenu inv = BlockStorage.getInventory(b); if (inv != null) { - for (int slot : getInputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } + inv.dropItems(b.getLocation(), getInputSlots()); } return true; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/WitherAssembler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/WitherAssembler.java index 3cedfb251..07b4c34e2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/WitherAssembler.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/WitherAssembler.java @@ -1,5 +1,6 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Wither; import org.bukkit.inventory.ItemStack; @@ -20,7 +21,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; * @see IronGolemAssembler * */ -public class WitherAssembler extends AbstractEntityAssembler { +public class WitherAssembler extends AbstractEntityAssembler { public WitherAssembler(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); @@ -58,9 +59,14 @@ public class WitherAssembler extends AbstractEntityAssembler { @Override protected void constructMenu(BlockMenuPreset preset) { - preset.addItem(1, new CustomItem(getHead(), "&7Wither Skeleton Skull Slot", "", "&rThis Slot accepts Wither Skeleton Skulls"), ChestMenuUtils.getEmptyClickHandler()); - preset.addItem(7, new CustomItem(getBody(), "&7Soul Sand Slot", "", "&rThis Slot accepts Soul Sand"), ChestMenuUtils.getEmptyClickHandler()); - preset.addItem(13, new CustomItem(Material.CLOCK, "&7Cooldown: &b30 Seconds", "", "&rThis Machine takes up to half a Minute to operate", "&rso give it some Time!"), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(1, new CustomItem(getHead(), "&7Wither Skeleton Skull Slot", "", "&fThis Slot accepts Wither Skeleton Skulls"), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(7, new CustomItem(getBody(), "&7Soul Sand Slot", "", "&fThis Slot accepts Soul Sand"), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(13, new CustomItem(Material.CLOCK, "&7Cooldown: &b30 Seconds", "", "&fThis Machine takes up to half a Minute to operate", "&fso give it some Time!"), ChestMenuUtils.getEmptyClickHandler()); + } + + @Override + public Wither spawnEntity(Location l) { + return l.getWorld().spawn(l, Wither.class); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/XPCollector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/XPCollector.java index 15ad321fa..98b75f825 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/XPCollector.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/XPCollector.java @@ -6,19 +6,18 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.ExperienceOrb; -import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.api.BlockStorage; @@ -39,30 +38,28 @@ public class XPCollector extends SlimefunItem implements InventoryBlock, EnergyN createPreset(this, this::constructMenu); - registerBlockHandler(getID(), new SlimefunBlockHandler() { + addItemHandler(onPlace()); + registerBlockHandler(getID(), (p, b, stack, reason) -> { + BlockMenu inv = BlockStorage.getInventory(b); - @Override - public void onPlace(Player p, Block b, SlimefunItem item) { - BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString()); + if (inv != null) { + inv.dropItems(b.getLocation(), getOutputSlots()); } - @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - BlockMenu inv = BlockStorage.getInventory(b); - - if (inv != null) { - for (int slot : getOutputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - } - return true; - } + return true; }); } + private BlockPlaceHandler onPlace() { + return new BlockPlaceHandler(false) { + + @Override + public void onPlayerPlace(BlockPlaceEvent e) { + BlockStorage.addBlockInfo(e.getBlock(), "owner", e.getPlayer().getUniqueId().toString()); + } + }; + } + @Override public int[] getInputSlots() { return new int[0]; @@ -85,7 +82,7 @@ public class XPCollector extends SlimefunItem implements InventoryBlock, EnergyN protected void constructMenu(BlockMenuPreset preset) { for (int slot : border) { - preset.addItem(slot, new CustomItem(new ItemStack(Material.PURPLE_STAINED_GLASS_PANE), " "), (p, s, item, action) -> false); + preset.addItem(slot, new CustomItem(Material.PURPLE_STAINED_GLASS_PANE, " "), (p, s, item, action) -> false); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/Reactor.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/Reactor.java index 81e77ce96..3f13bac0e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/Reactor.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/Reactor.java @@ -87,41 +87,7 @@ public abstract class Reactor extends AbstractEnergyProvider { BlockStorage.addBlockInfo(b, MODE, ReactorMode.GENERATOR.toString()); } - if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), MODE).equals(ReactorMode.GENERATOR.toString())) { - menu.replaceExistingItem(4, new CustomItem(SlimefunItems.NUCLEAR_REACTOR, "&7Focus: &eElectricity", "", "&6Your Reactor will focus on Power Generation", "&6If your Energy Network doesn't need Power", "&6it will not produce any either", "", "&7\u21E8 Click to change the Focus to &eProduction")); - menu.addMenuClickHandler(4, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, MODE, ReactorMode.PRODUCTION.toString()); - newInstance(menu, b); - return false; - }); - } - else { - menu.replaceExistingItem(4, new CustomItem(SlimefunItems.PLUTONIUM, "&7Focus: &eProduction", "", "&6Your Reactor will focus on producing goods", "&6If your Energy Network doesn't need Power", "&6it will continue to run and simply will", "&6not generate any Power in the mean time", "", "&7\u21E8 Click to change the Focus to &ePower Generation")); - menu.addMenuClickHandler(4, (p, slot, item, action) -> { - BlockStorage.addBlockInfo(b, MODE, ReactorMode.GENERATOR.toString()); - newInstance(menu, b); - return false; - }); - } - - BlockMenu port = getAccessPort(b.getLocation()); - if (port != null) { - menu.replaceExistingItem(INFO_SLOT, new CustomItem(Material.GREEN_WOOL, "&7Access Port", "", "&6Detected", "", "&7> Click to view Access Port")); - menu.addMenuClickHandler(INFO_SLOT, (p, slot, item, action) -> { - port.open(p); - newInstance(menu, b); - - return false; - }); - } - else { - menu.replaceExistingItem(INFO_SLOT, new CustomItem(Material.RED_WOOL, "&7Access Port", "", "&cNot detected", "", "&7Access Port must be", "&7placed 3 blocks above", "&7a reactor!")); - menu.addMenuClickHandler(INFO_SLOT, (p, slot, item, action) -> { - newInstance(menu, b); - menu.open(p); - return false; - }); - } + updateInventory(menu, b); } @Override @@ -139,26 +105,9 @@ public abstract class Reactor extends AbstractEnergyProvider { BlockMenu inv = BlockStorage.getInventory(b); if (inv != null) { - for (int slot : getFuelSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - - for (int slot : getCoolantSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - - for (int slot : getOutputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } + inv.dropItems(b.getLocation(), getFuelSlots()); + inv.dropItems(b.getLocation(), getCoolantSlots()); + inv.dropItems(b.getLocation(), getOutputSlots()); } progress.remove(b.getLocation()); @@ -170,6 +119,51 @@ public abstract class Reactor extends AbstractEnergyProvider { registerDefaultFuelTypes(); } + protected void updateInventory(BlockMenu menu, Block b) { + ReactorMode mode = getReactorMode(b.getLocation()); + + switch (mode) { + case GENERATOR: + menu.replaceExistingItem(4, new CustomItem(SlimefunItems.NUCLEAR_REACTOR, "&7Focus: &eElectricity", "", "&6Your Reactor will focus on Power Generation", "&6If your Energy Network doesn't need Power", "&6it will not produce any either", "", "&7\u21E8 Click to change the Focus to &eProduction")); + menu.addMenuClickHandler(4, (p, slot, item, action) -> { + BlockStorage.addBlockInfo(b, MODE, ReactorMode.PRODUCTION.toString()); + updateInventory(menu, b); + return false; + }); + break; + case PRODUCTION: + menu.replaceExistingItem(4, new CustomItem(SlimefunItems.PLUTONIUM, "&7Focus: &eProduction", "", "&6Your Reactor will focus on producing goods", "&6If your Energy Network doesn't need Power", "&6it will continue to run and simply will", "&6not generate any Power in the mean time", "", "&7\u21E8 Click to change the Focus to &ePower Generation")); + menu.addMenuClickHandler(4, (p, slot, item, action) -> { + BlockStorage.addBlockInfo(b, MODE, ReactorMode.GENERATOR.toString()); + updateInventory(menu, b); + return false; + }); + break; + default: + break; + } + + BlockMenu port = getAccessPort(b.getLocation()); + + if (port != null) { + menu.replaceExistingItem(INFO_SLOT, new CustomItem(Material.GREEN_WOOL, "&7Access Port", "", "&6Detected", "", "&7> Click to view Access Port")); + menu.addMenuClickHandler(INFO_SLOT, (p, slot, item, action) -> { + port.open(p); + updateInventory(menu, b); + + return false; + }); + } + else { + menu.replaceExistingItem(INFO_SLOT, new CustomItem(Material.RED_WOOL, "&7Access Port", "", "&cNot detected", "", "&7Access Port must be", "&7placed 3 blocks above", "&7a reactor!")); + menu.addMenuClickHandler(INFO_SLOT, (p, slot, item, action) -> { + updateInventory(menu, b); + menu.open(p); + return false; + }); + } + } + private void constructMenu(BlockMenuPreset preset) { for (int i : border) { preset.addItem(i, new CustomItem(new ItemStack(Material.GRAY_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler()); @@ -203,6 +197,16 @@ public abstract class Reactor extends AbstractEnergyProvider { } } + protected ReactorMode getReactorMode(Location l) { + ReactorMode mode = ReactorMode.GENERATOR; + + if (BlockStorage.hasBlockInfo(l) && BlockStorage.getLocationInfo(l, MODE).equals(ReactorMode.PRODUCTION.toString())) { + mode = ReactorMode.PRODUCTION; + } + + return mode; + } + public abstract void extraTick(Location l); /** @@ -278,7 +282,7 @@ public abstract class Reactor extends AbstractEnergyProvider { int space = getCapacity() - charge; - if (space >= produced || !ReactorMode.GENERATOR.toString().equals(BlockStorage.getLocationInfo(l, MODE))) { + if (space >= produced || getReactorMode(l) != ReactorMode.GENERATOR) { progress.put(l, timeleft - 1); checkForWaterBlocks(l); @@ -453,10 +457,10 @@ public abstract class Reactor extends AbstractEnergyProvider { } protected BlockMenu getAccessPort(Location l) { - Location portL = new Location(l.getWorld(), l.getX(), l.getY() + 3, l.getZ()); + Location port = new Location(l.getWorld(), l.getX(), l.getY() + 3, l.getZ()); - if (BlockStorage.check(portL, SlimefunItems.REACTOR_ACCESS_PORT.getItemId())) { - return BlockStorage.getInventory(portL); + if (BlockStorage.check(port, SlimefunItems.REACTOR_ACCESS_PORT.getItemId())) { + return BlockStorage.getInventory(port); } else { return null; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/Juice.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/Juice.java index f4076401b..15d2d1c78 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/Juice.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/Juice.java @@ -1,12 +1,25 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.food; -import org.bukkit.inventory.ItemStack; +import java.util.ArrayList; +import java.util.List; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler; +import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler; import io.github.thebusybiscuit.slimefun4.implementation.listeners.CoolerListener; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; /** @@ -19,10 +32,69 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; * @see CoolerListener * */ -public class Juice extends SlimefunItem { +public class Juice extends SimpleSlimefunItem { + + private final List effects; public Juice(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { - super(category, item, recipeType, recipe); + this(category, item, recipeType, recipe, null); + } + + public Juice(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { + super(category, item, recipeType, recipe, recipeOutput); + + ItemMeta meta = item.getItemMeta(); + + if (meta instanceof PotionMeta) { + effects = ((PotionMeta) meta).getCustomEffects(); + } + else { + effects = new ArrayList<>(); + } + } + + @Override + public ItemConsumptionHandler getItemHandler() { + return (e, p, item) -> { + // Fix for Saturation on potions is no longer working, + // Minecraft has been broken when it comes to Saturation potions for a long time + + for (PotionEffect effect : effects) { + if (effect.getType().equals(PotionEffectType.SATURATION)) { + p.addPotionEffect(effect); + break; + } + } + + removeGlassBottle(p, item); + }; + } + + /** + * Determines from which hand the juice is being drunk, and its amount + * + * @param p + * The {@link Player} that triggered this + * @param item + * The {@link ItemStack} in question + */ + private void removeGlassBottle(Player p, ItemStack item) { + if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInMainHand(), true)) { + if (p.getInventory().getItemInMainHand().getAmount() == 1) { + Slimefun.runSync(() -> p.getEquipment().getItemInMainHand().setAmount(0)); + } + else { + Slimefun.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1))); + } + } + else if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInOffHand(), true)) { + if (p.getInventory().getItemInOffHand().getAmount() == 1) { + Slimefun.runSync(() -> p.getEquipment().getItemInOffHand().setAmount(0)); + } + else { + Slimefun.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1))); + } + } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java index ea157dcf0..da8d3c4bf 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java @@ -8,12 +8,14 @@ import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram; @@ -21,19 +23,15 @@ import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenu import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.energy.ChargableBlock; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; -public abstract class GEOMiner extends AContainer implements InventoryBlock, RecipeDisplayItem { +public abstract class GEOMiner extends AContainer implements RecipeDisplayItem { private static final int[] BORDER = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 26, 27, 35, 36, 44, 45, 53 }; private static final int[] OUTPUT_BORDER = { 19, 20, 21, 22, 23, 24, 25, 28, 34, 37, 43, 46, 47, 48, 49, 50, 51, 52 }; @@ -43,43 +41,32 @@ public abstract class GEOMiner extends AContainer implements InventoryBlock, Rec public GEOMiner(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); - registerBlockHandler(getID(), new SlimefunBlockHandler() { + addItemHandler(onPlace()); + registerBlockHandler(getID(), (p, b, stack, reason) -> { + SimpleHologram.remove(b); - @Override - public void onPlace(Player p, Block b, SlimefunItem item) { - // Spawn the hologram - SimpleHologram.update(b, "&7Idling..."); + BlockMenu inv = BlockStorage.getInventory(b); + + if (inv != null) { + inv.dropItems(b.getLocation(), getOutputSlots()); } - @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - SimpleHologram.remove(b); - - BlockMenu inv = BlockStorage.getInventory(b); - - if (inv != null) { - for (int slot : getInputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - - for (int slot : getOutputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - } - - progress.remove(b); - processing.remove(b); - return true; - } + progress.remove(b); + processing.remove(b); + return true; }); } + private BlockPlaceHandler onPlace() { + return new BlockPlaceHandler(false) { + + @Override + public void onPlayerPlace(BlockPlaceEvent e) { + SimpleHologram.update(e.getBlock(), "&7Idling..."); + } + }; + } + @Override public String getInventoryTitle() { return "&6GEO-Miner"; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/ElevatorPlate.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/ElevatorPlate.java index 1495378dd..e177db8e2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/ElevatorPlate.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/ElevatorPlate.java @@ -12,6 +12,7 @@ import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; @@ -20,6 +21,7 @@ import io.github.thebusybiscuit.cscorelib2.chat.json.ClickEvent; import io.github.thebusybiscuit.cscorelib2.chat.json.CustomBookInterface; import io.github.thebusybiscuit.cscorelib2.chat.json.HoverEvent; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; @@ -28,9 +30,6 @@ import io.papermc.lib.PaperLib; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; @@ -43,19 +42,19 @@ public class ElevatorPlate extends SimpleSlimefunItem { public ElevatorPlate(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { super(category, item, recipeType, recipe, recipeOutput); - SlimefunItem.registerBlockHandler(getID(), new SlimefunBlockHandler() { + addItemHandler(onPlace()); + } + + private BlockPlaceHandler onPlace() { + return new BlockPlaceHandler(false) { @Override - public void onPlace(Player p, Block b, SlimefunItem item) { + public void onPlayerPlace(BlockPlaceEvent e) { + Block b = e.getBlock(); BlockStorage.addBlockInfo(b, DATA_KEY, "&rFloor #0"); - BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString()); + BlockStorage.addBlockInfo(b, "owner", e.getPlayer().getUniqueId().toString()); } - - @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - return true; - } - }); + }; } public Set getUsers() { @@ -136,6 +135,7 @@ public class ElevatorPlate extends SimpleSlimefunItem { } Location destination = new Location(player.getWorld(), block.getX() + 0.5, block.getY() + 0.4, block.getZ() + 0.5, yaw, player.getEyeLocation().getPitch()); + PaperLib.teleportAsync(player, destination).thenAccept(teleported -> { if (teleported.booleanValue()) { player.sendTitle(ChatColor.WHITE + ChatColors.color(floor), null, 20, 60, 20); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/GPSTransmitter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/GPSTransmitter.java index ef66e79c0..a9248431e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/GPSTransmitter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/GPSTransmitter.java @@ -3,19 +3,18 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.gps; import java.util.UUID; import org.bukkit.block.Block; -import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; @@ -26,22 +25,24 @@ public abstract class GPSTransmitter extends SimpleSlimefunItem imp public GPSTransmitter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); - SlimefunItem.registerBlockHandler(getID(), new SlimefunBlockHandler() { - - @Override - public void onPlace(Player p, Block b, SlimefunItem item) { - BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString()); - } - - @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - UUID owner = UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner")); - SlimefunPlugin.getGPSNetwork().updateTransmitter(b.getLocation(), owner, false); - return true; - } + addItemHandler(onPlace()); + registerBlockHandler(getID(), (p, b, stack, reason) -> { + UUID owner = UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner")); + SlimefunPlugin.getGPSNetwork().updateTransmitter(b.getLocation(), owner, false); + return true; }); } + private BlockPlaceHandler onPlace() { + return new BlockPlaceHandler(false) { + + @Override + public void onPlayerPlace(BlockPlaceEvent e) { + BlockStorage.addBlockInfo(e.getBlock(), "owner", e.getPlayer().getUniqueId().toString()); + } + }; + } + public abstract int getMultiplier(int y); public abstract int getEnergyConsumption(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/PersonalActivationPlate.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/PersonalActivationPlate.java index ae68ae60b..a814ecfde 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/PersonalActivationPlate.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/PersonalActivationPlate.java @@ -1,14 +1,12 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.gps; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; @@ -17,17 +15,16 @@ public class PersonalActivationPlate extends SlimefunItem { public PersonalActivationPlate(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); - SlimefunItem.registerBlockHandler(getID(), new SlimefunBlockHandler() { + addItemHandler(onPlace()); + } + + private BlockPlaceHandler onPlace() { + return new BlockPlaceHandler(false) { @Override - public void onPlace(Player p, Block b, SlimefunItem item) { - BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString()); + public void onPlayerPlace(BlockPlaceEvent e) { + BlockStorage.addBlockInfo(e.getBlock(), "owner", e.getPlayer().getUniqueId().toString()); } - - @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - return true; - } - }); + }; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/Teleporter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/Teleporter.java index 93329f3bc..7edf47a10 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/Teleporter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/Teleporter.java @@ -1,16 +1,15 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.gps; -import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.api.gps.GPSNetwork; import io.github.thebusybiscuit.slimefun4.api.gps.TeleportationManager; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; @@ -29,18 +28,17 @@ public class Teleporter extends SlimefunItem { public Teleporter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); - SlimefunItem.registerBlockHandler(getID(), new SlimefunBlockHandler() { + addItemHandler(onPlace()); + } + + private BlockPlaceHandler onPlace() { + return new BlockPlaceHandler(false) { @Override - public void onPlace(Player p, Block b, SlimefunItem item) { - BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString()); + public void onPlayerPlace(BlockPlaceEvent e) { + BlockStorage.addBlockInfo(e.getBlock(), "owner", e.getPlayer().getUniqueId().toString()); } - - @Override - public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) { - return true; - } - }); + }; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/EnchantmentRune.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/EnchantmentRune.java index c57ffe8d1..f4522a725 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/EnchantmentRune.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/EnchantmentRune.java @@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.magical; import java.util.ArrayList; import java.util.Collection; import java.util.EnumMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; @@ -16,14 +17,13 @@ import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemDropHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; @@ -35,7 +35,6 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; * @author Linox * * @see ItemDropHandler - * @see Enchantment * */ public class EnchantmentRune extends SimpleSlimefunItem { @@ -67,13 +66,17 @@ public class EnchantmentRune extends SimpleSlimefunItem { public ItemDropHandler getItemHandler() { return (e, p, item) -> { if (isItem(item.getItemStack())) { - - if (!Slimefun.hasUnlocked(p, this, true)) { - return true; + if (Slimefun.hasUnlocked(p, this, true)) { + Slimefun.runSync(() -> { + try { + addRandomEnchantment(p, item); + } + catch (Exception x) { + error("An Exception occured while trying to apply an Enchantment Rune", x); + } + }, 20L); } - Slimefun.runSync(() -> addRandomEnchantment(p, e, item), 20L); - return true; } @@ -81,69 +84,58 @@ public class EnchantmentRune extends SimpleSlimefunItem { }; } - private void addRandomEnchantment(Player p, PlayerDropItemEvent e, Item item) { + private void addRandomEnchantment(Player p, Item rune) { // Being sure the entity is still valid and not picked up or whatsoever. - if (!item.isValid()) { + if (!rune.isValid()) { return; } - Location l = item.getLocation(); + Location l = rune.getLocation(); Collection entites = l.getWorld().getNearbyEntities(l, RANGE, RANGE, RANGE, this::findCompatibleItem); Optional optional = entites.stream().findFirst(); if (optional.isPresent()) { - Item entity = (Item) optional.get(); - ItemStack target = entity.getItemStack(); + Item item = (Item) optional.get(); + ItemStack itemStack = item.getItemStack(); - List applicableEnchantmentList = applicableEnchantments.get(target.getType()); + List potentialEnchantments = applicableEnchantments.get(itemStack.getType()); - if (applicableEnchantmentList == null) { + if (potentialEnchantments == null) { SlimefunPlugin.getLocalization().sendMessage(p, "messages.enchantment-rune.fail", true); return; } else { - applicableEnchantmentList = new ArrayList<>(applicableEnchantmentList); + potentialEnchantments = new ArrayList<>(potentialEnchantments); } // Removing the enchantments that the item already has from enchantmentSet - for (Enchantment enchantment : target.getEnchantments().keySet()) { - for (Enchantment possibleEnchantment : applicableEnchantmentList) { - if (possibleEnchantment == enchantment || possibleEnchantment.conflictsWith(enchantment)) { - applicableEnchantmentList.remove(possibleEnchantment); - } - } - } + // This also removes any conflicting enchantments + removeIllegalEnchantments(itemStack, potentialEnchantments); - if (applicableEnchantmentList.isEmpty()) { + if (potentialEnchantments.isEmpty()) { SlimefunPlugin.getLocalization().sendMessage(p, "messages.enchantment-rune.no-enchantment", true); return; } - Enchantment enchantment = applicableEnchantmentList.get(ThreadLocalRandom.current().nextInt(applicableEnchantmentList.size())); - int level = 1; - - if (enchantment.getMaxLevel() != 1) { - level = ThreadLocalRandom.current().nextInt(enchantment.getMaxLevel()) + 1; - } - - target.addEnchantment(enchantment, level); - - if (target.getAmount() == 1) { - e.setCancelled(true); + Enchantment enchantment = potentialEnchantments.get(ThreadLocalRandom.current().nextInt(potentialEnchantments.size())); + int level = getRandomlevel(enchantment); + if (itemStack.getAmount() == 1) { // This lightning is just an effect, it deals no damage. l.getWorld().strikeLightningEffect(l); Slimefun.runSync(() -> { // Being sure entities are still valid and not picked up or whatsoever. - if (item.isValid() && entity.isValid() && target.getAmount() == 1) { + if (rune.isValid() && item.isValid() && itemStack.getAmount() == 1) { l.getWorld().spawnParticle(Particle.CRIT_MAGIC, l, 1); l.getWorld().playSound(l, Sound.ENTITY_ZOMBIE_VILLAGER_CURE, 1F, 1F); - entity.remove(); item.remove(); - l.getWorld().dropItemNaturally(l, target); + rune.remove(); + + itemStack.addEnchantment(enchantment, level); + l.getWorld().dropItemNaturally(l, itemStack); SlimefunPlugin.getLocalization().sendMessage(p, "messages.enchantment-rune.success", true); } @@ -155,6 +147,31 @@ public class EnchantmentRune extends SimpleSlimefunItem { } } + private int getRandomlevel(Enchantment enchantment) { + int level = 1; + + if (enchantment.getMaxLevel() != 1) { + level = ThreadLocalRandom.current().nextInt(enchantment.getMaxLevel()) + 1; + } + + return level; + } + + private void removeIllegalEnchantments(ItemStack target, List potentialEnchantments) { + for (Enchantment enchantment : target.getEnchantments().keySet()) { + Iterator iterator = potentialEnchantments.iterator(); + + while (iterator.hasNext()) { + Enchantment possibleEnchantment = iterator.next(); + + // Duplicate or conflict + if (possibleEnchantment.equals(enchantment) || possibleEnchantment.conflictsWith(enchantment)) { + iterator.remove(); + } + } + } + } + private boolean findCompatibleItem(Entity n) { if (n instanceof Item) { Item item = (Item) n; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/MagicalZombiePills.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/MagicalZombiePills.java index b14be25e1..33f193ef0 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/MagicalZombiePills.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/MagicalZombiePills.java @@ -1,12 +1,15 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.magical; -import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; +import org.bukkit.GameMode; import org.bukkit.Sound; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; import org.bukkit.entity.Villager; import org.bukkit.entity.ZombieVillager; import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.core.handlers.EntityInteractHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; @@ -36,10 +39,16 @@ public class MagicalZombiePills extends SimpleSlimefunItem { - if (entity.getType() == EntityType.ZOMBIE_VILLAGER) { + return (e, item, offhand) -> { + Entity entity = e.getRightClicked(); + + if (entity.getType() == EntityType.ZOMBIE_VILLAGER) { + Player p = e.getPlayer(); + + if (p.getGameMode() != GameMode.CREATIVE) { + ItemUtils.consumeItem(item, false); + } - ItemUtils.consumeItem(item, false); p.playSound(p.getLocation(), Sound.ENTITY_ZOMBIE_VILLAGER_CONVERTED, 1, 1); ZombieVillager zombieVillager = (ZombieVillager) entity; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/SoulboundRune.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/SoulboundRune.java index c9f33c4e5..9a9c4d54e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/SoulboundRune.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/SoulboundRune.java @@ -8,7 +8,6 @@ import org.bukkit.Sound; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.core.attributes.Soulbound; @@ -51,7 +50,7 @@ public class SoulboundRune extends SimpleSlimefunItem { return true; } - Slimefun.runSync(() -> activate(p, e, item), 20L); + Slimefun.runSync(() -> activate(p, item), 20L); return true; } @@ -59,41 +58,42 @@ public class SoulboundRune extends SimpleSlimefunItem { }; } - private void activate(Player p, PlayerDropItemEvent e, Item item) { + private void activate(Player p, Item rune) { // Being sure the entity is still valid and not picked up or whatsoever. - if (!item.isValid()) { + if (!rune.isValid()) { return; } - Location l = item.getLocation(); + Location l = rune.getLocation(); Collection entites = l.getWorld().getNearbyEntities(l, RANGE, RANGE, RANGE, this::findCompatibleItem); Optional optional = entites.stream().findFirst(); if (optional.isPresent()) { - Item entity = (Item) optional.get(); - ItemStack target = entity.getItemStack(); - - SlimefunUtils.setSoulbound(target, true); - - if (target.getAmount() == 1) { - e.setCancelled(true); + Item item = (Item) optional.get(); + ItemStack itemStack = item.getItemStack(); + if (itemStack.getAmount() == 1) { // This lightning is just an effect, it deals no damage. l.getWorld().strikeLightningEffect(l); Slimefun.runSync(() -> { // Being sure entities are still valid and not picked up or whatsoever. - if (item.isValid() && entity.isValid() && target.getAmount() == 1) { + if (rune.isValid() && item.isValid() && itemStack.getAmount() == 1) { l.getWorld().createExplosion(l, 0); l.getWorld().playSound(l, Sound.ENTITY_GENERIC_EXPLODE, 0.3F, 1); - entity.remove(); item.remove(); - l.getWorld().dropItemNaturally(l, target); + rune.remove(); + + SlimefunUtils.setSoulbound(itemStack, true); + l.getWorld().dropItemNaturally(l, itemStack); SlimefunPlugin.getLocalization().sendMessage(p, "messages.soulbound-rune.success", true); } + else { + SlimefunPlugin.getLocalization().sendMessage(p, "messages.soulbound-rune.fail", true); + } }, 10L); } else { @@ -102,9 +102,19 @@ public class SoulboundRune extends SimpleSlimefunItem { } } - private boolean findCompatibleItem(Entity n) { - if (n instanceof Item) { - Item item = (Item) n; + /** + * This method checks whether a given {@link Entity} is an {@link Item} which can + * be bound to a soul. We exclude the {@link SoulboundRune} itself and any already + * {@link Soulbound} {@link Item}. + * + * @param entity + * The {@link Entity} to check + * + * @return Whether this {@link Entity} is compatible + */ + private boolean findCompatibleItem(Entity entity) { + if (entity instanceof Item) { + Item item = (Item) entity; return !SlimefunUtils.isSoulbound(item.getItemStack()) && !isItem(item.getItemStack()); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/talismans/Talisman.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/talismans/Talisman.java index e0a58a0da..8ec502809 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/talismans/Talisman.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/talismans/Talisman.java @@ -11,6 +11,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockDropItemEvent; import org.bukkit.event.enchantment.EnchantItemEvent; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityEvent; @@ -19,10 +20,12 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; +import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.slimefun4.core.researching.Research; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; @@ -125,12 +128,11 @@ public class Talisman extends SlimefunItem { } private static boolean hasMessage(Talisman talisman) { - return !("").equalsIgnoreCase(talisman.getMessageSuffix()); + return talisman.getMessageSuffix() != null; } public static boolean checkFor(Event e, SlimefunItemStack stack) { - SlimefunItem item = SlimefunItem.getByItem(stack); - return checkFor(e, item); + return checkFor(e, stack.getItem()); } public static boolean checkFor(Event e, SlimefunItem item) { @@ -150,9 +152,9 @@ public class Talisman extends SlimefunItem { ItemStack talismanItem = talisman.getItem(); - if (p.getInventory().containsAtLeast(talismanItem, 1)) { - if (Slimefun.hasUnlocked(p, talismanItem, true)) { - activateTalisman(e, p, p.getInventory(), talisman, talismanItem); + if (SlimefunUtils.containsSimilarItem(p.getInventory(), talismanItem, true)) { + if (Slimefun.hasUnlocked(p, talisman, true)) { + activateTalisman(e, p, p.getInventory(), talisman); return true; } else { @@ -162,9 +164,9 @@ public class Talisman extends SlimefunItem { else { ItemStack enderTalisman = talisman.getEnderVariant(); - if (p.getEnderChest().containsAtLeast(enderTalisman, 1)) { - if (Slimefun.hasUnlocked(p, enderTalisman, true)) { - activateTalisman(e, p, p.getEnderChest(), talisman, enderTalisman); + if (SlimefunUtils.containsSimilarItem(p.getEnderChest(), enderTalisman, true)) { + if (Slimefun.hasUnlocked(p, talisman, true)) { + activateTalisman(e, p, p.getEnderChest(), talisman); return true; } else { @@ -177,12 +179,11 @@ public class Talisman extends SlimefunItem { } } - private static void activateTalisman(Event e, Player p, Inventory inv, Talisman talisman, ItemStack talismanItem) { - consumeItem(inv, talisman, talismanItem); + private static void activateTalisman(Event e, Player p, Inventory inv, Talisman talisman) { + consumeItem(inv, talisman); applyTalismanEffects(p, talisman); cancelEvent(e, talisman); sendMessage(p, talisman); - } private static void applyTalismanEffects(Player p, Talisman talisman) { @@ -203,9 +204,17 @@ public class Talisman extends SlimefunItem { } } - private static void consumeItem(Inventory inv, Talisman talisman, ItemStack talismanItem) { + private static void consumeItem(Inventory inv, Talisman talisman) { if (talisman.isConsumable()) { - inv.removeItem(talismanItem); + ItemStack[] contents = inv.getContents(); + for (int i = 0; i < contents.length; i++) { + ItemStack item = contents[i]; + + if (SlimefunUtils.isItemSimilar(item, talisman.getItem(), true, false)) { + ItemUtils.consumeItem(item, false); + return; + } + } } } @@ -216,6 +225,9 @@ public class Talisman extends SlimefunItem { else if (e instanceof BlockBreakEvent) { return ((BlockBreakEvent) e).getPlayer(); } + else if (e instanceof BlockDropItemEvent) { + return ((BlockDropItemEvent) e).getPlayer(); + } else if (e instanceof PlayerEvent) { return ((PlayerEvent) e).getPlayer(); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Bandage.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Bandage.java index 33235a6a3..4c2acb049 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Bandage.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Bandage.java @@ -16,10 +16,21 @@ import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +/** + * A {@link Bandage} or Rag is a medical supply which heals the {@link Player} and extinguishes + * fire. + * + * @author TheBusyBiscuit + * + */ public class Bandage extends SimpleSlimefunItem { - public Bandage(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { + private final int healingLevel; + + public Bandage(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput, int healingLevel) { super(category, item, recipeType, recipe, recipeOutput); + + this.healingLevel = healingLevel; } @Override @@ -37,7 +48,7 @@ public class Bandage extends SimpleSlimefunItem { } p.getWorld().playEffect(p.getLocation(), Effect.STEP_SOUND, Material.WHITE_WOOL); - p.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, 1)); + p.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, healingLevel)); p.setFireTicks(0); e.cancel(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Rag.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Rag.java deleted file mode 100644 index 2d314ee86..000000000 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Rag.java +++ /dev/null @@ -1,47 +0,0 @@ -package io.github.thebusybiscuit.slimefun4.implementation.items.medical; - -import org.bukkit.Effect; -import org.bukkit.GameMode; -import org.bukkit.Material; -import org.bukkit.attribute.Attribute; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; -import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; -import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; -import me.mrCookieSlime.Slimefun.Lists.RecipeType; -import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; - -public class Rag extends SimpleSlimefunItem { - - public Rag(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { - super(category, item, recipeType, recipe); - } - - @Override - public ItemUseHandler getItemHandler() { - return e -> { - Player p = e.getPlayer(); - - // Player is neither burning nor injured - if (p.getFireTicks() <= 0 && p.getHealth() >= p.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()) { - return; - } - - if (p.getGameMode() != GameMode.CREATIVE) { - ItemUtils.consumeItem(e.getItem(), false); - } - - p.getWorld().playEffect(p.getLocation(), Effect.STEP_SOUND, Material.WHITE_WOOL); - p.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, 0)); - p.setFireTicks(0); - - e.cancel(); - }; - } - -} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/misc/SyntheticEmerald.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/misc/SyntheticEmerald.java new file mode 100644 index 000000000..a8fa1fb2b --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/misc/SyntheticEmerald.java @@ -0,0 +1,29 @@ +package io.github.thebusybiscuit.slimefun4.implementation.items.misc; + +import org.bukkit.entity.Villager; +import org.bukkit.inventory.ItemStack; + +import io.github.thebusybiscuit.slimefun4.implementation.listeners.VillagerTradingListener; +import me.mrCookieSlime.Slimefun.Lists.RecipeType; +import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; + +/** + * The {@link SyntheticEmerald} is an almost normal emerald. + * It can even be used to trade with {@link Villager Villagers}. + * + * @author TheBusyBiscuit + * + * @see VillagerTradingListener + * + */ +public class SyntheticEmerald extends SlimefunItem { + + public SyntheticEmerald(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { + super(category, item, recipeType, recipe); + + setUseableInWorkbench(true); + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/BackpackCrafter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/BackpackCrafter.java index 6d2786244..89c537f04 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/BackpackCrafter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/BackpackCrafter.java @@ -13,7 +13,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; -import io.github.thebusybiscuit.cscorelib2.item.CustomItem; +import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.slimefun4.api.player.PlayerBackpack; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine; @@ -24,9 +24,19 @@ import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +/** + * This abstract super class is responsible for some utility methods for machines which + * are capable of upgrading backpacks. + * + * @author TheBusyBiscuit + * + * @see EnhancedCraftingTable + * @see MagicWorkbench + * + */ abstract class BackpackCrafter extends MultiBlockMachine { - public BackpackCrafter(Category category, SlimefunItemStack item, ItemStack[] recipe, BlockFace trigger) { + BackpackCrafter(Category category, SlimefunItemStack item, ItemStack[] recipe, BlockFace trigger) { super(category, item, recipe, trigger); } @@ -34,7 +44,15 @@ abstract class BackpackCrafter extends MultiBlockMachine { Inventory fakeInv = Bukkit.createInventory(null, 9, "Fake Inventory"); for (int j = 0; j < inv.getContents().length; j++) { - ItemStack stack = inv.getContents()[j] != null && inv.getContents()[j].getAmount() > 1 ? new CustomItem(inv.getContents()[j], inv.getContents()[j].getAmount() - 1) : null; + ItemStack stack = inv.getContents()[j]; + + // Fixes #2103 - Properly simulating the consumption + // (which may leave behind empty buckets or glass bottles) + if (stack != null) { + stack = stack.clone(); + ItemUtils.consumeItem(stack, true); + } + fakeInv.setItem(j, stack); } @@ -91,7 +109,6 @@ abstract class BackpackCrafter extends MultiBlockMachine { PlayerProfile.fromUUID(UUID.fromString(idSplit[0]), profile -> { Optional optional = profile.getBackpack(Integer.parseInt(idSplit[1])); - optional.ifPresent(playerBackpack -> playerBackpack.setSize(size)); }); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/EnhancedCraftingTable.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/EnhancedCraftingTable.java index 97b72b81a..d01668dd9 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/EnhancedCraftingTable.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/EnhancedCraftingTable.java @@ -43,6 +43,7 @@ public class EnhancedCraftingTable extends BackpackCrafter { for (int i = 0; i < inputs.size(); i++) { if (isCraftable(inv, inputs.get(i))) { ItemStack output = RecipeType.getRecipeOutputList(this, inputs.get(i)).clone(); + if (Slimefun.hasUnlocked(p, output, true)) { craft(inv, dispenser, p, b, output); } @@ -72,12 +73,15 @@ public class EnhancedCraftingTable extends BackpackCrafter { ItemUtils.consumeItem(item, true); } } + p.getWorld().playSound(b.getLocation(), Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1); outputInv.addItem(output); } - else SlimefunPlugin.getLocalization().sendMessage(p, "machines.full-inventory", true); + else { + SlimefunPlugin.getLocalization().sendMessage(p, "machines.full-inventory", true); + } } private boolean isCraftable(Inventory inv, ItemStack[] recipe) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/GrindStone.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/GrindStone.java index cff9d414e..5dbf0177c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/GrindStone.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/GrindStone.java @@ -40,9 +40,6 @@ public class GrindStone extends MultiBlockMachine { recipes.add(new ItemStack(Material.BONE_BLOCK)); recipes.add(new ItemStack(Material.BONE_MEAL, 9)); - recipes.add(new ItemStack(Material.GRAVEL)); - recipes.add(new ItemStack(Material.FLINT)); - recipes.add(new ItemStack(Material.ENDER_EYE)); recipes.add(new SlimefunItemStack(SlimefunItems.ENDER_LUMP_1, 2)); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreCrusher.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreCrusher.java index 9d07221a0..a1fd26c24 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreCrusher.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreCrusher.java @@ -25,8 +25,16 @@ import io.papermc.lib.PaperLib; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +/** + * The {@link OreCrusher} is a {@link MultiBlockMachine} which allows you to double ores + * and crush some other {@link Material Materials} into various resources. + * + * @author TheBusyBiscuit + * + */ public class OreCrusher extends MultiBlockMachine { private final DoubleOreSetting doubleOres = new DoubleOreSetting(); @@ -96,15 +104,18 @@ public class OreCrusher extends MultiBlockMachine { if (convert != null && SlimefunUtils.isItemSimilar(current, convert, true)) { ItemStack adding = RecipeType.getRecipeOutput(this, convert); Inventory outputInv = findOutputInventory(adding, dispBlock, inv); - if (outputInv != null) { - ItemStack removing = current.clone(); - removing.setAmount(convert.getAmount()); - inv.removeItem(removing); - outputInv.addItem(adding); - p.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, 1); - } - else { - SlimefunPlugin.getLocalization().sendMessage(p, "machines.full-inventory", true); + + if (Slimefun.hasUnlocked(p, adding, true)) { + if (outputInv != null) { + ItemStack removing = current.clone(); + removing.setAmount(convert.getAmount()); + inv.removeItem(removing); + outputInv.addItem(adding); + p.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, 1); + } + else { + SlimefunPlugin.getLocalization().sendMessage(p, "machines.full-inventory", true); + } } return; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreWasher.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreWasher.java index 73e2a4fe3..099ab6f04 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreWasher.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreWasher.java @@ -34,6 +34,18 @@ public class OreWasher extends MultiBlockMachine { legacyMode = SlimefunPlugin.getCfg().getBoolean("options.legacy-ore-washer"); dusts = new ItemStack[] { SlimefunItems.IRON_DUST, SlimefunItems.GOLD_DUST, SlimefunItems.COPPER_DUST, SlimefunItems.TIN_DUST, SlimefunItems.ZINC_DUST, SlimefunItems.ALUMINUM_DUST, SlimefunItems.MAGNESIUM_DUST, SlimefunItems.LEAD_DUST, SlimefunItems.SILVER_DUST }; } + + @Override + protected void registerDefaultRecipes(List recipes) { + // Iron and Gold are displayed as Ore Crusher recipes, as that is their primary + // way of obtainining them. But we also wanna display them here, so we just + // add these two recipes manually + recipes.add(SlimefunItems.SIFTED_ORE); + recipes.add(SlimefunItems.IRON_DUST); + + recipes.add(SlimefunItems.SIFTED_ORE); + recipes.add(SlimefunItems.GOLD_DUST); + } @Override public List getDisplayRecipes() { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/IndustrialMiner.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/IndustrialMiner.java index deb98ba23..4e4a54301 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/IndustrialMiner.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/IndustrialMiner.java @@ -7,6 +7,7 @@ import java.util.Map; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; +import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import org.apache.commons.lang.Validate; import org.bukkit.Location; import org.bukkit.Material; @@ -47,6 +48,7 @@ public class IndustrialMiner extends MultiBlockMachine { private final int range; private final boolean silkTouch; + private final ItemSetting canMineAncientDebris = new ItemSetting<>("can-mine-ancient-debris", false); public IndustrialMiner(Category category, SlimefunItemStack item, Material baseMaterial, boolean silkTouch, int range) { super(category, item, new ItemStack[] { null, null, null, new CustomItem(Material.PISTON, "Piston (facing up)"), new ItemStack(Material.CHEST), new CustomItem(Material.PISTON, "Piston (facing up)"), new ItemStack(baseMaterial), new ItemStack(SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14) ? Material.BLAST_FURNACE : Material.FURNACE), new ItemStack(baseMaterial) }, BlockFace.UP); @@ -55,6 +57,7 @@ public class IndustrialMiner extends MultiBlockMachine { this.silkTouch = silkTouch; registerDefaultFuelTypes(); + addItemSetting(canMineAncientDebris); } /** @@ -129,7 +132,7 @@ public class IndustrialMiner extends MultiBlockMachine { case LAPIS_ORE: return new ItemStack(Material.LAPIS_LAZULI, 4 + random.nextInt(4)); default: - // This includes Iron and Gold ore + // This includes Iron and Gold ore (and Ancient Debris) return new ItemStack(ore); } } @@ -207,7 +210,19 @@ public class IndustrialMiner extends MultiBlockMachine { * @return Whether this {@link IndustrialMiner} is capable of mining this {@link Material} */ public boolean canMine(Material type) { - return type.name().endsWith("_ORE"); + if (type.name().endsWith("_ORE")) { + return true; + } + else if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) { + if (type == Material.GILDED_BLACKSTONE) { + return true; + } + else if (type == Material.ANCIENT_DEBRIS) { + return canMineAncientDebris.getValue(); + } + } + + return false; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/seasonal/ChristmasPresent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/seasonal/ChristmasPresent.java index bf0ffe8c7..88a1673b8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/seasonal/ChristmasPresent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/seasonal/ChristmasPresent.java @@ -3,6 +3,8 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.seasonal; import java.util.concurrent.ThreadLocalRandom; import org.bukkit.GameMode; +import org.bukkit.block.Block; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; @@ -12,8 +14,18 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunIte import io.github.thebusybiscuit.slimefun4.utils.FireworkUtils; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +/** + * The {@link ChristmasPresent} is a seasonal {@link SlimefunItem} that drops a random + * gift when being placed down. + * + * @author TheBusyBiscuit + * + * @see EasterEgg + * + */ public class ChristmasPresent extends SimpleSlimefunItem implements NotPlaceable { private final ItemStack[] gifts; @@ -26,22 +38,23 @@ public class ChristmasPresent extends SimpleSlimefunItem impl @Override public BlockPlaceHandler getItemHandler() { - return (p, e, item) -> { - if (isItem(item)) { + return new BlockPlaceHandler(false) { + + @Override + public void onPlayerPlace(BlockPlaceEvent e) { e.setCancelled(true); if (e.getPlayer().getGameMode() != GameMode.CREATIVE) { ItemUtils.consumeItem(item, false); } - FireworkUtils.launchRandom(p, 3); + FireworkUtils.launchRandom(e.getPlayer(), 3); + Block b = e.getBlock(); ItemStack gift = gifts[ThreadLocalRandom.current().nextInt(gifts.length)].clone(); - e.getBlockPlaced().getWorld().dropItemNaturally(e.getBlockPlaced().getLocation(), gift); - return true; + b.getWorld().dropItemNaturally(b.getLocation(), gift); } - return false; }; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosiveShovel.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosiveShovel.java index 8b83819a5..c7ee1477f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosiveShovel.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosiveShovel.java @@ -1,8 +1,5 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.tools; -import java.util.List; - -import org.bukkit.Effect; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -31,15 +28,8 @@ public class ExplosiveShovel extends ExplosiveTool { } @Override - protected void breakBlock(Player p, ItemStack item, Block b, int fortune, List drops) { - if (MaterialTools.getBreakableByShovel().contains(b.getType()) && SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.BREAK_BLOCK)) { - SlimefunPlugin.getProtectionManager().logAction(p, b, ProtectableAction.BREAK_BLOCK); - - b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType()); - b.breakNaturally(item); - - damageItem(p, item); - } + protected boolean canBreak(Player p, Block b) { + return MaterialTools.getBreakableByShovel().contains(b.getType()) && SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.BREAK_BLOCK); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosiveTool.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosiveTool.java index 2ad1cb1b2..15d6db5b6 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosiveTool.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosiveTool.java @@ -9,7 +9,6 @@ import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.entity.Player; -import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockExplodeEvent; import org.bukkit.inventory.ItemStack; @@ -19,7 +18,7 @@ import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem; import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; -import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; +import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Lists.RecipeType; @@ -28,10 +27,18 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -class ExplosiveTool extends SimpleSlimefunItem implements NotPlaceable, DamageableItem { +/** + * This {@link SlimefunItem} is a super class for items like the {@link ExplosivePickaxe} or {@link ExplosiveShovel}. + * + * @author TheBusyBiscuit + * + * @see ExplosivePickaxe + * @see ExplosiveShovel + * + */ +class ExplosiveTool extends SimpleSlimefunItem implements NotPlaceable, DamageableItem { private final ItemSetting damageOnUse = new ItemSetting<>("damage-on-use", true); private final ItemSetting callExplosionEvent = new ItemSetting<>("call-explosion-event", false); @@ -43,35 +50,16 @@ class ExplosiveTool extends SimpleSlimefunItem implements Not } @Override - public BlockBreakHandler getItemHandler() { - return new BlockBreakHandler() { + public ToolUseHandler getItemHandler() { + return (e, tool, fortune, drops) -> { + Player p = e.getPlayer(); + Block b = e.getBlock(); - @Override - public boolean isPrivate() { - return false; - } + b.getWorld().createExplosion(b.getLocation(), 0.0F); + b.getWorld().playSound(b.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 0.2F, 1F); - @Override - public boolean onBlockBreak(BlockBreakEvent e, ItemStack item, int fortune, List drops) { - if (isItem(item)) { - Player p = e.getPlayer(); - - if (Slimefun.hasUnlocked(p, ExplosiveTool.this, true)) { - Block b = e.getBlock(); - - b.getWorld().createExplosion(b.getLocation(), 0.0F); - b.getWorld().playSound(b.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 0.2F, 1F); - - List blocks = findBlocks(b); - breakBlocks(p, item, b, blocks, fortune, drops); - } - - return true; - } - else { - return false; - } - } + List blocks = findBlocks(b); + breakBlocks(p, tool, b, blocks, fortune, drops); }; } @@ -82,13 +70,17 @@ class ExplosiveTool extends SimpleSlimefunItem implements Not if (!blockExplodeEvent.isCancelled()) { for (Block block : blockExplodeEvent.blockList()) { - breakBlock(p, item, block, fortune, drops); + if (canBreak(p, block)) { + breakBlock(p, item, block, fortune, drops); + } } } } else { for (Block block : blocks) { - breakBlock(p, item, block, fortune, drops); + if (canBreak(p, block)) { + breakBlock(p, item, block, fortune, drops); + } } } } @@ -117,38 +109,48 @@ class ExplosiveTool extends SimpleSlimefunItem implements Not return damageOnUse.getValue(); } - protected void breakBlock(Player p, ItemStack item, Block b, int fortune, List drops) { - if (!b.isEmpty() && !b.isLiquid() && !MaterialCollections.getAllUnbreakableBlocks().contains(b.getType()) && SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.BREAK_BLOCK)) { - SlimefunPlugin.getProtectionManager().logAction(p, b, ProtectableAction.BREAK_BLOCK); - - b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType()); - SlimefunItem sfItem = BlockStorage.check(b); - - if (sfItem != null && !sfItem.useVanillaBlockBreaking()) { - SlimefunBlockHandler handler = SlimefunPlugin.getRegistry().getBlockHandlers().get(sfItem.getID()); - - if (handler != null && !handler.onBreak(p, b, sfItem, UnregisterReason.PLAYER_BREAK)) { - drops.add(BlockStorage.retrieve(b)); - } - } - else if (b.getType() == Material.PLAYER_HEAD || b.getType().name().endsWith("_SHULKER_BOX")) { - b.breakNaturally(); - } - else { - boolean applyFortune = b.getType().name().endsWith("_ORE") && b.getType() != Material.IRON_ORE && b.getType() != Material.GOLD_ORE; - - for (ItemStack drop : b.getDrops(getItem())) { - // For some reason this check is necessary with Paper - if (drop != null && drop.getType() != Material.AIR) { - b.getWorld().dropItemNaturally(b.getLocation(), applyFortune ? new CustomItem(drop, fortune) : drop); - } - } - - b.setType(Material.AIR); - } - - damageItem(p, item); + protected boolean canBreak(Player p, Block b) { + if (b.isEmpty() || b.isLiquid()) { + return false; + } + else if (MaterialCollections.getAllUnbreakableBlocks().contains(b.getType())) { + return false; + } + else { + return SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.BREAK_BLOCK); } } + private void breakBlock(Player p, ItemStack item, Block b, int fortune, List drops) { + SlimefunPlugin.getProtectionManager().logAction(p, b, ProtectableAction.BREAK_BLOCK); + + b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType()); + SlimefunItem sfItem = BlockStorage.check(b); + + if (sfItem != null && !sfItem.useVanillaBlockBreaking()) { + SlimefunBlockHandler handler = SlimefunPlugin.getRegistry().getBlockHandlers().get(sfItem.getID()); + + if (handler != null && !handler.onBreak(p, b, sfItem, UnregisterReason.PLAYER_BREAK)) { + drops.add(BlockStorage.retrieve(b)); + } + } + else if (b.getType() == Material.PLAYER_HEAD || b.getType() == Material.SHULKER_BOX || b.getType().name().endsWith("_SHULKER_BOX")) { + b.breakNaturally(item); + } + else { + boolean applyFortune = b.getType().name().endsWith("_ORE") && b.getType() != Material.IRON_ORE && b.getType() != Material.GOLD_ORE; + + for (ItemStack drop : b.getDrops(getItem())) { + // For some reason this check is necessary with Paper + if (drop != null && drop.getType() != Material.AIR) { + b.getWorld().dropItemNaturally(b.getLocation(), applyFortune ? new CustomItem(drop, fortune) : drop); + } + } + + b.setType(Material.AIR); + } + + damageItem(p, item); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/HerculesPickaxe.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/HerculesPickaxe.java index ddcee83ca..cb633e9d3 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/HerculesPickaxe.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/HerculesPickaxe.java @@ -1,57 +1,37 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.tools; -import java.util.List; - import org.bukkit.Material; -import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; -import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; +import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -public class HerculesPickaxe extends SimpleSlimefunItem { +public class HerculesPickaxe extends SimpleSlimefunItem { public HerculesPickaxe(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); } @Override - public BlockBreakHandler getItemHandler() { - return new BlockBreakHandler() { - - @Override - public boolean isPrivate() { - return false; - } - - @Override - public boolean onBlockBreak(BlockBreakEvent e, ItemStack item, int fortune, List drops) { - if (e.getBlock().getType().toString().endsWith("_ORE") && isItem(item)) { - if (!Slimefun.hasUnlocked(e.getPlayer(), HerculesPickaxe.this, true)) { - return true; - } - - if (e.getBlock().getType() == Material.IRON_ORE) { - drops.add(new CustomItem(SlimefunItems.IRON_DUST, 2)); - } - else if (e.getBlock().getType() == Material.GOLD_ORE) { - drops.add(new CustomItem(SlimefunItems.GOLD_DUST, 2)); - } - else { - for (ItemStack drop : e.getBlock().getDrops(getItem())) { - drops.add(new CustomItem(drop, drop.getAmount() * 2)); - } - } - - return true; + public ToolUseHandler getItemHandler() { + return (e, tool, fortune, drops) -> { + if (e.getBlock().getType().toString().endsWith("_ORE")) { + if (e.getBlock().getType() == Material.IRON_ORE) { + drops.add(new CustomItem(SlimefunItems.IRON_DUST, 2)); + } + else if (e.getBlock().getType() == Material.GOLD_ORE) { + drops.add(new CustomItem(SlimefunItems.GOLD_DUST, 2)); + } + else { + for (ItemStack drop : e.getBlock().getDrops(tool)) { + drops.add(new CustomItem(drop, drop.getAmount() * 2)); + } } - else return false; } }; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/LumberAxe.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/LumberAxe.java index 77610b2a1..0e55e7ddb 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/LumberAxe.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/LumberAxe.java @@ -9,20 +9,18 @@ import org.bukkit.Sound; import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.block.data.Orientable; -import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.blocks.Vein; import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; -import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; +import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; /** @@ -46,37 +44,25 @@ public class LumberAxe extends SimpleSlimefunItem implements Not public void preRegister() { super.preRegister(); - addItemHandler(new BlockBreakHandler() { + addItemHandler(onBlockBreak()); + } - @Override - public boolean isPrivate() { - return false; - } + private ToolUseHandler onBlockBreak() { + return (e, tool, fortune, drops) -> { + if (MaterialCollections.getAllLogs().contains(e.getBlock().getType())) { + List logs = Vein.find(e.getBlock(), MAX_BROKEN, b -> Tag.LOGS.isTagged(b.getType())); - @Override - public boolean onBlockBreak(BlockBreakEvent e, ItemStack item, int fortune, List drops) { - if (MaterialCollections.getAllLogs().contains(e.getBlock().getType()) && isItem(item)) { - if (!Slimefun.hasUnlocked(e.getPlayer(), LumberAxe.this, true)) { - return true; - } - - List logs = Vein.find(e.getBlock(), MAX_BROKEN, b -> MaterialCollections.getAllLogs().contains(b.getType())); - - if (logs.contains(e.getBlock())) { - logs.remove(e.getBlock()); - } - - for (Block b : logs) { - if (SlimefunPlugin.getProtectionManager().hasPermission(e.getPlayer(), b, ProtectableAction.BREAK_BLOCK)) { - breakLog(b); - } - } - - return true; + if (logs.contains(e.getBlock())) { + logs.remove(e.getBlock()); + } + + for (Block b : logs) { + if (SlimefunPlugin.getProtectionManager().hasPermission(e.getPlayer(), b, ProtectableAction.BREAK_BLOCK)) { + breakLog(b); + } } - else return false; } - }); + }; } @Override diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PickaxeOfContainment.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PickaxeOfContainment.java index c86507d3d..d03f03729 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PickaxeOfContainment.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PickaxeOfContainment.java @@ -7,11 +7,10 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.CreatureSpawner; import org.bukkit.entity.EntityType; -import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; +import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.BrokenSpawner; @@ -21,7 +20,6 @@ import io.papermc.lib.PaperLib; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; /** @@ -29,51 +27,29 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; * Upon breaking a Spawner, a {@link BrokenSpawner} will be dropped. * But it also allows you to break a {@link RepairedSpawner}. * - * @author Admin + * @author TheBusyBiscuit + * + * @see BrokenSpawner + * @see RepairedSpawner * */ -public class PickaxeOfContainment extends SimpleSlimefunItem { +public class PickaxeOfContainment extends SimpleSlimefunItem { public PickaxeOfContainment(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); } @Override - public BlockBreakHandler getItemHandler() { - return new BlockBreakHandler() { + public ToolUseHandler getItemHandler() { + return (e, tool, fortune, drops) -> { + Block b = e.getBlock(); - @Override - public boolean isPrivate() { - return false; - } + if (b.getType() == Material.SPAWNER) { + ItemStack spawner = breakSpawner(b); + b.getLocation().getWorld().dropItemNaturally(b.getLocation(), spawner); - @Override - public boolean onBlockBreak(BlockBreakEvent e, ItemStack item, int fortune, List drops) { - if (isItem(item)) { - if (!Slimefun.hasUnlocked(e.getPlayer(), PickaxeOfContainment.this, true)) { - return true; - } - - Block b = e.getBlock(); - - if (b.getType() != Material.SPAWNER) { - return true; - } - - ItemStack spawner = breakSpawner(b); - b.getLocation().getWorld().dropItemNaturally(b.getLocation(), spawner); - - e.setExpToDrop(0); - e.setDropItems(false); - return true; - } - else { - if (e.getBlock().getType() == Material.SPAWNER) { - e.setDropItems(false); - } - - return false; - } + e.setExpToDrop(0); + e.setDropItems(false); } }; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PickaxeOfVeinMining.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PickaxeOfVeinMining.java index e2ed14c78..5375fcc8a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PickaxeOfVeinMining.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PickaxeOfVeinMining.java @@ -7,7 +7,6 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; -import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.blocks.Vein; @@ -15,12 +14,11 @@ import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; -import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; +import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; /** @@ -30,7 +28,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; * @author TheBusyBiscuit * */ -public class PickaxeOfVeinMining extends SimpleSlimefunItem { +public class PickaxeOfVeinMining extends SimpleSlimefunItem { private final ItemSetting maxBlocks = new ItemSetting("max-blocks", 16) { @@ -49,28 +47,11 @@ public class PickaxeOfVeinMining extends SimpleSlimefunItem { } @Override - public BlockBreakHandler getItemHandler() { - return new BlockBreakHandler() { - - @Override - public boolean isPrivate() { - return false; - } - - @Override - public boolean onBlockBreak(BlockBreakEvent e, ItemStack item, int fortune, List drops) { - if (MaterialCollections.getAllOres().contains(e.getBlock().getType()) && isItem(item)) { - if (!Slimefun.hasUnlocked(e.getPlayer(), PickaxeOfVeinMining.this, true)) { - return true; - } - - List blocks = Vein.find(e.getBlock(), maxBlocks.getValue(), MaterialCollections.getAllOres()); - breakBlocks(e.getPlayer(), blocks, fortune); - return true; - } - else { - return false; - } + public ToolUseHandler getItemHandler() { + return (e, tool, fortune, drops) -> { + if (MaterialCollections.getAllOres().contains(e.getBlock().getType())) { + List blocks = Vein.find(e.getBlock(), maxBlocks.getValue(), MaterialCollections.getAllOres()); + breakBlocks(e.getPlayer(), blocks, fortune); } }; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/SmeltersPickaxe.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/SmeltersPickaxe.java index bbd13af58..a4b85d96e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/SmeltersPickaxe.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/SmeltersPickaxe.java @@ -1,66 +1,43 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.tools; import java.util.Collection; -import java.util.List; import java.util.Optional; import org.bukkit.Effect; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections; import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem; -import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; +import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -public class SmeltersPickaxe extends SimpleSlimefunItem implements DamageableItem { +public class SmeltersPickaxe extends SimpleSlimefunItem implements DamageableItem { public SmeltersPickaxe(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); } @Override - public BlockBreakHandler getItemHandler() { - return new BlockBreakHandler() { + public ToolUseHandler getItemHandler() { + return (e, tool, fortune, drops) -> { + if (MaterialCollections.getAllOres().contains(e.getBlock().getType()) && !BlockStorage.hasBlockInfo(e.getBlock())) { + Collection blockDrops = e.getBlock().getDrops(getItem()); - @Override - public boolean isPrivate() { - return false; - } - - @Override - public boolean onBlockBreak(BlockBreakEvent e, ItemStack item, int fortune, List drops) { - if (MaterialCollections.getAllOres().contains(e.getBlock().getType()) && isItem(item)) { - if (!Slimefun.hasUnlocked(e.getPlayer(), SmeltersPickaxe.this, true)) { - return true; + for (ItemStack drop : blockDrops) { + if (drop != null && drop.getType() != Material.AIR) { + smelt(e.getBlock(), drop, fortune); + drops.add(drop); } - - if (BlockStorage.hasBlockInfo(e.getBlock())) { - return true; - } - - Collection blockDrops = e.getBlock().getDrops(getItem()); - - for (ItemStack drop : blockDrops) { - if (drop != null && drop.getType() != Material.AIR) { - smelt(e.getBlock(), drop, fortune); - drops.add(drop); - } - } - - damageItem(e.getPlayer(), item); - - return true; } - else return false; + + damageItem(e.getPlayer(), tool); } }; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/ExplosiveBow.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/ExplosiveBow.java index 0a4e82b1c..ac1b31420 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/ExplosiveBow.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/ExplosiveBow.java @@ -63,14 +63,13 @@ public class ExplosiveBow extends SlimefunBow { double distanceSquared = distanceVector.lengthSquared(); double damage = calculateDamage(distanceSquared, e.getDamage()); - Vector knockback = velocity.add(distanceVector.normalize().multiply((int) (e.getDamage() / damage))); - entity.setVelocity(knockback); - if (!entity.getUniqueId().equals(target.getUniqueId())) { EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(e.getDamager(), entity, EntityDamageEvent.DamageCause.ENTITY_EXPLOSION, damage); Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { + Vector knockback = velocity.add(distanceVector.normalize().multiply((int) (e.getDamage() / damage))); + entity.setVelocity(knockback); entity.damage(event.getDamage()); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/SeismicAxe.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/SeismicAxe.java index 3f8bd137a..53d43e5c8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/SeismicAxe.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/SeismicAxe.java @@ -80,17 +80,18 @@ public class SeismicAxe extends SimpleSlimefunItem implements No } private void pushEntity(Player p, Entity entity) { - Vector vector = entity.getLocation().toVector().subtract(p.getLocation().toVector()).normalize(); - vector.multiply(STRENGTH); - vector.setY(0.9); - entity.setVelocity(vector); - if (entity.getType() != EntityType.PLAYER || p.getWorld().getPVP()) { - EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(p, entity, DamageCause.ENTITY_ATTACK, 6D); + EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(p, entity, DamageCause.ENTITY_ATTACK, DAMAGE); Bukkit.getPluginManager().callEvent(event); + // Fixes #2207 - Only apply Vector if the Player is able to damage the entity if (!event.isCancelled()) { - ((LivingEntity) entity).damage(DAMAGE); + Vector vector = entity.getLocation().toVector().subtract(p.getLocation().toVector()).normalize(); + vector.multiply(STRENGTH); + vector.setY(0.9); + entity.setVelocity(vector); + + ((LivingEntity) entity).damage(event.getDamage()); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java index 825859459..960ca8587 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java @@ -27,8 +27,10 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.util.Vector; +import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; +import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; @@ -52,6 +54,8 @@ import me.mrCookieSlime.Slimefun.api.Slimefun; */ public class AncientAltarListener implements Listener { + public static final String ITEM_PREFIX = ChatColors.color("&dALTAR &3Probe - &e"); + private AncientAltar altar; private final Set altarRecipes = new HashSet<>(); @@ -128,6 +132,11 @@ public class AncientAltarListener implements Listener { return; } + if (!SlimefunPlugin.getProtectionManager().hasPermission(p, pedestal, ProtectableAction.ACCESS_INVENTORIES)) { + SlimefunPlugin.getLocalization().sendMessage(p, "inventory.no-access", true); + return; + } + // getting the currently placed item Item stack = findItem(pedestal); @@ -157,6 +166,11 @@ public class AncientAltarListener implements Listener { } private void useAltar(Block altar, Player p) { + if (!SlimefunPlugin.getProtectionManager().hasPermission(p, altar, ProtectableAction.ACCESS_INVENTORIES)) { + SlimefunPlugin.getLocalization().sendMessage(p, "inventory.no-access", true); + return; + } + ItemStack catalyst = new CustomItem(p.getInventory().getItemInMainHand(), 1); List pedestals = getPedestals(altar); @@ -292,7 +306,7 @@ public class AncientAltarListener implements Listener { } String nametag = ItemUtils.getItemName(stack); - Item entity = b.getWorld().dropItem(b.getLocation().add(0.5, 1.2, 0.5), new CustomItem(stack, "&5&dALTAR &3Probe - &e" + System.nanoTime())); + Item entity = b.getWorld().dropItem(b.getLocation().add(0.5, 1.2, 0.5), new CustomItem(stack, ITEM_PREFIX + System.nanoTime())); entity.setVelocity(new Vector(0, 0.1, 0)); SlimefunUtils.markAsNoPickup(entity, "altar_item"); entity.setCustomNameVisible(true); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BeeListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BeeListener.java index e45936f88..92577900d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BeeListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BeeListener.java @@ -42,7 +42,9 @@ public class BeeListener implements Listener { if (profile.hasFullProtectionAgainst(ProtectionType.BEES)) { for (ItemStack armor : p.getInventory().getArmorContents()) { - ItemUtils.damageItem(armor, 1, false); + if (armor != null) { + ItemUtils.damageItem(armor, 1, false); + } } e.setDamage(0D); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java index d7d69e17b..81a9f876e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java @@ -1,7 +1,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners; import java.util.ArrayList; -import java.util.HashSet; +import java.util.EnumSet; import java.util.List; import java.util.Optional; import java.util.Random; @@ -24,18 +24,29 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; +import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; -import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.Slimefun; +/** + * The {@link BlockListener} is responsible for listening to the {@link BlockPlaceEvent} + * and {@link BlockBreakEvent}. + * + * @author TheBusyBiscuit + * + * @see BlockPlaceHandler + * @see BlockBreakHandler + * @see ToolUseHandler + * + */ public class BlockListener implements Listener { // Materials that require a Block under it, e.g. Pressure Plates - private final Set sensitiveMaterials = new HashSet<>(); + private final Set sensitiveMaterials = EnumSet.noneOf(Material.class); public BlockListener(SlimefunPlugin plugin) { plugin.getServer().getPluginManager().registerEvents(this, plugin); @@ -49,7 +60,7 @@ public class BlockListener implements Listener { } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onBlockRegister(BlockPlaceEvent e) { + public void onBlockPlace(BlockPlaceEvent e) { if (BlockStorage.hasBlockInfo(e.getBlock())) { e.setCancelled(true); return; @@ -70,28 +81,51 @@ public class BlockListener implements Listener { BlockStorage.addBlockInfo(e.getBlock(), "id", sfItem.getID(), true); SlimefunBlockHandler blockHandler = SlimefunPlugin.getRegistry().getBlockHandlers().get(sfItem.getID()); + if (blockHandler != null) { blockHandler.onPlace(e.getPlayer(), e.getBlock(), sfItem); } - else { - sfItem.callItemHandler(BlockPlaceHandler.class, handler -> handler.onBlockPlace(e.getPlayer(), e, item)); - } + + sfItem.callItemHandler(BlockPlaceHandler.class, handler -> handler.onPlayerPlace(e)); } } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onBlockUnregister(BlockBreakEvent e) { - if (hasSensitiveBlockAbove(e.getPlayer(), e.getBlock())) { - e.setCancelled(true); - return; - } + public void onBlockBreak(BlockBreakEvent e) { + checkForSensitiveBlockAbove(e.getPlayer(), e.getBlock()); - SlimefunItem sfItem = BlockStorage.check(e.getBlock()); ItemStack item = e.getPlayer().getInventory().getItemInMainHand(); int fortune = getBonusDropsWithFortune(item, e.getBlock()); List drops = new ArrayList<>(); + if (item.getType() != Material.AIR) { + callToolHandler(e, item, fortune, drops); + } + + if (!e.isCancelled()) { + callBlockHandler(e, item, fortune, drops); + } + + dropItems(e, drops); + } + + private void callToolHandler(BlockBreakEvent e, ItemStack item, int fortune, List drops) { + SlimefunItem tool = SlimefunItem.getByItem(item); + + if (tool != null) { + if (Slimefun.hasUnlocked(e.getPlayer(), tool, true)) { + tool.callItemHandler(ToolUseHandler.class, handler -> handler.onToolUse(e, item, fortune, drops)); + } + else { + e.setCancelled(true); + } + } + } + + private void callBlockHandler(BlockBreakEvent e, ItemStack item, int fortune, List drops) { + SlimefunItem sfItem = BlockStorage.check(e.getBlock()); + if (sfItem == null && SlimefunPlugin.getBlockDataService().isTileEntity(e.getBlock().getType())) { Optional blockData = SlimefunPlugin.getBlockDataService().getBlockData(e.getBlock()); @@ -116,16 +150,6 @@ public class BlockListener implements Listener { drops.addAll(sfItem.getDrops()); BlockStorage.clearBlockInfo(e.getBlock()); } - - if (item.getType() != Material.AIR) { - for (ItemHandler handler : SlimefunItem.getPublicItemHandlers(BlockBreakHandler.class)) { - if (((BlockBreakHandler) handler).onBlockBreak(e, item, fortune, drops)) { - break; - } - } - } - - dropItems(e, drops); } private void dropItems(BlockBreakEvent e, List drops) { @@ -142,7 +166,17 @@ public class BlockListener implements Listener { } } - private boolean hasSensitiveBlockAbove(Player p, Block b) { + /** + * This method checks for a sensitive {@link Block}. + * Sensitive {@link Block Blocks} are pressure plates or saplings, which should be broken + * when the block beneath is broken as well. + * + * @param p + * The {@link Player} who broke this {@link Block} + * @param b + * The {@link Block} that was broken + */ + private void checkForSensitiveBlockAbove(Player p, Block b) { Block blockAbove = b.getRelative(BlockFace.UP); if (sensitiveMaterials.contains(blockAbove.getType())) { @@ -156,14 +190,13 @@ public class BlockListener implements Listener { blockAbove.getWorld().dropItemNaturally(blockAbove.getLocation(), BlockStorage.retrieve(blockAbove)); blockAbove.setType(Material.AIR); } - else { - return true; - } + } + else { + blockAbove.getWorld().dropItemNaturally(blockAbove.getLocation(), BlockStorage.retrieve(blockAbove)); + blockAbove.setType(Material.AIR); } } } - - return false; } private int getBonusDropsWithFortune(ItemStack item, Block b) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/DebugFishListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/DebugFishListener.java index a463f2324..30a969e25 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/DebugFishListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/DebugFishListener.java @@ -1,7 +1,10 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners; +import java.util.logging.Level; + import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.block.Skull; import org.bukkit.block.data.Directional; import org.bukkit.block.data.Rotatable; @@ -23,8 +26,16 @@ import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.BlockStorage; +import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.energy.ChargableBlock; +/** + * This {@link Listener} is responsible for handling our debugging tool, the debug fish. + * This is where the functionality of this item is implemented. + * + * @author TheBusyBiscuit + * + */ public class DebugFishListener implements Listener { private final String greenCheckmark; @@ -45,28 +56,46 @@ public class DebugFishListener implements Listener { Player p = e.getPlayer(); - if (p.isOp() && SlimefunUtils.isItemSimilar(e.getItem(), SlimefunItems.DEBUG_FISH, true)) { + if (SlimefunUtils.isItemSimilar(e.getItem(), SlimefunItems.DEBUG_FISH, true, false)) { e.setCancelled(true); - if (e.getAction() == Action.LEFT_CLICK_BLOCK) { - if (p.isSneaking()) { - if (BlockStorage.hasBlockInfo(e.getClickedBlock())) { - BlockStorage.clearBlockInfo(e.getClickedBlock()); - } + if (p.hasPermission("slimefun.debugging")) { + if (e.getAction() == Action.LEFT_CLICK_BLOCK) { + onLeftClick(p, e.getClickedBlock(), e); } - else { - e.setCancelled(false); + else if (e.getAction() == Action.RIGHT_CLICK_BLOCK) { + onRightClick(p, e.getClickedBlock(), e.getBlockFace()); } } - else if (e.getAction() == Action.RIGHT_CLICK_BLOCK) { - if (p.isSneaking()) { - Block b = e.getClickedBlock().getRelative(e.getBlockFace()); - b.setType(Material.PLAYER_HEAD); - SkullBlock.setFromHash(b, HeadTexture.MISSING_TEXTURE.getTexture()); - } - else if (BlockStorage.hasBlockInfo(e.getClickedBlock())) { - sendInfo(p, e.getClickedBlock()); - } + else { + SlimefunPlugin.getLocalization().sendMessage(p, "messages.no-permission", true); + } + } + } + + private void onLeftClick(Player p, Block b, PlayerInteractEvent e) { + if (p.isSneaking()) { + if (BlockStorage.hasBlockInfo(b)) { + BlockStorage.clearBlockInfo(b); + } + } + else { + e.setCancelled(false); + } + } + + private void onRightClick(Player p, Block b, BlockFace face) { + if (p.isSneaking()) { + Block block = b.getRelative(face); + block.setType(Material.PLAYER_HEAD); + SkullBlock.setFromHash(block, HeadTexture.MISSING_TEXTURE.getTexture()); + } + else if (BlockStorage.hasBlockInfo(b)) { + try { + sendInfo(p, b); + } + catch (Exception x) { + Slimefun.getLogger().log(Level.SEVERE, "An Exception occured while using a Debug-Fish", x); } } } @@ -108,7 +137,7 @@ public class DebugFishListener implements Listener { else { p.sendMessage(ChatColors.color("&dTicking: " + redCross)); } - + if (SlimefunPlugin.getProfiler().hasTimings(b)) { p.sendMessage(ChatColors.color(" &dTimings: &e" + SlimefunPlugin.getProfiler().getTime(b))); p.sendMessage(ChatColors.color(" &dTotal Timings: &e" + SlimefunPlugin.getProfiler().getTime(item))); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/EnhancedFurnaceListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/EnhancedFurnaceListener.java index fcfb83f4f..d4e94d139 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/EnhancedFurnaceListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/EnhancedFurnaceListener.java @@ -65,7 +65,7 @@ public class EnhancedFurnaceListener implements Listener { if (state instanceof Furnace) { FurnaceInventory inventory = ((Furnace) state).getInventory(); - int amount = inventory.getSmelting().getType().toString().endsWith("_ORE") ? ((EnhancedFurnace) sfItem).getOutput() : 1; + int amount = inventory.getSmelting().getType().toString().endsWith("_ORE") ? ((EnhancedFurnace) sfItem).getRandomOutputAmount() : 1; Optional result = SlimefunPlugin.getMinecraftRecipeService().getFurnaceOutput(inventory.getSmelting()); if (result.isPresent()) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/PlayerInteractEntityListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/EntityInteractionListener.java similarity index 78% rename from src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/PlayerInteractEntityListener.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/EntityInteractionListener.java index 2bdc3baec..0372b850d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/PlayerInteractEntityListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/EntityInteractionListener.java @@ -4,7 +4,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; @@ -21,14 +21,14 @@ import me.mrCookieSlime.Slimefun.api.Slimefun; * @see EntityInteractHandler * */ -public class PlayerInteractEntityListener implements Listener { +public class EntityInteractionListener implements Listener { - public PlayerInteractEntityListener(SlimefunPlugin plugin) { + public EntityInteractionListener(SlimefunPlugin plugin) { plugin.getServer().getPluginManager().registerEvents(this, plugin); } @EventHandler - public void onInteractEntity(PlayerInteractAtEntityEvent e) { + public void onInteractEntity(PlayerInteractEntityEvent e) { if (!e.getRightClicked().isValid()) { return; } @@ -45,7 +45,7 @@ public class PlayerInteractEntityListener implements Listener { SlimefunItem sfItem = SlimefunItem.getByItem(itemStack); if (sfItem != null && Slimefun.hasUnlocked(e.getPlayer(), sfItem, true)) { - sfItem.callItemHandler(EntityInteractHandler.class, handler -> handler.onInteract(e.getPlayer(), e.getRightClicked(), itemStack, e.getHand() == EquipmentSlot.OFF_HAND)); + sfItem.callItemHandler(EntityInteractHandler.class, handler -> handler.onInteract(e, itemStack, e.getHand() == EquipmentSlot.OFF_HAND)); } } } \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ItemPickupListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ItemPickupListener.java index d009d5007..ce734ed8d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ItemPickupListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ItemPickupListener.java @@ -4,20 +4,18 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.inventory.meta.ItemMeta; -import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; /** * Listens to the ItemPickup events to prevent it if the item has the "no_pickup" metadata or is an ALTAR_PROBE. - * + * * @author TheBusyBiscuit */ public class ItemPickupListener implements Listener { - private static final String ITEM_PREFIX = ChatColors.color("&5&dALTAR &3Probe - &e"); - public ItemPickupListener(SlimefunPlugin plugin) { plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -27,9 +25,13 @@ public class ItemPickupListener implements Listener { if (SlimefunUtils.hasNoPickupFlag(e.getItem())) { e.setCancelled(true); } - else if (e.getItem().getItemStack().hasItemMeta() && e.getItem().getItemStack().getItemMeta().hasDisplayName() && e.getItem().getItemStack().getItemMeta().getDisplayName().startsWith(ITEM_PREFIX)) { - e.setCancelled(true); - e.getItem().remove(); + else if (e.getItem().getItemStack().hasItemMeta()) { + ItemMeta meta = e.getItem().getItemStack().getItemMeta(); + + if (meta.hasDisplayName() && meta.getDisplayName().startsWith(AncientAltarListener.ITEM_PREFIX)) { + e.setCancelled(true); + e.getItem().remove(); + } } } @@ -38,9 +40,13 @@ public class ItemPickupListener implements Listener { if (SlimefunUtils.hasNoPickupFlag(e.getItem())) { e.setCancelled(true); } - else if (e.getItem().getItemStack().hasItemMeta() && e.getItem().getItemStack().getItemMeta().hasDisplayName() && e.getItem().getItemStack().getItemMeta().getDisplayName().startsWith(ITEM_PREFIX)) { - e.setCancelled(true); - e.getItem().remove(); + else if (e.getItem().getItemStack().hasItemMeta()) { + ItemMeta meta = e.getItem().getItemStack().getItemMeta(); + + if (meta.hasDisplayName() && meta.getDisplayName().startsWith(AncientAltarListener.ITEM_PREFIX)) { + e.setCancelled(true); + e.getItem().remove(); + } } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/PiglinListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/PiglinListener.java new file mode 100644 index 000000000..c5f68cfd7 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/PiglinListener.java @@ -0,0 +1,106 @@ +package io.github.thebusybiscuit.slimefun4.implementation.listeners; + +import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; + +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Piglin; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDropItemEvent; +import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; + +import io.github.thebusybiscuit.slimefun4.core.attributes.PiglinBarterDrop; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; + +/** + * This {@link Listener} prevents a {@link Piglin} from bartering with a + * {@link SlimefunItem}. + * It also listens to the {@link EntityDropItemEvent} to + * inject a {@link PiglinBarterDrop} if the chance check passes. + * + * @author poma123 + * @author dNiym + * + */ +public class PiglinListener implements Listener { + + public PiglinListener(SlimefunPlugin plugin) { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void onPickup(EntityPickupItemEvent e) { + if (e.getEntityType() == EntityType.PIGLIN) { + ItemStack item = e.getItem().getItemStack(); + + // Don't let Piglins pick up gold from Slimefun + if (SlimefunItem.getByItem(item) != null) { + e.setCancelled(true); + } + } + } + + @EventHandler + public void onInteract(PlayerInteractEntityEvent e) { + if (!e.getRightClicked().isValid() || e.getRightClicked().getType() != EntityType.PIGLIN) { + return; + } + + Player p = e.getPlayer(); + ItemStack item; + + if (e.getHand() == EquipmentSlot.OFF_HAND) { + item = p.getInventory().getItemInOffHand(); + } + else { + item = p.getInventory().getItemInMainHand(); + } + + // We only care about Gold since it's the actual "Bartering" we wanna prevent + if (item.getType() == Material.GOLD_INGOT) { + SlimefunItem sfItem = SlimefunItem.getByItem(item); + + if (sfItem != null) { + SlimefunPlugin.getLocalization().sendMessage(p, "messages.piglin-barter", true); + e.setCancelled(true); + } + } + } + + @EventHandler + public void onPiglinDropItem(EntityDropItemEvent e) { + if (e.getEntity() instanceof Piglin) { + Set drops = SlimefunPlugin.getRegistry().getBarteringDrops(); + + /* + * NOTE: Getting a new random number each iteration because multiple items could have the same + * % chance to drop, and if one fails all items with that number will fail. + * Getting a new random number will allow multiple items with the same % chance to drop. + */ + + for (ItemStack is : drops) { + SlimefunItem sfi = SlimefunItem.getByItem(is); + // Check the getBarteringLootChance and compare against a random number 0-100, + // if the random number is greater then replace the item. + if (sfi instanceof PiglinBarterDrop) { + int chance = ((PiglinBarterDrop) sfi).getBarteringLootChance(); + + if (chance < 1 || chance >= 100) { + sfi.warn("The Piglin Bartering chance must be between 1-99%"); + } + else if (chance > ThreadLocalRandom.current().nextInt(100)) { + e.getItemDrop().setItemStack(sfi.getRecipeOutput()); + return; + } + } + } + } + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunBowListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunBowListener.java index 9a69a0038..cb45f387b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunBowListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunBowListener.java @@ -8,6 +8,7 @@ import org.bukkit.entity.Arrow; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; @@ -67,16 +68,14 @@ public class SlimefunBowListener implements Listener { }, 4L); } - @EventHandler + @EventHandler(priority = EventPriority.HIGH) public void onArrowSuccessfulHit(EntityDamageByEntityEvent e) { if (e.getDamager() instanceof Arrow && e.getEntity() instanceof LivingEntity && e.getCause() != EntityDamageEvent.DamageCause.ENTITY_EXPLOSION) { - SlimefunBow bow = projectiles.get(e.getDamager().getUniqueId()); + SlimefunBow bow = projectiles.remove(e.getDamager().getUniqueId()); - if (bow != null) { + if (!e.isCancelled() && bow != null) { bow.callItemHandler(BowShootHandler.class, handler -> handler.onHit(e, (LivingEntity) e.getEntity())); } - - projectiles.remove(e.getDamager().getUniqueId()); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunGuideListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunGuideListener.java index 760ef9faf..490fc44a9 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunGuideListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunGuideListener.java @@ -33,8 +33,8 @@ public class SlimefunGuideListener implements Listener { return; } - SlimefunGuideLayout type = SlimefunPlugin.getCfg().getBoolean("guide.default-view-book") ? SlimefunGuideLayout.BOOK : SlimefunGuideLayout.CHEST; - p.getInventory().addItem(SlimefunGuide.getItem(type)); + SlimefunGuideLayout type = SlimefunGuide.getDefaultLayout(); + p.getInventory().addItem(SlimefunGuide.getItem(type).clone()); } } @@ -69,7 +69,7 @@ public class SlimefunGuideListener implements Listener { Player p = e.getPlayer(); ItemStack item = e.getItem(); - if (SlimefunUtils.isItemSimilar(item, SlimefunGuide.getItem(layout), true)) { + if (SlimefunUtils.isItemSimilar(item, SlimefunGuide.getItem(layout), true, false)) { e.cancel(); if (!SlimefunPlugin.getWorldSettingsService().isWorldEnabled(p.getWorld())) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunItemConsumeListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunItemConsumeListener.java index 6fc3c8374..e56acdcfb 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunItemConsumeListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunItemConsumeListener.java @@ -1,22 +1,23 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners; -import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerItemConsumeEvent; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.PotionMeta; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice; -import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.Slimefun; +/** + * This {@link Listener} is responsible for handling the {@link ItemConsumptionHandler} + * for any {@link SlimefunItem}. + * + * @author TheBusyBiscuit + * + */ public class SlimefunItemConsumeListener implements Listener { public SlimefunItemConsumeListener(SlimefunPlugin plugin) { @@ -31,53 +32,11 @@ public class SlimefunItemConsumeListener implements Listener { if (sfItem != null) { if (Slimefun.hasUnlocked(p, sfItem, true)) { - if (sfItem instanceof Juice) { - // Fix for Saturation on potions is no longer working - - for (PotionEffect effect : ((PotionMeta) item.getItemMeta()).getCustomEffects()) { - if (effect.getType().equals(PotionEffectType.SATURATION)) { - p.addPotionEffect(new PotionEffect(PotionEffectType.SATURATION, effect.getDuration(), effect.getAmplifier())); - break; - } - } - - removeGlassBottle(p, item); - } - else { - sfItem.callItemHandler(ItemConsumptionHandler.class, handler -> handler.onConsume(e, p, item)); - } + sfItem.callItemHandler(ItemConsumptionHandler.class, handler -> handler.onConsume(e, p, item)); } else { e.setCancelled(true); } } } - - /** - * Determines from which hand the juice is being drunk, and its amount - * - * @param p - * The {@link Player} that triggered this - * @param item - * The {@link ItemStack} in question - */ - private void removeGlassBottle(Player p, ItemStack item) { - if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInMainHand(), true)) { - if (p.getInventory().getItemInMainHand().getAmount() == 1) { - Slimefun.runSync(() -> p.getEquipment().getItemInMainHand().setAmount(0)); - } - else { - Slimefun.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1))); - } - } - else if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInOffHand(), true)) { - if (p.getInventory().getItemInOffHand().getAmount() == 1) { - Slimefun.runSync(() -> p.getEquipment().getItemInOffHand().setAmount(0)); - } - else { - Slimefun.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1))); - } - } - } - } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TalismanListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TalismanListener.java index 1c1c2c114..8a41ff747 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TalismanListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TalismanListener.java @@ -13,13 +13,14 @@ import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.AbstractArrow; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.ChestedHorse; +import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockDropItemEvent; import org.bukkit.event.enchantment.EnchantItemEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; @@ -35,7 +36,6 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.util.Vector; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; -import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.MagicianTalisman; @@ -229,29 +229,48 @@ public class TalismanListener implements Listener { } } - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onBlockBreak(BlockBreakEvent e) { - ItemStack item = e.getPlayer().getInventory().getItemInMainHand(); + @EventHandler(ignoreCancelled = true) + public void onBlockDropItems(BlockDropItemEvent e) { + // We only want to double ores + Material type = e.getBlockState().getType(); + if (type.name().endsWith("_ORE")) { + ItemStack item = e.getPlayer().getInventory().getItemInMainHand(); - if (item.getType() != Material.AIR && item.getAmount() > 0) { - List drops = new ArrayList<>(e.getBlock().getDrops(item)); - int dropAmount = 1; + if (item.getType() != Material.AIR && item.getAmount() > 0 && !item.containsEnchantment(Enchantment.SILK_TOUCH)) { + Collection drops = e.getItems(); - if (item.getEnchantments().containsKey(Enchantment.LOOT_BONUS_BLOCKS) && !item.getEnchantments().containsKey(Enchantment.SILK_TOUCH)) { - Random random = ThreadLocalRandom.current(); - dropAmount = random.nextInt(item.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS) + 2) - 1; - dropAmount = Math.max(dropAmount, 1); - dropAmount = (e.getBlock().getType() == Material.LAPIS_ORE ? 4 + random.nextInt(5) : 1) * (dropAmount + 1); - } + if (Talisman.checkFor(e, SlimefunItems.TALISMAN_MINER)) { + int dropAmount = getAmountWithFortune(type, item.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS)); + boolean doubledDrops = false; - if (!item.getEnchantments().containsKey(Enchantment.SILK_TOUCH) && MaterialCollections.getAllOres().contains(e.getBlock().getType()) && Talisman.checkFor(e, SlimefunItems.TALISMAN_MINER)) { - for (ItemStack drop : drops) { - if (!drop.getType().isBlock()) { - int amount = Math.max(1, (dropAmount * 2) - drop.getAmount()); - e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation(), new CustomItem(drop, amount)); + for (Item drop : drops) { + ItemStack droppedItem = drop.getItemStack(); + + if (!droppedItem.getType().isBlock()) { + int amount = Math.max(1, (dropAmount * 2) - droppedItem.getAmount()); + e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation(), new CustomItem(droppedItem, amount)); + doubledDrops = true; + } + } + + if (doubledDrops) { + SlimefunPlugin.getLocalization().sendMessage(e.getPlayer(), "messages.talisman.miner", true); } } } } } + + private int getAmountWithFortune(Material type, int fortuneLevel) { + if (fortuneLevel > 0) { + Random random = ThreadLocalRandom.current(); + int amount = random.nextInt(fortuneLevel + 2) - 1; + amount = Math.max(amount, 1); + amount = (type == Material.LAPIS_ORE ? 4 + random.nextInt(5) : 1) * (amount + 1); + return amount; + } + else { + return 1; + } + } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/VanillaMachinesListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/VanillaMachinesListener.java index ed660f5cc..bdb8d367f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/VanillaMachinesListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/VanillaMachinesListener.java @@ -6,6 +6,7 @@ import org.bukkit.event.Event.Result; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.CraftItemEvent; +import org.bukkit.event.inventory.InventoryAction; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.PrepareItemCraftEvent; @@ -95,10 +96,24 @@ public class VanillaMachinesListener implements Listener { @EventHandler(ignoreCancelled = true) public void onPreBrew(InventoryClickEvent e) { - Inventory inventory = e.getInventory(); + Inventory clickedInventory = e.getClickedInventory(); + Inventory topInventory = e.getView().getTopInventory(); - if (inventory.getType() == InventoryType.BREWING && e.getRawSlot() < inventory.getSize() && inventory.getHolder() instanceof BrewingStand) { - e.setCancelled(isUnallowed(SlimefunItem.getByItem(e.getCursor()))); + if (clickedInventory != null && topInventory.getType() == InventoryType.BREWING && topInventory.getHolder() instanceof BrewingStand) { + if (e.getAction() == InventoryAction.HOTBAR_SWAP) { + e.setCancelled(true); + return; + } + + if (clickedInventory.getType() == InventoryType.BREWING) { + e.setCancelled(isUnallowed(SlimefunItem.getByItem(e.getCursor()))); + } else { + e.setCancelled(isUnallowed(SlimefunItem.getByItem(e.getCurrentItem()))); + } + + if (e.getResult() == Result.DENY) { + SlimefunPlugin.getLocalization().sendMessage((Player) e.getWhoClicked(), "brewing_stand.not-working", true); + } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/VillagerTradingListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/VillagerTradingListener.java new file mode 100644 index 000000000..2f199a217 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/VillagerTradingListener.java @@ -0,0 +1,57 @@ +package io.github.thebusybiscuit.slimefun4.implementation.listeners; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event.Result; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; + +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem; +import io.github.thebusybiscuit.slimefun4.implementation.items.misc.SyntheticEmerald; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; + +/** + * This {@link Listener} prevents any {@link SlimefunItem} from being used to trade with + * Villagers, with one exception being {@link SyntheticEmerald}. + * + * @author TheBusyBiscuit + * + */ +public class VillagerTradingListener implements Listener { + + public VillagerTradingListener(SlimefunPlugin plugin) { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler(ignoreCancelled = true) + public void onPreBrew(InventoryClickEvent e) { + Inventory clickedInventory = e.getClickedInventory(); + Inventory topInventory = e.getView().getTopInventory(); + + if (clickedInventory != null && topInventory.getType() == InventoryType.MERCHANT) { + if (e.getAction() == InventoryAction.HOTBAR_SWAP) { + e.setCancelled(true); + return; + } + + if (clickedInventory.getType() == InventoryType.MERCHANT) { + e.setCancelled(isUnallowed(SlimefunItem.getByItem(e.getCursor()))); + } + else { + e.setCancelled(isUnallowed(SlimefunItem.getByItem(e.getCurrentItem()))); + } + + if (e.getResult() == Result.DENY) { + SlimefunPlugin.getLocalization().sendMessage((Player) e.getWhoClicked(), "villagers.no-trading", true); + } + } + } + + private boolean isUnallowed(SlimefunItem item) { + return item != null && !(item instanceof VanillaItem) && !(item instanceof SyntheticEmerald) && !item.isDisabled(); + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/WorldListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/WorldListener.java index 31b64d0c2..1e4617fae 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/WorldListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/WorldListener.java @@ -28,7 +28,7 @@ public class WorldListener implements Listener { BlockStorage storage = BlockStorage.getStorage(e.getWorld()); if (storage != null) { - storage.save(true); + storage.saveAndRemove(); } else { Slimefun.getLogger().log(Level.SEVERE, "Could not save Slimefun Blocks for World \"{0}\"", e.getWorld().getName()); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/ResearchSetup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/ResearchSetup.java index 1a0cca6d2..e6a363007 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/ResearchSetup.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/ResearchSetup.java @@ -110,7 +110,7 @@ public final class ResearchSetup { register("redstone_alloy", 84, "Redstone Alloy", 16, SlimefunItems.REDSTONE_ALLOY); register("carbonado_tools", 85, "Top Tier Machines", 24, SlimefunItems.CARBONADO_MULTI_TOOL, SlimefunItems.CARBONADO_JETPACK, SlimefunItems.CARBONADO_JETBOOTS); register("first_aid", 86, "First Aid", 2, SlimefunItems.CLOTH, SlimefunItems.RAG, SlimefunItems.BANDAGE, SlimefunItems.SPLINT, SlimefunItems.TIN_CAN, SlimefunItems.VITAMINS, SlimefunItems.MEDICINE); - register("gold_armor", 87, "Shiny Armor", 13, SlimefunItems.GOLD_HELMET, SlimefunItems.GOLD_CHESTPLATE, SlimefunItems.GOLD_LEGGINGS, SlimefunItems.GOLD_BOOTS); + register("gold_armor", 87, "Shiny Armor", 13, SlimefunItems.GOLDEN_HELMET_12K, SlimefunItems.GOLDEN_CHESTPLATE_12K, SlimefunItems.GOLDEN_LEGGINGS_12K, SlimefunItems.GOLDEN_BOOTS_12K); register("night_vision_googles", 89, "Night Vision Goggles", 10, SlimefunItems.NIGHT_VISION_GOGGLES); register("pickaxe_of_containment", 90, "Pickaxe of Containment", 14, SlimefunItems.PICKAXE_OF_CONTAINMENT, SlimefunItems.BROKEN_SPAWNER); register("hercules_pickaxe", 91, "Hercules Pickaxe", 28, SlimefunItems.HERCULES_PICKAXE); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java index 32ebda3d6..e39b0a16b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java @@ -25,7 +25,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem; import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar; import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AdvancedFarmerAndroid; -import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AndroidType; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.ButcherAndroid; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.FarmerAndroid; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.FisherAndroid; @@ -139,13 +138,13 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.Talisman; import io.github.thebusybiscuit.slimefun4.implementation.items.medical.Bandage; import io.github.thebusybiscuit.slimefun4.implementation.items.medical.Medicine; -import io.github.thebusybiscuit.slimefun4.implementation.items.medical.Rag; import io.github.thebusybiscuit.slimefun4.implementation.items.medical.Splint; import io.github.thebusybiscuit.slimefun4.implementation.items.medical.Vitamins; import io.github.thebusybiscuit.slimefun4.implementation.items.misc.BasicCircuitBoard; import io.github.thebusybiscuit.slimefun4.implementation.items.misc.CoolantCell; import io.github.thebusybiscuit.slimefun4.implementation.items.misc.OrganicFertilizer; import io.github.thebusybiscuit.slimefun4.implementation.items.misc.OrganicFood; +import io.github.thebusybiscuit.slimefun4.implementation.items.misc.SyntheticEmerald; import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.ArmorForge; import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.AutomatedPanningMachine; import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.Compressor; @@ -182,6 +181,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.IcyBow; import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SeismicAxe; import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SwordOfBeheading; import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.VampireBlade; +import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; @@ -202,7 +202,7 @@ public final class SlimefunItemSetup { private static final Material BLACK_DYE; private static final Material GREEN_DYE; - private static boolean alreadyRan = false; + private static boolean registeredItems = false; static { if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { @@ -219,1980 +219,1981 @@ public final class SlimefunItemSetup { } } - private SlimefunItemSetup() {} + private SlimefunItemSetup() {} - public static void setup(SlimefunPlugin plugin) { - if (alreadyRan) { - throw new UnsupportedOperationException("Slimefun Items can only be registered once!"); - } + public static void setup(SlimefunPlugin plugin) { + if (registeredItems) { + throw new UnsupportedOperationException("Slimefun Items can only be registered once!"); + } - alreadyRan = true; - DefaultCategories categories = new DefaultCategories(); - - new SlimefunItem(categories.weapons, SlimefunItems.GRANDMAS_WALKING_STICK, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.OAK_LOG), null, null, new ItemStack(Material.OAK_LOG), null, null, new ItemStack(Material.OAK_LOG), null}) - .register(plugin); - - new SlimefunItem(categories.weapons, SlimefunItems.GRANDPAS_WALKING_STICK, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.LEATHER), new ItemStack(Material.OAK_LOG), new ItemStack(Material.LEATHER), null, new ItemStack(Material.OAK_LOG), null, null, new ItemStack(Material.OAK_LOG), null}) - .register(plugin); - - new PortableCrafter(categories.usefulItems, SlimefunItems.PORTABLE_CRAFTER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.BOOK), new ItemStack(Material.CRAFTING_TABLE), null, null, null, null, null, null, null}) - .register(plugin); - - new FortuneCookie(categories.food, SlimefunItems.FORTUNE_COOKIE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.COOKIE), new ItemStack(Material.PAPER), null, null, null, null, null, null, null}) - .register(plugin); - - new DietCookie(categories.food, SlimefunItems.DIET_COOKIE, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {new ItemStack(Material.COOKIE), SlimefunItems.ELYTRA_SCALE, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.basicMachines, SlimefunItems.OUTPUT_CHEST, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.LEAD_INGOT, new ItemStack(Material.HOPPER), SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, new ItemStack(Material.CHEST), SlimefunItems.LEAD_INGOT, null, SlimefunItems.LEAD_INGOT, null}) - .register(plugin); - - new EnhancedCraftingTable(categories.basicMachines, SlimefunItems.ENHANCED_CRAFTING_TABLE).register(plugin); - - new PortableDustbin(categories.usefulItems, SlimefunItems.PORTABLE_DUSTBIN, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT)}) - .register(plugin); - - new MeatJerky(categories.food, SlimefunItems.BEEF_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.COOKED_BEEF), null, null, null, null, null, null, null}) - .register(plugin); - - new MeatJerky(categories.food, SlimefunItems.PORK_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.COOKED_PORKCHOP), null, null, null, null, null, null, null}) - .register(plugin); - - new MeatJerky(categories.food, SlimefunItems.CHICKEN_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.COOKED_CHICKEN), null, null, null, null, null, null, null}) - .register(plugin); - - new MeatJerky(categories.food, SlimefunItems.MUTTON_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.COOKED_MUTTON), null, null, null, null, null, null, null}) - .register(plugin); - - new MeatJerky(categories.food, SlimefunItems.RABBIT_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.COOKED_RABBIT), null, null, null, null, null, null, null}) - .register(plugin); - - new MeatJerky(categories.food, SlimefunItems.FISH_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.COOKED_COD), null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.food, SlimefunItems.KELP_COOKIE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.DRIED_KELP), null, new ItemStack(Material.DRIED_KELP), new ItemStack(Material.SUGAR), new ItemStack(Material.DRIED_KELP), null, new ItemStack(Material.DRIED_KELP), null}, - new CustomItem(SlimefunItems.KELP_COOKIE, 2)) - .register(plugin); - - new GrindStone(categories.basicMachines, SlimefunItems.GRIND_STONE).register(plugin); - new ArmorForge(categories.basicMachines, SlimefunItems.ARMOR_FORGE).register(plugin); - - OreCrusher oreCrusher = new OreCrusher(categories.basicMachines, SlimefunItems.ORE_CRUSHER); - oreCrusher.register(plugin); - - new Compressor(categories.basicMachines, SlimefunItems.COMPRESSOR).register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.MAGIC_LUMP_1, RecipeType.GRIND_STONE, - new ItemStack[] {new ItemStack(Material.NETHER_WART), null, null, null, null, null, null, null, null}, - new CustomItem(SlimefunItems.MAGIC_LUMP_1, 2)) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.MAGIC_LUMP_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_1, SlimefunItems.MAGIC_LUMP_1, null, SlimefunItems.MAGIC_LUMP_1, SlimefunItems.MAGIC_LUMP_1, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.MAGIC_LUMP_3, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_2, SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, SlimefunItems.MAGIC_LUMP_2, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.ENDER_LUMP_1, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, null, null, new ItemStack(Material.ENDER_EYE), null, null, null, null}, - new CustomItem(SlimefunItems.ENDER_LUMP_1, 2)) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.ENDER_LUMP_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.ENDER_LUMP_1, SlimefunItems.ENDER_LUMP_1, null, SlimefunItems.ENDER_LUMP_1, SlimefunItems.ENDER_LUMP_1, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.ENDER_LUMP_3, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.ENDER_LUMP_2, SlimefunItems.ENDER_LUMP_2, null, SlimefunItems.ENDER_LUMP_2, SlimefunItems.ENDER_LUMP_2, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.SYNTHETIC_SHULKER_SHELL, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {SlimefunItems.ENDER_LUMP_3, SlimefunItems.ENDER_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.REINFORCED_PLATE, new ItemStack(Material.TURTLE_HELMET), SlimefunItems.REINFORCED_PLATE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.ENDER_RUNE, SlimefunItems.ENDER_LUMP_3}) - .setUseableInWorkbench(true) - .register(plugin); - - new EnderBackpack(categories.magicalGadgets, SlimefunItems.ENDER_BACKPACK, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {SlimefunItems.ENDER_LUMP_2, new ItemStack(Material.LEATHER), SlimefunItems.ENDER_LUMP_2, new ItemStack(Material.LEATHER), new ItemStack(Material.CHEST), new ItemStack(Material.LEATHER), SlimefunItems.ENDER_LUMP_2, new ItemStack(Material.LEATHER), SlimefunItems.ENDER_LUMP_2}) - .register(plugin); - - new SlimefunItem(categories.magicalArmor, SlimefunItems.ENDER_HELMET, RecipeType.ARMOR_FORGE, - new ItemStack[] {SlimefunItems.ENDER_LUMP_1, new ItemStack(Material.ENDER_EYE), SlimefunItems.ENDER_LUMP_1, new ItemStack(Material.OBSIDIAN), null, new ItemStack(Material.OBSIDIAN), null, null, null}) - .register(plugin); - - new SlimefunItem(categories.magicalArmor, SlimefunItems.ENDER_CHESTPLATE, RecipeType.ARMOR_FORGE, - new ItemStack[] {SlimefunItems.ENDER_LUMP_1, null, SlimefunItems.ENDER_LUMP_1, new ItemStack(Material.OBSIDIAN), new ItemStack(Material.ENDER_EYE), new ItemStack(Material.OBSIDIAN), new ItemStack(Material.OBSIDIAN), new ItemStack(Material.OBSIDIAN), new ItemStack(Material.OBSIDIAN)}) - .register(plugin); - - new SlimefunItem(categories.magicalArmor, SlimefunItems.ENDER_LEGGINGS, RecipeType.ARMOR_FORGE, - new ItemStack[] {SlimefunItems.ENDER_LUMP_1, new ItemStack(Material.ENDER_EYE), SlimefunItems.ENDER_LUMP_1, new ItemStack(Material.OBSIDIAN), null, new ItemStack(Material.OBSIDIAN), new ItemStack(Material.OBSIDIAN), null, new ItemStack(Material.OBSIDIAN)}) - .register(plugin); - - new SlimefunItem(categories.magicalArmor, SlimefunItems.ENDER_BOOTS, RecipeType.ARMOR_FORGE, - new ItemStack[] {null, null, null, SlimefunItems.ENDER_LUMP_1, null, SlimefunItems.ENDER_LUMP_1, new ItemStack(Material.OBSIDIAN), null, new ItemStack(Material.OBSIDIAN)}) - .register(plugin); - - new MagicEyeOfEnder(categories.magicalGadgets, SlimefunItems.MAGIC_EYE_OF_ENDER, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {SlimefunItems.ENDER_LUMP_2, new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_2, new ItemStack(Material.ENDER_PEARL), new ItemStack(Material.ENDER_EYE), new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_2, new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_2}) - .register(plugin); - - new MagicSugar(categories.food, SlimefunItems.MAGIC_SUGAR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.REDSTONE), new ItemStack(Material.GLOWSTONE_DUST), null, null, null, null, null, null}) - .register(plugin); - - new MonsterJerky(categories.food, SlimefunItems.MONSTER_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.ROTTEN_FLESH), null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_HELMET, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT), null, null, null}, null) - .register(plugin); - - new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_CHESTPLATE, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT)}, null) - .register(plugin); - - new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_LEGGINGS, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT)}, - new PotionEffect[] {new PotionEffect(PotionEffectType.SPEED, 300, 2)}) - .register(plugin); - - new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_BOOTS, RecipeType.ARMOR_FORGE, - new ItemStack[] {null, null, null, new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT)}, - new PotionEffect[] {new PotionEffect(PotionEffectType.JUMP, 300, 5)}) - .register(plugin); - - new SwordOfBeheading(categories.weapons, SlimefunItems.SWORD_OF_BEHEADING, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.EMERALD), null, SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.EMERALD), SlimefunItems.MAGIC_LUMP_2, null, new ItemStack(Material.BLAZE_ROD), null}) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.MAGICAL_BOOK_COVER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.BOOK), SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, null}) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.MAGICAL_GLASS, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_2, SlimefunItems.GOLD_DUST, SlimefunItems.MAGIC_LUMP_2, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, new ItemStack(Material.GLASS_PANE), SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.MAGIC_LUMP_2, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.MAGIC_LUMP_2}) - .register(plugin); - - new BasicCircuitBoard(categories.technicalComponents, SlimefunItems.BASIC_CIRCUIT_BOARD, RecipeType.MOB_DROP, - new ItemStack[] {null, null, null, null, new CustomItem(SlimefunUtils.getCustomHead("89091d79ea0f59ef7ef94d7bba6e5f17f2f7d4572c44f90f76c4819a714"), "&aIron Golem"), null, null, null, null}) - .register(plugin); - - new UnplaceableBlock(categories.technicalComponents, SlimefunItems.ADVANCED_CIRCUIT_BOARD, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.REDSTONE_BLOCK), SlimefunItems.BASIC_CIRCUIT_BOARD, new ItemStack(Material.REDSTONE_BLOCK), new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.LAPIS_BLOCK)}) - .register(plugin); - - new GoldPan(categories.tools, SlimefunItems.GOLD_PAN, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, null, new ItemStack(Material.STONE), new ItemStack(Material.BOWL), new ItemStack(Material.STONE), new ItemStack(Material.STONE), new ItemStack(Material.STONE), new ItemStack(Material.STONE)}) - .register(plugin); - - new NetherGoldPan(categories.tools, SlimefunItems.NETHER_GOLD_PAN, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, null, new ItemStack(Material.NETHER_BRICK), SlimefunItems.GOLD_PAN, new ItemStack(Material.NETHER_BRICK), new ItemStack(Material.NETHER_BRICK), new ItemStack(Material.NETHER_BRICK), new ItemStack(Material.NETHER_BRICK)}) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.SIFTED_ORE, RecipeType.GOLD_PAN, - new ItemStack[] {new ItemStack(Material.GRAVEL), null, null, null, null, null, null, null, null}) - .register(plugin); - - new MakeshiftSmeltery(categories.basicMachines, SlimefunItems.MAKESHIFT_SMELTERY).register(plugin); - new Smeltery(categories.basicMachines, SlimefunItems.SMELTERY).register(plugin); - - new SlimefunItem(categories.basicMachines, SlimefunItems.IGNITION_CHAMBER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.IRON_INGOT), new ItemStack(Material.FLINT_AND_STEEL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), SlimefunItems.BASIC_CIRCUIT_BOARD, new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.OBSERVER), null}) - .register(plugin); - - new PressureChamber(categories.basicMachines, SlimefunItems.PRESSURE_CHAMBER).register(plugin); - - new SlimefunItem(categories.technicalComponents, SlimefunItems.BATTERY, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.REDSTONE), null, SlimefunItems.ZINC_INGOT, SlimefunItems.SULFATE, SlimefunItems.COPPER_INGOT, SlimefunItems.ZINC_INGOT, SlimefunItems.SULFATE, SlimefunItems.COPPER_INGOT}) - .register(plugin); - - registerArmorSet(categories.magicalArmor, new ItemStack(Material.GLOWSTONE), new ItemStack[] {SlimefunItems.GLOWSTONE_HELMET, SlimefunItems.GLOWSTONE_CHESTPLATE, SlimefunItems.GLOWSTONE_LEGGINGS, SlimefunItems.GLOWSTONE_BOOTS}, "GLOWSTONE", - new PotionEffect[][] { - new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)}, - new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)}, - new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)}, - new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)} - }, plugin); - - registerArmorSet(categories.armor, SlimefunItems.DAMASCUS_STEEL_INGOT, new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_HELMET, SlimefunItems.DAMASCUS_STEEL_CHESTPLATE, SlimefunItems.DAMASCUS_STEEL_LEGGINGS, SlimefunItems.DAMASCUS_STEEL_BOOTS}, "DAMASCUS_STEEL", false, plugin); - - registerArmorSet(categories.armor, SlimefunItems.REINFORCED_ALLOY_INGOT, new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_HELMET, SlimefunItems.REINFORCED_ALLOY_CHESTPLATE, SlimefunItems.REINFORCED_ALLOY_LEGGINGS, SlimefunItems.REINFORCED_ALLOY_BOOTS}, "REINFORCED_ALLOY", false, plugin); - - registerArmorSet(categories.armor, new ItemStack(Material.CACTUS), new ItemStack[] {SlimefunItems.CACTUS_HELMET, SlimefunItems.CACTUS_CHESTPLATE, SlimefunItems.CACTUS_LEGGINGS, SlimefunItems.CACTUS_BOOTS}, "CACTUS", false, plugin); - - new SlimefunItem(categories.resources, SlimefunItems.REINFORCED_ALLOY_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.SOLDER_INGOT, SlimefunItems.BILLON_INGOT, SlimefunItems.GOLD_24K, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.HARDENED_METAL_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.ALUMINUM_BRONZE_INGOT, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.DAMASCUS_STEEL_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.STEEL_INGOT, SlimefunItems.IRON_DUST, SlimefunItems.CARBON, new ItemStack(Material.IRON_INGOT), null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.STEEL_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.IRON_DUST, SlimefunItems.CARBON, new ItemStack(Material.IRON_INGOT), null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.BRONZE_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.COPPER_DUST, SlimefunItems.TIN_DUST, SlimefunItems.COPPER_INGOT, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.DURALUMIN_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.ALUMINUM_DUST, SlimefunItems.COPPER_DUST, SlimefunItems.ALUMINUM_INGOT, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.BILLON_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.SILVER_DUST, SlimefunItems.COPPER_DUST, SlimefunItems.SILVER_INGOT, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.BRASS_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.COPPER_DUST, SlimefunItems.ZINC_DUST, SlimefunItems.COPPER_INGOT, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.ALUMINUM_BRASS_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.ALUMINUM_DUST, SlimefunItems.BRASS_INGOT, SlimefunItems.ALUMINUM_INGOT, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.ALUMINUM_BRONZE_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.ALUMINUM_DUST, SlimefunItems.BRONZE_INGOT, SlimefunItems.ALUMINUM_INGOT, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.CORINTHIAN_BRONZE_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.SILVER_DUST, SlimefunItems.GOLD_DUST, SlimefunItems.COPPER_DUST, SlimefunItems.BRONZE_INGOT, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.SOLDER_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.LEAD_DUST, SlimefunItems.TIN_DUST, SlimefunItems.LEAD_INGOT, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.SYNTHETIC_SAPPHIRE, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.ALUMINUM_DUST, new ItemStack(Material.GLASS), new ItemStack(Material.GLASS_PANE), SlimefunItems.ALUMINUM_INGOT, new ItemStack(Material.LAPIS_LAZULI), null, null, null, null}) - .setUseableInWorkbench(true) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.SYNTHETIC_DIAMOND, RecipeType.PRESSURE_CHAMBER, - new ItemStack[] {SlimefunItems.CARBON_CHUNK, null, null, null, null, null, null, null, null}) - .setUseableInWorkbench(true) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.RAW_CARBONADO, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.SYNTHETIC_DIAMOND, SlimefunItems.CARBON_CHUNK, new ItemStack(Material.GLASS_PANE), null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.NICKEL_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.IRON_DUST, new ItemStack(Material.IRON_INGOT), SlimefunItems.COPPER_DUST, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.COBALT_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.IRON_DUST, SlimefunItems.COPPER_DUST, SlimefunItems.NICKEL_INGOT, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.CARBONADO, RecipeType.PRESSURE_CHAMBER, - new ItemStack[] {SlimefunItems.RAW_CARBONADO, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.FERROSILICON, RecipeType.SMELTERY, - new ItemStack[] {new ItemStack(Material.IRON_INGOT), SlimefunItems.IRON_DUST, SlimefunItems.SILICON, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.IRON_DUST, RecipeType.ORE_CRUSHER, - new ItemStack[] {new ItemStack(Material.IRON_ORE), null, null, null, null, null, null, null, null}, - new CustomItem(SlimefunItems.IRON_DUST, oreCrusher.isOreDoublingEnabled() ? 2 : 1)) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.GOLD_DUST, RecipeType.ORE_CRUSHER, - new ItemStack[] {new ItemStack(Material.GOLD_ORE), null, null, null, null, null, null, null, null}, - new CustomItem(SlimefunItems.GOLD_DUST, oreCrusher.isOreDoublingEnabled() ? 2 : 1)) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.COPPER_DUST, RecipeType.ORE_WASHER, - new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.TIN_DUST, RecipeType.ORE_WASHER, - new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.LEAD_DUST, RecipeType.ORE_WASHER, - new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.SILVER_DUST, RecipeType.ORE_WASHER, - new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.ALUMINUM_DUST, RecipeType.ORE_WASHER, - new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.ZINC_DUST, RecipeType.ORE_WASHER, - new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.MAGNESIUM_DUST, RecipeType.ORE_WASHER, - new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.COPPER_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.COPPER_DUST, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.TIN_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.TIN_DUST, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.SILVER_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.SILVER_DUST, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.LEAD_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.LEAD_DUST, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.ALUMINUM_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.ALUMINUM_DUST, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.ZINC_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.ZINC_DUST, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.MAGNESIUM_INGOT, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.MAGNESIUM_DUST, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.SULFATE, RecipeType.ORE_CRUSHER, - new ItemStack[] {new ItemStack(Material.NETHERRACK, 16), null, null, null, null, null, null, null, null}) - .register(plugin); - - new UnplaceableBlock(categories.resources, SlimefunItems.CARBON, RecipeType.COMPRESSOR, - new ItemStack[] {new ItemStack(Material.COAL, 8), null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.WHEAT_FLOUR, RecipeType.GRIND_STONE, - new ItemStack[] {new ItemStack(Material.WHEAT), null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.STEEL_PLATE, RecipeType.COMPRESSOR, - new ItemStack[] {new CustomItem(SlimefunItems.STEEL_INGOT, 8), null, null, null, null, null, null, null, null}) - .register(plugin); - - new UnplaceableBlock(categories.resources, SlimefunItems.COMPRESSED_CARBON, RecipeType.COMPRESSOR, - new ItemStack[] {new CustomItem(SlimefunItems.CARBON, 4), null, null, null, null, null, null, null, null}) - .register(plugin); - - new UnplaceableBlock(categories.resources, SlimefunItems.CARBON_CHUNK, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.COMPRESSED_CARBON, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.COMPRESSED_CARBON, new ItemStack(Material.FLINT), SlimefunItems.COMPRESSED_CARBON, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.COMPRESSED_CARBON}) - .register(plugin); - - new SlimefunItem(categories.technicalComponents, SlimefunItems.STEEL_THRUSTER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.REDSTONE), null, SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.STEEL_PLATE, new ItemStack(Material.FIRE_CHARGE), SlimefunItems.STEEL_PLATE}) - .register(plugin); - - new SlimefunItem(categories.technicalComponents, SlimefunItems.POWER_CRYSTAL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.REDSTONE), SlimefunItems.SYNTHETIC_SAPPHIRE, new ItemStack(Material.REDSTONE), SlimefunItems.SYNTHETIC_SAPPHIRE, SlimefunItems.SYNTHETIC_DIAMOND, SlimefunItems.SYNTHETIC_SAPPHIRE, new ItemStack(Material.REDSTONE), SlimefunItems.SYNTHETIC_SAPPHIRE, new ItemStack(Material.REDSTONE)}) - .register(plugin); - - new Jetpack(categories.technicalGadgets, SlimefunItems.DURALUMIN_JETPACK, - new ItemStack[] {SlimefunItems.DURALUMIN_INGOT, null, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.35, 20) - .register(plugin); - - new Jetpack(categories.technicalGadgets, SlimefunItems.SOLDER_JETPACK, - new ItemStack[] {SlimefunItems.SOLDER_INGOT, null, SlimefunItems.SOLDER_INGOT, SlimefunItems.SOLDER_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.SOLDER_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.4, 30) - .register(plugin); - - new Jetpack(categories.technicalGadgets, SlimefunItems.BILLON_JETPACK, - new ItemStack[] {SlimefunItems.BILLON_INGOT, null, SlimefunItems.BILLON_INGOT, SlimefunItems.BILLON_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.BILLON_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.45, 45) - .register(plugin); - - new Jetpack(categories.technicalGadgets, SlimefunItems.STEEL_JETPACK, - new ItemStack[] {SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.5, 60) - .register(plugin); - - new Jetpack(categories.technicalGadgets, SlimefunItems.DAMASCUS_STEEL_JETPACK, - new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_INGOT, null, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.55, 75) - .register(plugin); - - new Jetpack(categories.technicalGadgets, SlimefunItems.REINFORCED_ALLOY_JETPACK, - new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_INGOT, null, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.6, 100) - .register(plugin); - - new Jetpack(categories.technicalGadgets, SlimefunItems.CARBONADO_JETPACK, - new ItemStack[] {SlimefunItems.CARBON_CHUNK, null, SlimefunItems.CARBON_CHUNK, SlimefunItems.CARBONADO, SlimefunItems.POWER_CRYSTAL, SlimefunItems.CARBONADO, SlimefunItems.STEEL_THRUSTER, SlimefunItems.LARGE_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.7, 150) - .register(plugin); - - new Parachute(categories.technicalGadgets, SlimefunItems.PARACHUTE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.CHAIN, null, SlimefunItems.CHAIN, null, null, null}) - .register(plugin); - - new HologramProjector(categories.technicalGadgets, SlimefunItems.HOLOGRAM_PROJECTOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.POWER_CRYSTAL, null, SlimefunItems.ALUMINUM_BRASS_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_BRASS_INGOT, null, SlimefunItems.ALUMINUM_BRASS_INGOT, null}, - new CustomItem(SlimefunItems.HOLOGRAM_PROJECTOR, 3)) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.CHAIN, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null, null}, - new CustomItem(SlimefunItems.CHAIN, 8)) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.HOOK, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null, null, null}) - .register(plugin); - - new GrapplingHook(categories.tools, SlimefunItems.GRAPPLING_HOOK, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, SlimefunItems.HOOK, null, SlimefunItems.CHAIN, null, SlimefunItems.CHAIN, null, null}) - .register(plugin); - - new MagicWorkbench(categories.basicMachines, SlimefunItems.MAGIC_WORKBENCH).register(plugin); - - new SlimefunItem(categories.magicalGadgets, SlimefunItems.STAFF_ELEMENTAL, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.MAGICAL_BOOK_COVER, SlimefunItems.MAGIC_LUMP_3, null, new ItemStack(Material.STICK), SlimefunItems.MAGICAL_BOOK_COVER, SlimefunItems.MAGIC_LUMP_3, null, null}) - .register(plugin); - - new WindStaff(categories.magicalGadgets, SlimefunItems.STAFF_WIND, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, new ItemStack(Material.FEATHER), SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.STAFF_ELEMENTAL, new ItemStack(Material.FEATHER), SlimefunItems.STAFF_ELEMENTAL, null, null}) - .register(plugin); - - new WaterStaff(categories.magicalGadgets, SlimefunItems.STAFF_WATER, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, new ItemStack(Material.LILY_PAD), SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.STAFF_ELEMENTAL, new ItemStack(Material.LILY_PAD), SlimefunItems.STAFF_ELEMENTAL, null, null}) - .register(plugin); - - String[] multiToolItems = new String[] {"PORTABLE_CRAFTER", "MAGIC_EYE_OF_ENDER", "STAFF_ELEMENTAL_WIND", "GRAPPLING_HOOK"}; - - new MultiTool(categories.technicalGadgets, SlimefunItems.DURALUMIN_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.DURALUMIN_INGOT, null, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.DURALUMIN_INGOT, null, SlimefunItems.DURALUMIN_INGOT, null}, - 20, multiToolItems) - .register(plugin); - - new MultiTool(categories.technicalGadgets, SlimefunItems.SOLDER_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SOLDER_INGOT, null, SlimefunItems.SOLDER_INGOT, SlimefunItems.SOLDER_INGOT, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.SOLDER_INGOT, null, SlimefunItems.SOLDER_INGOT, null}, - 30, multiToolItems) - .register(plugin); - - new MultiTool(categories.technicalGadgets, SlimefunItems.BILLON_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.BILLON_INGOT, null, SlimefunItems.BILLON_INGOT, SlimefunItems.BILLON_INGOT, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.BILLON_INGOT, null, SlimefunItems.BILLON_INGOT, null}, - 40, multiToolItems) - .register(plugin); - - new MultiTool(categories.technicalGadgets, SlimefunItems.STEEL_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_INGOT, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null}, - 50, multiToolItems) - .register(plugin); - - new MultiTool(categories.technicalGadgets, SlimefunItems.DAMASCUS_STEEL_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_INGOT, null, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.DAMASCUS_STEEL_INGOT, null, SlimefunItems.DAMASCUS_STEEL_INGOT, null}, - 60, multiToolItems) - .register(plugin); - - new MultiTool(categories.technicalGadgets, SlimefunItems.REINFORCED_ALLOY_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_INGOT, null, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.REINFORCED_ALLOY_INGOT, null, SlimefunItems.REINFORCED_ALLOY_INGOT, null}, - 75, multiToolItems) - .register(plugin); - - new MultiTool(categories.technicalGadgets, SlimefunItems.CARBONADO_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CARBONADO, null, SlimefunItems.CARBONADO, SlimefunItems.CARBONADO, SlimefunItems.LARGE_CAPACITOR, SlimefunItems.CARBONADO, null, SlimefunItems.CARBONADO, null}, - 100, "PORTABLE_CRAFTER", "MAGIC_EYE_OF_ENDER", "STAFF_ELEMENTAL_WIND", "GRAPPLING_HOOK", "GOLD_PAN", "NETHER_GOLD_PAN") - .register(plugin); - - new OreWasher(categories.basicMachines, SlimefunItems.ORE_WASHER).register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.GOLD_24K, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_22K, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.GOLD_22K, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_20K, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.GOLD_20K, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_18K, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.GOLD_18K, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_16K, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.GOLD_16K, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_14K, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.GOLD_14K, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_12K, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.GOLD_12K, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_10K, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.GOLD_10K, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_8K, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.GOLD_8K, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_6K, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.GOLD_6K, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_4K, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.GOLD_4K, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.GOLD_DUST, null, null, null, null, null, null, null, null}) - .setUseableInWorkbench(true) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.STONE_CHUNK, RecipeType.ORE_WASHER, - new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.SILICON, RecipeType.SMELTERY, - new ItemStack[] {new ItemStack(Material.QUARTZ_BLOCK), null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.technicalComponents, SlimefunItems.SOLAR_PANEL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), SlimefunItems.SILICON, SlimefunItems.SILICON, SlimefunItems.SILICON, SlimefunItems.FERROSILICON, SlimefunItems.FERROSILICON, SlimefunItems.FERROSILICON}) - .register(plugin); - - new SolarHelmet(categories.technicalGadgets, SlimefunItems.SOLAR_HELMET, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.SOLAR_PANEL, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, null, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.MEDIUM_CAPACITOR, null, SlimefunItems.MEDIUM_CAPACITOR}, - 0.1) - .register(plugin); - - new UnplaceableBlock(categories.magicalResources, SlimefunItems.LAVA_CRYSTAL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.BLAZE_POWDER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.BLAZE_POWDER), SlimefunItems.FIRE_RUNE, new ItemStack(Material.BLAZE_POWDER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.BLAZE_POWDER), SlimefunItems.MAGIC_LUMP_1}) - .register(plugin); - - new SlimefunItem(categories.magicalGadgets, SlimefunItems.STAFF_FIRE, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, null, SlimefunItems.LAVA_CRYSTAL, null, SlimefunItems.STAFF_ELEMENTAL, null, SlimefunItems.STAFF_ELEMENTAL, null, null}) - .register(plugin); - - if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { - new StormStaff(categories.magicalGadgets, SlimefunItems.STAFF_STORM, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {SlimefunItems.LIGHTNING_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.LIGHTNING_RUNE, SlimefunItems.STAFF_WATER, SlimefunItems.MAGIC_SUGAR, SlimefunItems.STAFF_WIND, SlimefunItems.LIGHTNING_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.LIGHTNING_RUNE}) - .register(plugin); - - ItemStack weaknessPotion = new ItemStack(Material.POTION); - PotionMeta meta = (PotionMeta) weaknessPotion.getItemMeta(); - meta.setBasePotionData(new PotionData(PotionType.WEAKNESS, false, false)); - weaknessPotion.setItemMeta(meta); - - new MagicalZombiePills(categories.magicalGadgets, SlimefunItems.MAGICAL_ZOMBIE_PILLS, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {new ItemStack(Material.GOLD_INGOT), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.GOLD_INGOT), new ItemStack(Material.APPLE), weaknessPotion, new ItemStack(Material.APPLE), new ItemStack(Material.GOLD_INGOT), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.GOLD_INGOT)}, - new CustomItem(SlimefunItems.MAGICAL_ZOMBIE_PILLS, 2)) - .register(plugin); - } - - new SmeltersPickaxe(categories.tools, SlimefunItems.SMELTERS_PICKAXE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.LAVA_CRYSTAL, SlimefunItems.LAVA_CRYSTAL, SlimefunItems.LAVA_CRYSTAL, null, SlimefunItems.FERROSILICON, null, null, SlimefunItems.FERROSILICON, null}) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.COMMON_TALISMAN, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_2, SlimefunItems.GOLD_8K, SlimefunItems.MAGIC_LUMP_2, null, new ItemStack(Material.EMERALD), null, SlimefunItems.MAGIC_LUMP_2, SlimefunItems.GOLD_8K, SlimefunItems.MAGIC_LUMP_2}) - .register(plugin); - - new Talisman(SlimefunItems.TALISMAN_ANVIL, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.ANVIL), SlimefunItems.COMMON_TALISMAN, new ItemStack(Material.ANVIL), SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, - true, false, "anvil") - .register(plugin); - - new Talisman(SlimefunItems.TALISMAN_MINER, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.SYNTHETIC_SAPPHIRE, SlimefunItems.COMMON_TALISMAN, SlimefunItems.SIFTED_ORE, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, - false, false, "miner", 20) - .register(plugin); - - new Talisman(SlimefunItems.TALISMAN_HUNTER, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.SYNTHETIC_SAPPHIRE, SlimefunItems.COMMON_TALISMAN, SlimefunItems.MONSTER_JERKY, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, - false, false, "hunter", 20) - .register(plugin); - - new Talisman(SlimefunItems.TALISMAN_LAVA, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.LAVA_CRYSTAL, SlimefunItems.COMMON_TALISMAN, new ItemStack(Material.LAVA_BUCKET), SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, - true, true, "lava", new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 3600, 4)) - .register(plugin); - - new Talisman(SlimefunItems.TALISMAN_WATER, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.WATER_BUCKET), SlimefunItems.COMMON_TALISMAN, new ItemStack(Material.FISHING_ROD), SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, - true, true, "water", new PotionEffect(PotionEffectType.WATER_BREATHING, 3600, 4)) - .register(plugin); - - new Talisman(SlimefunItems.TALISMAN_ANGEL, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.FEATHER), SlimefunItems.COMMON_TALISMAN, new ItemStack(Material.FEATHER), SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, - false, true, "angel", 75) - .register(plugin); - - new Talisman(SlimefunItems.TALISMAN_FIRE, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.LAVA_CRYSTAL, SlimefunItems.COMMON_TALISMAN, SlimefunItems.LAVA_CRYSTAL, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, - true, true, "fire", new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 3600, 4)) - .register(plugin); - - new MagicianTalisman(SlimefunItems.TALISMAN_MAGICIAN, - new ItemStack[] {SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.ENCHANTING_TABLE), SlimefunItems.COMMON_TALISMAN, new ItemStack(Material.ENCHANTING_TABLE), SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3}) - .register(plugin); - - new Talisman(SlimefunItems.TALISMAN_TRAVELLER, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.STAFF_WIND, SlimefunItems.TALISMAN_ANGEL, SlimefunItems.STAFF_WIND, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, - false, false, "traveller", 60, new PotionEffect(PotionEffectType.SPEED, 3600, 2)) - .register(plugin); - - new Talisman(SlimefunItems.TALISMAN_WARRIOR, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.COMMON_TALISMAN, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, - true, true, "warrior", new PotionEffect(PotionEffectType.INCREASE_DAMAGE, 3600, 2)) - .register(plugin); - - new Talisman(SlimefunItems.TALISMAN_KNIGHT, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.GILDED_IRON, SlimefunItems.TALISMAN_WARRIOR, SlimefunItems.GILDED_IRON, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, - "knight", 30, new PotionEffect(PotionEffectType.REGENERATION, 100, 3)) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.GILDED_IRON, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.GOLD_24K, SlimefunItems.IRON_DUST, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.SYNTHETIC_EMERALD, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.SYNTHETIC_SAPPHIRE, SlimefunItems.ALUMINUM_DUST, SlimefunItems.ALUMINUM_INGOT, new ItemStack(Material.GLASS_PANE), null, null, null, null, null}) - .setUseableInWorkbench(true) - .register(plugin); - - registerArmorSet(categories.armor, SlimefunItems.CHAIN, new ItemStack[] { - new ItemStack(Material.CHAINMAIL_HELMET), new ItemStack(Material.CHAINMAIL_CHESTPLATE), new ItemStack(Material.CHAINMAIL_LEGGINGS), new ItemStack(Material.CHAINMAIL_BOOTS) - }, "CHAIN", true, plugin); - - new Talisman(SlimefunItems.TALISMAN_WHIRLWIND, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.STAFF_WIND, SlimefunItems.TALISMAN_TRAVELLER, SlimefunItems.STAFF_WIND, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3} - , false, true, "whirlwind", 60) - .register(plugin); - - new Talisman(SlimefunItems.TALISMAN_WIZARD, - new ItemStack[] {SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3, SlimefunItems.MAGIC_EYE_OF_ENDER, SlimefunItems.TALISMAN_MAGICIAN, SlimefunItems.MAGIC_EYE_OF_ENDER, SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3}, - false, false, "wizard", 60) - .register(plugin); - - new LumberAxe(categories.tools, SlimefunItems.LUMBER_AXE, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {SlimefunItems.SYNTHETIC_DIAMOND, SlimefunItems.SYNTHETIC_DIAMOND, null, SlimefunItems.SYNTHETIC_EMERALD, SlimefunItems.GILDED_IRON, null, null, SlimefunItems.GILDED_IRON, null}) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.SALT, RecipeType.ORE_WASHER, - new ItemStack[] {new ItemStack(Material.SAND, 2), null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.HEAVY_CREAM, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.MILK_BUCKET), null, null, null, null, null, null, null, null}, - new CustomItem(SlimefunItems.HEAVY_CREAM, 2)) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.CHEESE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.MILK_BUCKET), SlimefunItems.SALT, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.BUTTER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.HEAVY_CREAM, SlimefunItems.SALT, null, null, null, null, null, null, null}) - .register(plugin); - - registerArmorSet(categories.armor, SlimefunItems.GILDED_IRON, new ItemStack[] { - SlimefunItems.GILDED_IRON_HELMET, SlimefunItems.GILDED_IRON_CHESTPLATE, SlimefunItems.GILDED_IRON_LEGGINGS, SlimefunItems.GILDED_IRON_BOOTS - }, "GILDED_IRON", false, plugin); - - new SlimefunItem(categories.technicalComponents, SlimefunItems.REINFORCED_CLOTH, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.CLOTH, null, SlimefunItems.CLOTH, SlimefunItems.LEAD_INGOT, SlimefunItems.CLOTH, null, SlimefunItems.CLOTH, null}, new SlimefunItemStack(SlimefunItems.REINFORCED_CLOTH, 2)) - .register(plugin); - - new HazmatArmorPiece(categories.armor, SlimefunItems.SCUBA_HELMET, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.ORANGE_WOOL), SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.ORANGE_WOOL), SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.GLASS_PANE), SlimefunItems.REINFORCED_CLOTH, null, null, null}, - new PotionEffect[] {new PotionEffect(PotionEffectType.WATER_BREATHING, 300, 1)}) - .register(plugin); - - new HazmatArmorPiece(categories.armor, SlimefunItems.HAZMAT_CHESTPLATE, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.ORANGE_WOOL), null, new ItemStack(Material.ORANGE_WOOL), SlimefunItems.REINFORCED_CLOTH, SlimefunItems.REINFORCED_CLOTH, SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.BLACK_WOOL), SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.BLACK_WOOL)}, - new PotionEffect[] {new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 300, 1)}) - .register(plugin); - - new HazmatArmorPiece(categories.armor, SlimefunItems.HAZMAT_LEGGINGS, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.BLACK_WOOL), SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.BLACK_WOOL), SlimefunItems.REINFORCED_CLOTH, null, SlimefunItems.REINFORCED_CLOTH, SlimefunItems.REINFORCED_CLOTH, null, SlimefunItems.REINFORCED_CLOTH}, new PotionEffect[0]) - .register(plugin); - - new HazmatArmorPiece(categories.armor, SlimefunItems.HAZMAT_BOOTS, RecipeType.ARMOR_FORGE, - new ItemStack[] {SlimefunItems.REINFORCED_CLOTH, null, SlimefunItems.REINFORCED_CLOTH, SlimefunItems.REINFORCED_CLOTH, null, SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.BLACK_WOOL), null, new ItemStack(Material.BLACK_WOOL)}, new PotionEffect[0]) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.CRUSHED_ORE, RecipeType.ORE_CRUSHER, - new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.PULVERIZED_ORE, RecipeType.ORE_CRUSHER, - new ItemStack[] {SlimefunItems.CRUSHED_ORE, null, null, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.PURE_ORE_CLUSTER, RecipeType.ORE_WASHER, - new ItemStack[] {SlimefunItems.PULVERIZED_ORE, null, null, null, null, null, null, null, null}) - .register(plugin); - - new UnplaceableBlock(categories.misc, SlimefunItems.TINY_URANIUM, RecipeType.ORE_CRUSHER, - new ItemStack[] {SlimefunItems.PURE_ORE_CLUSTER, null, null, null, null, null, null, null, null}) - .register(plugin); - - new RadioactiveItem(categories.misc, Radioactivity.MODERATE, SlimefunItems.SMALL_URANIUM, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM}) - .register(plugin); - - new RadioactiveItem(categories.resources, Radioactivity.HIGH, SlimefunItems.URANIUM, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SMALL_URANIUM, SlimefunItems.SMALL_URANIUM, null, SlimefunItems.SMALL_URANIUM, SlimefunItems.SMALL_URANIUM, null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.REDSTONE_ALLOY, RecipeType.SMELTERY, - new ItemStack[] {new ItemStack(Material.REDSTONE), new ItemStack(Material.REDSTONE_BLOCK), SlimefunItems.FERROSILICON, SlimefunItems.HARDENED_METAL_INGOT, null, null, null, null, null}) - .register(plugin); - - registerArmorSet(categories.armor, SlimefunItems.GOLD_12K, new ItemStack[] { - SlimefunItems.GOLD_HELMET, SlimefunItems.GOLD_CHESTPLATE, SlimefunItems.GOLD_LEGGINGS, SlimefunItems.GOLD_BOOTS - }, "GOLD_12K", false, plugin); - - new SlimefunItem(categories.misc, SlimefunItems.CLOTH, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.WHITE_WOOL), null, null, null, null, null, null, null, null}, - new CustomItem(SlimefunItems.CLOTH, 8)) - .register(plugin); - - new Rag(categories.usefulItems, SlimefunItems.RAG, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.CLOTH, new ItemStack(Material.STRING), null, new ItemStack(Material.STRING), SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.CLOTH}) - .register(plugin); - - new Bandage(categories.usefulItems, SlimefunItems.BANDAGE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.RAG, new ItemStack(Material.STRING), SlimefunItems.RAG, null, null, null, null, null, null}, - new CustomItem(SlimefunItems.BANDAGE, 4)) - .register(plugin); - - new Splint(categories.usefulItems, SlimefunItems.SPLINT, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.STICK), new ItemStack(Material.STICK), new ItemStack(Material.STICK), null, new ItemStack(Material.IRON_INGOT), null}, - new CustomItem(SlimefunItems.SPLINT, 4)) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.TIN_CAN, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, null, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT}, - new CustomItem(SlimefunItems.TIN_CAN, 8)) - .register(plugin); - - new Vitamins(categories.usefulItems, SlimefunItems.VITAMINS, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.TIN_CAN, new ItemStack(Material.APPLE), new ItemStack(Material.RED_MUSHROOM), new ItemStack(Material.SUGAR), null, null, null, null, null}) - .register(plugin); - - new Medicine(categories.usefulItems, SlimefunItems.MEDICINE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.VITAMINS, new ItemStack(Material.GLASS_BOTTLE), SlimefunItems.HEAVY_CREAM, null, null, null, null, null, null}) - .register(plugin); - - new SlimefunArmorPiece(categories.technicalGadgets, SlimefunItems.NIGHT_VISION_GOGGLES, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.COAL_BLOCK), new ItemStack(Material.COAL_BLOCK), new ItemStack(Material.COAL_BLOCK), new ItemStack(Material.LIME_STAINED_GLASS_PANE), new ItemStack(Material.COAL_BLOCK), new ItemStack(Material.LIME_STAINED_GLASS_PANE), new ItemStack(Material.COAL_BLOCK), null, new ItemStack(Material.COAL_BLOCK)}, - new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 20)}) - .register(plugin); - - new PickaxeOfContainment(categories.tools, SlimefunItems.PICKAXE_OF_CONTAINMENT, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {SlimefunItems.FERROSILICON, SlimefunItems.FERROSILICON, SlimefunItems.FERROSILICON, null, SlimefunItems.GILDED_IRON, null, null, SlimefunItems.GILDED_IRON, null}) - .register(plugin); - - new HerculesPickaxe(categories.tools, SlimefunItems.HERCULES_PICKAXE, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.HARDENED_METAL_INGOT, null, SlimefunItems.FERROSILICON, null, null, SlimefunItems.FERROSILICON, null}) - .register(plugin); + registeredItems = true; + DefaultCategories categories = new DefaultCategories(); - if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { - new TableSaw(categories.basicMachines, SlimefunItems.TABLE_SAW).register(plugin); - } + new SlimefunItem(categories.weapons, SlimefunItems.GRANDMAS_WALKING_STICK, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.OAK_LOG), null, null, new ItemStack(Material.OAK_LOG), null, null, new ItemStack(Material.OAK_LOG), null}) + .register(plugin); + + new SlimefunItem(categories.weapons, SlimefunItems.GRANDPAS_WALKING_STICK, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.LEATHER), new ItemStack(Material.OAK_LOG), new ItemStack(Material.LEATHER), null, new ItemStack(Material.OAK_LOG), null, null, new ItemStack(Material.OAK_LOG), null}) + .register(plugin); - new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_HELMET_STEEL, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), null, null, null}, null) - .register(plugin); + new PortableCrafter(categories.usefulItems, SlimefunItems.PORTABLE_CRAFTER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.BOOK), new ItemStack(Material.CRAFTING_TABLE), null, null, null, null, null, null, null}) + .register(plugin); - new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_CHESTPLATE_STEEL, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL)}, null) - .register(plugin); + new FortuneCookie(categories.food, SlimefunItems.FORTUNE_COOKIE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.COOKIE), new ItemStack(Material.PAPER), null, null, null, null, null, null, null}) + .register(plugin); - new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_LEGGINGS_STEEL, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL)}, - new PotionEffect[] {new PotionEffect(PotionEffectType.SPEED, 300, 2)}) - .register(plugin); + new DietCookie(categories.food, SlimefunItems.DIET_COOKIE, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {new ItemStack(Material.COOKIE), SlimefunItems.ELYTRA_SCALE, null, null, null, null, null, null, null}) + .register(plugin); - new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_BOOTS_STEEL, RecipeType.ARMOR_FORGE, - new ItemStack[] {null, null, null, new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL)}, - new PotionEffect[] {new PotionEffect(PotionEffectType.JUMP, 300, 5)}) - .register(plugin); + new SlimefunItem(categories.basicMachines, SlimefunItems.OUTPUT_CHEST, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.LEAD_INGOT, new ItemStack(Material.HOPPER), SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, new ItemStack(Material.CHEST), SlimefunItems.LEAD_INGOT, null, SlimefunItems.LEAD_INGOT, null}) + .register(plugin); + + new EnhancedCraftingTable(categories.basicMachines, SlimefunItems.ENHANCED_CRAFTING_TABLE).register(plugin); - new VampireBlade(categories.weapons, SlimefunItems.BLADE_OF_VAMPIRES, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, null, new ItemStack(Material.BLAZE_ROD), null}) - .register(plugin); + new PortableDustbin(categories.usefulItems, SlimefunItems.PORTABLE_DUSTBIN, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT)}) + .register(plugin); - new SlimefunItem(categories.misc, SlimefunItems.GOLD_24K_BLOCK, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K}) - .register(plugin); + new MeatJerky(categories.food, SlimefunItems.BEEF_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.COOKED_BEEF), null, null, null, null, null, null, null}) + .register(plugin); - new Composter(categories.basicMachines, SlimefunItems.COMPOSTER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.OAK_SLAB), null, new ItemStack(Material.OAK_SLAB), new ItemStack(Material.OAK_SLAB), null, new ItemStack(Material.OAK_SLAB), new ItemStack(Material.OAK_SLAB), new ItemStack(Material.CAULDRON), new ItemStack(Material.OAK_SLAB)}) - .register(plugin); + new MeatJerky(categories.food, SlimefunItems.PORK_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.COOKED_PORKCHOP), null, null, null, null, null, null, null}) + .register(plugin); - new SlimefunItem(categories.magicalArmor, SlimefunItems.FARMER_SHOES, RecipeType.ARMOR_FORGE, - new ItemStack[] {null, null, null, new ItemStack(Material.HAY_BLOCK), null, new ItemStack(Material.HAY_BLOCK), new ItemStack(Material.HAY_BLOCK), null, new ItemStack(Material.HAY_BLOCK)}) - .register(plugin); - - new ExplosivePickaxe(categories.tools, SlimefunItems.EXPLOSIVE_PICKAXE, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {new ItemStack(Material.TNT), SlimefunItems.SYNTHETIC_DIAMOND, new ItemStack(Material.TNT), null, SlimefunItems.FERROSILICON, null, null, SlimefunItems.FERROSILICON, null}) - .register(plugin); + new MeatJerky(categories.food, SlimefunItems.CHICKEN_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.COOKED_CHICKEN), null, null, null, null, null, null, null}) + .register(plugin); - new ExplosiveShovel(categories.tools, SlimefunItems.EXPLOSIVE_SHOVEL, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.SYNTHETIC_DIAMOND, null, null, new ItemStack(Material.TNT), null, null, SlimefunItems.FERROSILICON, null}) - .register(plugin); + new MeatJerky(categories.food, SlimefunItems.MUTTON_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.COOKED_MUTTON), null, null, null, null, null, null, null}) + .register(plugin); - new AutomatedPanningMachine(categories.basicMachines, SlimefunItems.AUTOMATED_PANNING_MACHINE).register(plugin); - - new IndustrialMiner(categories.basicMachines, SlimefunItems.INDUSTRIAL_MINER, Material.IRON_BLOCK, false, 3).register(plugin); - new AdvancedIndustrialMiner(categories.basicMachines, SlimefunItems.ADVANCED_INDUSTRIAL_MINER).register(plugin); + new MeatJerky(categories.food, SlimefunItems.RABBIT_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.COOKED_RABBIT), null, null, null, null, null, null, null}) + .register(plugin); - new SlimefunItem(categories.magicalArmor, SlimefunItems.BOOTS_OF_THE_STOMPER, RecipeType.ARMOR_FORGE, - new ItemStack[] {null, null, null, new ItemStack(Material.YELLOW_WOOL), null, new ItemStack(Material.YELLOW_WOOL), new ItemStack(Material.PISTON), null, new ItemStack(Material.PISTON)}) - .register(plugin); + new MeatJerky(categories.food, SlimefunItems.FISH_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.COOKED_COD), null, null, null, null, null, null, null}) + .register(plugin); - new PickaxeOfTheSeeker(categories.tools, SlimefunItems.PICKAXE_OF_THE_SEEKER, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {new ItemStack(Material.COMPASS), SlimefunItems.SYNTHETIC_DIAMOND, new ItemStack(Material.COMPASS), null, SlimefunItems.FERROSILICON, null, null, SlimefunItems.FERROSILICON, null}) - .register(plugin); + new SlimefunItem(categories.food, SlimefunItems.KELP_COOKIE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.DRIED_KELP), null, new ItemStack(Material.DRIED_KELP), new ItemStack(Material.SUGAR), new ItemStack(Material.DRIED_KELP), null, new ItemStack(Material.DRIED_KELP), null}, + new SlimefunItemStack(SlimefunItems.KELP_COOKIE, 2)) + .register(plugin); - new SlimefunBackpack(9, categories.usefulItems, SlimefunItems.BACKPACK_SMALL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.LEATHER), null, new ItemStack(Material.LEATHER), SlimefunItems.GOLD_6K, new ItemStack(Material.CHEST), SlimefunItems.GOLD_6K, new ItemStack(Material.LEATHER), new ItemStack(Material.LEATHER), new ItemStack(Material.LEATHER)}) - .register(plugin); + new GrindStone(categories.basicMachines, SlimefunItems.GRIND_STONE).register(plugin); + new ArmorForge(categories.basicMachines, SlimefunItems.ARMOR_FORGE).register(plugin); + + OreCrusher oreCrusher = new OreCrusher(categories.basicMachines, SlimefunItems.ORE_CRUSHER); + oreCrusher.register(plugin); + + new Compressor(categories.basicMachines, SlimefunItems.COMPRESSOR).register(plugin); - new SlimefunBackpack(18, categories.usefulItems, SlimefunItems.BACKPACK_MEDIUM, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.LEATHER), null, new ItemStack(Material.LEATHER), SlimefunItems.GOLD_10K, SlimefunItems.BACKPACK_SMALL, SlimefunItems.GOLD_10K, new ItemStack(Material.LEATHER), new ItemStack(Material.LEATHER), new ItemStack(Material.LEATHER)}) - .register(plugin); + new SlimefunItem(categories.magicalResources, SlimefunItems.MAGIC_LUMP_1, RecipeType.GRIND_STONE, + new ItemStack[] {new ItemStack(Material.NETHER_WART), null, null, null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.MAGIC_LUMP_1, 2)) + .register(plugin); - new SlimefunBackpack(27, categories.usefulItems, SlimefunItems.BACKPACK_LARGE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.LEATHER), null, new ItemStack(Material.LEATHER), SlimefunItems.GOLD_14K, SlimefunItems.BACKPACK_MEDIUM, SlimefunItems.GOLD_14K, new ItemStack(Material.LEATHER), new ItemStack(Material.LEATHER), new ItemStack(Material.LEATHER)}) - .register(plugin); + new SlimefunItem(categories.magicalResources, SlimefunItems.MAGIC_LUMP_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_1, SlimefunItems.MAGIC_LUMP_1, null, SlimefunItems.MAGIC_LUMP_1, SlimefunItems.MAGIC_LUMP_1, null, null, null, null}) + .register(plugin); - new SlimefunBackpack(36, categories.usefulItems, SlimefunItems.WOVEN_BACKPACK, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CLOTH, null, SlimefunItems.CLOTH, SlimefunItems.GOLD_16K, SlimefunItems.BACKPACK_LARGE, SlimefunItems.GOLD_16K, SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.CLOTH}) - .register(plugin); + new SlimefunItem(categories.magicalResources, SlimefunItems.MAGIC_LUMP_3, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_2, SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, SlimefunItems.MAGIC_LUMP_2, null, null, null, null}) + .register(plugin); - new Crucible(categories.basicMachines, SlimefunItems.CRUCIBLE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.TERRACOTTA), null, new ItemStack(Material.TERRACOTTA), new ItemStack(Material.TERRACOTTA), null, new ItemStack(Material.TERRACOTTA), new ItemStack(Material.TERRACOTTA), new ItemStack(Material.FLINT_AND_STEEL), new ItemStack(Material.TERRACOTTA)}) - .register(plugin); + new SlimefunItem(categories.magicalResources, SlimefunItems.ENDER_LUMP_1, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, null, null, new ItemStack(Material.ENDER_EYE), null, null, null, null}, + new SlimefunItemStack(SlimefunItems.ENDER_LUMP_1, 2)) + .register(plugin); - new SlimefunBackpack(45, categories.usefulItems, SlimefunItems.GILDED_BACKPACK, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.GOLD_22K, null, SlimefunItems.GOLD_22K, new ItemStack(Material.LEATHER), SlimefunItems.WOVEN_BACKPACK, new ItemStack(Material.LEATHER), SlimefunItems.GOLD_22K, null, SlimefunItems.GOLD_22K}) - .register(plugin); + new SlimefunItem(categories.magicalResources, SlimefunItems.ENDER_LUMP_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.ENDER_LUMP_1, SlimefunItems.ENDER_LUMP_1, null, SlimefunItems.ENDER_LUMP_1, SlimefunItems.ENDER_LUMP_1, null, null, null, null}) + .register(plugin); - new SlimefunBackpack(54, categories.usefulItems, SlimefunItems.RADIANT_BACKPACK, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.GOLD_24K, null, SlimefunItems.GOLD_24K, new ItemStack(Material.LEATHER), SlimefunItems.GILDED_BACKPACK, new ItemStack(Material.LEATHER), SlimefunItems.GOLD_24K, null, SlimefunItems.GOLD_24K}) - .register(plugin); - - new RestoredBackpack(categories.usefulItems).register(plugin); - - new SlimefunItem(categories.technicalComponents, SlimefunItems.MAGNET, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.NICKEL_INGOT, SlimefunItems.ALUMINUM_DUST, SlimefunItems.IRON_DUST, SlimefunItems.COBALT_INGOT, null, null, null, null, null}) - .register(plugin); - - new InfusedMagnet(categories.magicalGadgets, SlimefunItems.INFUSED_MAGNET, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ENDER_LUMP_2, SlimefunItems.MAGNET, SlimefunItems.ENDER_LUMP_2, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}) - .register(plugin); - - new SlimefunItem(categories.tools, SlimefunItems.COBALT_PICKAXE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.COBALT_INGOT, SlimefunItems.COBALT_INGOT, SlimefunItems.COBALT_INGOT, null, SlimefunItems.NICKEL_INGOT, null, null, SlimefunItems.NICKEL_INGOT, null}) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.NECROTIC_SKULL, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.ESSENCE_OF_AFTERLIFE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {SlimefunItems.ENDER_LUMP_3, SlimefunItems.AIR_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.EARTH_RUNE, SlimefunItems.NECROTIC_SKULL, SlimefunItems.FIRE_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.WATER_RUNE, SlimefunItems.ENDER_LUMP_3}) - .register(plugin); - - new SoulboundBackpack(36, categories.magicalGadgets, SlimefunItems.BOUND_BACKPACK, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {SlimefunItems.ENDER_LUMP_2, null, SlimefunItems.ENDER_LUMP_2, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.WOVEN_BACKPACK, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.ENDER_LUMP_2, null, SlimefunItems.ENDER_LUMP_2}) - .register(plugin); - - new JetBoots(categories.technicalGadgets, SlimefunItems.DURALUMIN_JETBOOTS, - new ItemStack[] {null, null, null, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.35, 20) - .register(plugin); - - new JetBoots(categories.technicalGadgets, SlimefunItems.SOLDER_JETBOOTS, - new ItemStack[] {null, null, null, SlimefunItems.SOLDER_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.SOLDER_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.4, 30) - .register(plugin); - - new JetBoots(categories.technicalGadgets, SlimefunItems.BILLON_JETBOOTS, - new ItemStack[] {null, null, null, SlimefunItems.BILLON_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.BILLON_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.45, 40) - .register(plugin); - - new JetBoots(categories.technicalGadgets, SlimefunItems.STEEL_JETBOOTS, - new ItemStack[] {null, null, null, SlimefunItems.STEEL_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.5, 50) - .register(plugin); - - new JetBoots(categories.technicalGadgets, SlimefunItems.DAMASCUS_STEEL_JETBOOTS, - new ItemStack[] {null, null, null, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.55, 75) - .register(plugin); - - new JetBoots(categories.technicalGadgets, SlimefunItems.REINFORCED_ALLOY_JETBOOTS, - new ItemStack[] {null, null, null, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.6, 100) - .register(plugin); - - new JetBoots(categories.technicalGadgets, SlimefunItems.CARBONADO_JETBOOTS, - new ItemStack[] {null, null, null, SlimefunItems.CARBONADO, SlimefunItems.POWER_CRYSTAL, SlimefunItems.CARBONADO, SlimefunItems.STEEL_THRUSTER, SlimefunItems.LARGE_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.7, 125) - .register(plugin); - - new JetBoots(categories.technicalGadgets, SlimefunItems.ARMORED_JETBOOTS, - new ItemStack[] {null, null, null, SlimefunItems.STEEL_PLATE, SlimefunItems.POWER_CRYSTAL, SlimefunItems.STEEL_PLATE, SlimefunItems.STEEL_THRUSTER, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, - 0.45, 50) - .register(plugin); - - new SeismicAxe(categories.weapons, SlimefunItems.SEISMIC_AXE, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.HARDENED_METAL_INGOT, null, SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.STAFF_ELEMENTAL, null, null, SlimefunItems.STAFF_ELEMENTAL, null}) - .register(plugin); - - new PickaxeOfVeinMining(categories.tools, SlimefunItems.PICKAXE_OF_VEIN_MINING, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {new ItemStack(Material.EMERALD_ORE), SlimefunItems.SYNTHETIC_DIAMOND, new ItemStack(Material.EMERALD_ORE), null, SlimefunItems.GILDED_IRON, null, null, SlimefunItems.GILDED_IRON, null}) - .register(plugin); - - new SoulboundItem(categories.weapons, SlimefunItems.SOULBOUND_SWORD, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_SWORD), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) - .register(plugin); - - new SoulboundItem(categories.weapons, SlimefunItems.SOULBOUND_TRIDENT, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.TRIDENT), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) - .register(plugin); - - new SoulboundItem(categories.weapons, SlimefunItems.SOULBOUND_BOW, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.BOW), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) - .register(plugin); - - new SoulboundItem(categories.tools, SlimefunItems.SOULBOUND_PICKAXE, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_PICKAXE), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) - .register(plugin); - - new SoulboundItem(categories.tools, SlimefunItems.SOULBOUND_AXE, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_AXE), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) - .register(plugin); - - new SoulboundItem(categories.tools, SlimefunItems.SOULBOUND_SHOVEL, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_SHOVEL), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) - .register(plugin); - - new SoulboundItem(categories.tools, SlimefunItems.SOULBOUND_HOE, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_HOE), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) - .register(plugin); - - new SoulboundItem(categories.magicalArmor, SlimefunItems.SOULBOUND_HELMET, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_HELMET), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) - .register(plugin); - - new SoulboundItem(categories.magicalArmor, SlimefunItems.SOULBOUND_CHESTPLATE, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_CHESTPLATE), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) - .register(plugin); - - new SoulboundItem(categories.magicalArmor, SlimefunItems.SOULBOUND_LEGGINGS, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_LEGGINGS), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) - .register(plugin); - - new SoulboundItem(categories.magicalArmor, SlimefunItems.SOULBOUND_BOOTS, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_BOOTS), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) - .register(plugin); - - new Juicer(categories.basicMachines, SlimefunItems.JUICER).register(plugin); - - new Juice(categories.food, SlimefunItems.APPLE_JUICE, RecipeType.JUICER, - new ItemStack[] {new ItemStack(Material.APPLE), null, null, null, null, null, null, null, null}) - .register(plugin); - - new Juice(categories.food, SlimefunItems.CARROT_JUICE, RecipeType.JUICER, - new ItemStack[] {new ItemStack(Material.CARROT), null, null, null, null, null, null, null, null}) - .register(plugin); - - new Juice(categories.food, SlimefunItems.MELON_JUICE, RecipeType.JUICER, - new ItemStack[] {new ItemStack(Material.MELON_SLICE), null, null, null, null, null, null, null, null}) - .register(plugin); - - new Juice(categories.food, SlimefunItems.PUMPKIN_JUICE, RecipeType.JUICER, - new ItemStack[] {new ItemStack(Material.PUMPKIN), null, null, null, null, null, null, null, null}) - .register(plugin); - - if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { - new Juice(categories.food, SlimefunItems.SWEET_BERRY_JUICE, RecipeType.JUICER, - new ItemStack[] {new ItemStack(Material.SWEET_BERRIES), null, null, null, null, null, null, null, null}) + new SlimefunItem(categories.magicalResources, SlimefunItems.ENDER_LUMP_3, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.ENDER_LUMP_2, SlimefunItems.ENDER_LUMP_2, null, SlimefunItems.ENDER_LUMP_2, SlimefunItems.ENDER_LUMP_2, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.magicalResources, SlimefunItems.SYNTHETIC_SHULKER_SHELL, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {SlimefunItems.ENDER_LUMP_3, SlimefunItems.ENDER_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.REINFORCED_PLATE, new ItemStack(Material.TURTLE_HELMET), SlimefunItems.REINFORCED_PLATE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.ENDER_RUNE, SlimefunItems.ENDER_LUMP_3}) + .setUseableInWorkbench(true) .register(plugin); - } - new Juice(categories.food, SlimefunItems.GOLDEN_APPLE_JUICE, RecipeType.JUICER, - new ItemStack[] {new ItemStack(Material.GOLDEN_APPLE), null, null, null, null, null, null, null, null}) - .register(plugin); + new EnderBackpack(categories.magicalGadgets, SlimefunItems.ENDER_BACKPACK, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {SlimefunItems.ENDER_LUMP_2, new ItemStack(Material.LEATHER), SlimefunItems.ENDER_LUMP_2, new ItemStack(Material.LEATHER), new ItemStack(Material.CHEST), new ItemStack(Material.LEATHER), SlimefunItems.ENDER_LUMP_2, new ItemStack(Material.LEATHER), SlimefunItems.ENDER_LUMP_2}) + .register(plugin); - new BrokenSpawner(categories.magicalResources, SlimefunItems.BROKEN_SPAWNER, new RecipeType(new NamespacedKey(plugin, "pickaxe_of_containment"), SlimefunItems.PICKAXE_OF_CONTAINMENT), - new ItemStack[] {null, null, null, null, new ItemStack(Material.SPAWNER), null, null, null, null}) - .register(plugin); + new SlimefunItem(categories.magicalArmor, SlimefunItems.ENDER_HELMET, RecipeType.ARMOR_FORGE, + new ItemStack[] {SlimefunItems.ENDER_LUMP_1, new ItemStack(Material.ENDER_EYE), SlimefunItems.ENDER_LUMP_1, new ItemStack(Material.OBSIDIAN), null, new ItemStack(Material.OBSIDIAN), null, null, null}) + .register(plugin); - new RepairedSpawner(categories.magicalGadgets, SlimefunItems.REPAIRED_SPAWNER, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {SlimefunItems.ENDER_RUNE, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.BROKEN_SPAWNER, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.ENDER_RUNE}) - .register(plugin); + new SlimefunItem(categories.magicalArmor, SlimefunItems.ENDER_CHESTPLATE, RecipeType.ARMOR_FORGE, + new ItemStack[] {SlimefunItems.ENDER_LUMP_1, null, SlimefunItems.ENDER_LUMP_1, new ItemStack(Material.OBSIDIAN), new ItemStack(Material.ENDER_EYE), new ItemStack(Material.OBSIDIAN), new ItemStack(Material.OBSIDIAN), new ItemStack(Material.OBSIDIAN), new ItemStack(Material.OBSIDIAN)}) + .register(plugin); - new EnhancedFurnace(categories.basicMachines, 1, 1, 1, SlimefunItems.ENHANCED_FURNACE, - new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, new ItemStack(Material.FURNACE), SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) - .register(plugin); + new SlimefunItem(categories.magicalArmor, SlimefunItems.ENDER_LEGGINGS, RecipeType.ARMOR_FORGE, + new ItemStack[] {SlimefunItems.ENDER_LUMP_1, new ItemStack(Material.ENDER_EYE), SlimefunItems.ENDER_LUMP_1, new ItemStack(Material.OBSIDIAN), null, new ItemStack(Material.OBSIDIAN), new ItemStack(Material.OBSIDIAN), null, new ItemStack(Material.OBSIDIAN)}) + .register(plugin); - new EnhancedFurnace(categories.basicMachines, 2, 1, 1, SlimefunItems.ENHANCED_FURNACE_2, - new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) - .register(plugin); + new SlimefunItem(categories.magicalArmor, SlimefunItems.ENDER_BOOTS, RecipeType.ARMOR_FORGE, + new ItemStack[] {null, null, null, SlimefunItems.ENDER_LUMP_1, null, SlimefunItems.ENDER_LUMP_1, new ItemStack(Material.OBSIDIAN), null, new ItemStack(Material.OBSIDIAN)}) + .register(plugin); - new EnhancedFurnace(categories.basicMachines, 2, 2, 1, SlimefunItems.ENHANCED_FURNACE_3, - new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_2, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) - .register(plugin); + new MagicEyeOfEnder(categories.magicalGadgets, SlimefunItems.MAGIC_EYE_OF_ENDER, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {SlimefunItems.ENDER_LUMP_2, new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_2, new ItemStack(Material.ENDER_PEARL), new ItemStack(Material.ENDER_EYE), new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_2, new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_2}) + .register(plugin); - new EnhancedFurnace(categories.basicMachines, 3, 2, 1, SlimefunItems.ENHANCED_FURNACE_4, - new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_3, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) - .register(plugin); + new MagicSugar(categories.food, SlimefunItems.MAGIC_SUGAR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.REDSTONE), new ItemStack(Material.GLOWSTONE_DUST), null, null, null, null, null, null}) + .register(plugin); - new EnhancedFurnace(categories.basicMachines, 3, 2, 2, SlimefunItems.ENHANCED_FURNACE_5, - new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_4, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) - .register(plugin); + new MonsterJerky(categories.food, SlimefunItems.MONSTER_JERKY, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.ROTTEN_FLESH), null, null, null, null, null, null, null}) + .register(plugin); - new EnhancedFurnace(categories.basicMachines, 3, 3, 2, SlimefunItems.ENHANCED_FURNACE_6, - new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_5, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) - .register(plugin); + new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_HELMET, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT), null, null, null}, null) + .register(plugin); - new EnhancedFurnace(categories.basicMachines, 4, 3, 2, SlimefunItems.ENHANCED_FURNACE_7, - new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_6, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) - .register(plugin); + new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_CHESTPLATE, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT)}, null) + .register(plugin); - new EnhancedFurnace(categories.basicMachines, 4, 4, 2, SlimefunItems.ENHANCED_FURNACE_8, - new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_7, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) - .register(plugin); + new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_LEGGINGS, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT)}, + new PotionEffect[] {new PotionEffect(PotionEffectType.SPEED, 300, 2)}) + .register(plugin); - new EnhancedFurnace(categories.basicMachines, 5, 4, 2, SlimefunItems.ENHANCED_FURNACE_9, - new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_8, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) - .register(plugin); + new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_BOOTS, RecipeType.ARMOR_FORGE, + new ItemStack[] {null, null, null, new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT)}, + new PotionEffect[] {new PotionEffect(PotionEffectType.JUMP, 300, 5)}) + .register(plugin); - new EnhancedFurnace(categories.basicMachines, 5, 5, 2, SlimefunItems.ENHANCED_FURNACE_10, - new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_9, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) - .register(plugin); + new SwordOfBeheading(categories.weapons, SlimefunItems.SWORD_OF_BEHEADING, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.EMERALD), null, SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.EMERALD), SlimefunItems.MAGIC_LUMP_2, null, new ItemStack(Material.BLAZE_ROD), null}) + .register(plugin); - new EnhancedFurnace(categories.basicMachines, 5, 5, 3, SlimefunItems.ENHANCED_FURNACE_11, - new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_10, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) - .register(plugin); + new SlimefunItem(categories.magicalResources, SlimefunItems.MAGICAL_BOOK_COVER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.BOOK), SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, null}) + .register(plugin); - new EnhancedFurnace(categories.basicMachines, 10, 10, 3, SlimefunItems.REINFORCED_FURNACE, - new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.ENHANCED_FURNACE_11, SlimefunItems.HEATING_COIL, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT}) - .register(plugin); + new SlimefunItem(categories.magicalResources, SlimefunItems.MAGICAL_GLASS, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_2, SlimefunItems.GOLD_DUST, SlimefunItems.MAGIC_LUMP_2, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, new ItemStack(Material.GLASS_PANE), SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.MAGIC_LUMP_2, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.MAGIC_LUMP_2}) + .register(plugin); - new EnhancedFurnace(categories.basicMachines, 20, 10, 3, SlimefunItems.CARBONADO_EDGED_FURNACE, - new ItemStack[] {SlimefunItems.CARBONADO, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.CARBONADO, SlimefunItems.HEATING_COIL, SlimefunItems.REINFORCED_FURNACE, SlimefunItems.HEATING_COIL, SlimefunItems.CARBONADO, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.CARBONADO}) - .register(plugin); + new BasicCircuitBoard(categories.technicalComponents, SlimefunItems.BASIC_CIRCUIT_BOARD, RecipeType.MOB_DROP, + new ItemStack[] {null, null, null, null, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.IRON_GOLEM.getTexture()), "&aIron Golem"), null, null, null, null}) + .register(plugin); - new SlimefunItem(categories.technicalComponents, SlimefunItems.ELECTRO_MAGNET, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.NICKEL_INGOT, SlimefunItems.MAGNET, SlimefunItems.COBALT_INGOT, null, SlimefunItems.BATTERY, null, null, null, null}) - .register(plugin); + new UnplaceableBlock(categories.technicalComponents, SlimefunItems.ADVANCED_CIRCUIT_BOARD, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.REDSTONE_BLOCK), SlimefunItems.BASIC_CIRCUIT_BOARD, new ItemStack(Material.REDSTONE_BLOCK), new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.LAPIS_BLOCK)}) + .register(plugin); - new SlimefunItem(categories.technicalComponents, SlimefunItems.ELECTRIC_MOTOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, null, SlimefunItems.ELECTRO_MAGNET, null, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE}) - .register(plugin); + new GoldPan(categories.tools, SlimefunItems.GOLD_PAN, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, null, new ItemStack(Material.STONE), new ItemStack(Material.BOWL), new ItemStack(Material.STONE), new ItemStack(Material.STONE), new ItemStack(Material.STONE), new ItemStack(Material.STONE)}) + .register(plugin); - new SlimefunItem(categories.technicalComponents, SlimefunItems.HEATING_COIL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE}) - .register(plugin); + new NetherGoldPan(categories.tools, SlimefunItems.NETHER_GOLD_PAN, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, null, new ItemStack(Material.NETHER_BRICK), SlimefunItems.GOLD_PAN, new ItemStack(Material.NETHER_BRICK), new ItemStack(Material.NETHER_BRICK), new ItemStack(Material.NETHER_BRICK), new ItemStack(Material.NETHER_BRICK)}) + .register(plugin); - new SlimefunItem(categories.technicalComponents, SlimefunItems.COPPER_WIRE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, null, SlimefunItems.COPPER_INGOT, SlimefunItems.COPPER_INGOT, SlimefunItems.COPPER_INGOT, null, null, null}, - new CustomItem(SlimefunItems.COPPER_WIRE, 8)) - .register(plugin); - - new BlockPlacer(categories.basicMachines, SlimefunItems.BLOCK_PLACER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.GOLD_4K, new ItemStack(Material.PISTON), SlimefunItems.GOLD_4K, new ItemStack(Material.IRON_INGOT), SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.IRON_INGOT), SlimefunItems.GOLD_4K, new ItemStack(Material.PISTON), SlimefunItems.GOLD_4K}) - .register(plugin); + new SlimefunItem(categories.misc, SlimefunItems.SIFTED_ORE, RecipeType.GOLD_PAN, + new ItemStack[] {new ItemStack(Material.GRAVEL), null, null, null, null, null, null, null, null}) + .register(plugin); - new TelepositionScroll(categories.magicalGadgets, SlimefunItems.SCROLL_OF_DIMENSIONAL_TELEPOSITION, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, SlimefunItems.ENDER_LUMP_3, SlimefunItems.MAGIC_EYE_OF_ENDER, SlimefunItems.ENDER_LUMP_3, SlimefunItems.MAGICAL_BOOK_COVER, SlimefunItems.ENDER_LUMP_3, SlimefunItems.MAGIC_EYE_OF_ENDER, SlimefunItems.ENDER_LUMP_3, null}) - .register(plugin); + new MakeshiftSmeltery(categories.basicMachines, SlimefunItems.MAKESHIFT_SMELTERY).register(plugin); + new Smeltery(categories.basicMachines, SlimefunItems.SMELTERY).register(plugin); + + new SlimefunItem(categories.basicMachines, SlimefunItems.IGNITION_CHAMBER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.IRON_INGOT), new ItemStack(Material.FLINT_AND_STEEL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), SlimefunItems.BASIC_CIRCUIT_BOARD, new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.OBSERVER), null}) + .register(plugin); + + new PressureChamber(categories.basicMachines, SlimefunItems.PRESSURE_CHAMBER).register(plugin); - new ExplosiveBow(categories.weapons, SlimefunItems.EXPLOSIVE_BOW, - new ItemStack[] {null, new ItemStack(Material.STICK), new ItemStack(Material.GUNPOWDER), SlimefunItems.STAFF_FIRE, null, SlimefunItems.SULFATE, null, new ItemStack(Material.STICK), new ItemStack(Material.GUNPOWDER)}) - .register(plugin); + new SlimefunItem(categories.technicalComponents, SlimefunItems.BATTERY, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.REDSTONE), null, SlimefunItems.ZINC_INGOT, SlimefunItems.SULFATE, SlimefunItems.COPPER_INGOT, SlimefunItems.ZINC_INGOT, SlimefunItems.SULFATE, SlimefunItems.COPPER_INGOT}) + .register(plugin); - new IcyBow(categories.weapons, SlimefunItems.ICY_BOW, - new ItemStack[] {null, new ItemStack(Material.STICK), new ItemStack(Material.ICE), SlimefunItems.STAFF_WATER, null, new ItemStack(Material.PACKED_ICE), null, new ItemStack(Material.STICK), new ItemStack(Material.ICE)}) - .register(plugin); + registerArmorSet(categories.magicalArmor, new ItemStack(Material.GLOWSTONE), new ItemStack[] {SlimefunItems.GLOWSTONE_HELMET, SlimefunItems.GLOWSTONE_CHESTPLATE, SlimefunItems.GLOWSTONE_LEGGINGS, SlimefunItems.GLOWSTONE_BOOTS}, "GLOWSTONE", false, + new PotionEffect[][] { + new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)}, + new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)}, + new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)}, + new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)} + }, plugin); - new KnowledgeTome(categories.magicalGadgets, SlimefunItems.TOME_OF_KNOWLEDGE_SHARING, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, new ItemStack(Material.FEATHER), null, new ItemStack(Material.INK_SAC), SlimefunItems.MAGICAL_BOOK_COVER, new ItemStack(Material.GLASS_BOTTLE), null, new ItemStack(Material.WRITABLE_BOOK), null}) - .register(plugin); + registerArmorSet(categories.armor, SlimefunItems.DAMASCUS_STEEL_INGOT, new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_HELMET, SlimefunItems.DAMASCUS_STEEL_CHESTPLATE, SlimefunItems.DAMASCUS_STEEL_LEGGINGS, SlimefunItems.DAMASCUS_STEEL_BOOTS}, "DAMASCUS_STEEL", false, new PotionEffect[0][0], plugin); - new KnowledgeFlask(categories.magicalGadgets, SlimefunItems.FLASK_OF_KNOWLEDGE, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, null, null, SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.GLASS_PANE), SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, null}, - new CustomItem(SlimefunItems.FLASK_OF_KNOWLEDGE, 8)) - .register(plugin); + registerArmorSet(categories.armor, SlimefunItems.REINFORCED_ALLOY_INGOT, new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_HELMET, SlimefunItems.REINFORCED_ALLOY_CHESTPLATE, SlimefunItems.REINFORCED_ALLOY_LEGGINGS, SlimefunItems.REINFORCED_ALLOY_BOOTS}, "REINFORCED_ALLOY", false, new PotionEffect[0][0], plugin); - new BirthdayCake(categories.birthday, new SlimefunItemStack("BIRTHDAY_CAKE", Material.CAKE, "&bBirthday Cake"), RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.TORCH), null, new ItemStack(Material.SUGAR), new ItemStack(Material.CAKE), new ItemStack(Material.SUGAR), null, null, null}) - .register(plugin); + registerArmorSet(categories.armor, new ItemStack(Material.CACTUS), new ItemStack[] {SlimefunItems.CACTUS_HELMET, SlimefunItems.CACTUS_CHESTPLATE, SlimefunItems.CACTUS_LEGGINGS, SlimefunItems.CACTUS_BOOTS}, "CACTUS", false, new PotionEffect[0][0], plugin); - new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_MILK, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.MILK_BUCKET), new ItemStack(Material.GLASS_BOTTLE), null, null, null, null, null, null, null}, - new CustomItem(SlimefunItems.CHRISTMAS_MILK, 4)) - .register(plugin); + new SlimefunItem(categories.resources, SlimefunItems.REINFORCED_ALLOY_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.SOLDER_INGOT, SlimefunItems.BILLON_INGOT, SlimefunItems.GOLD_24K, null, null, null}) + .register(plugin); - new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_CHOCOLATE_MILK, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CHRISTMAS_MILK, new ItemStack(Material.COCOA_BEANS), null, null, null, null, null, null, null}, - new CustomItem(SlimefunItems.CHRISTMAS_CHOCOLATE_MILK, 2)) - .register(plugin); + new SlimefunItem(categories.resources, SlimefunItems.HARDENED_METAL_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.ALUMINUM_BRONZE_INGOT, null, null, null, null, null}) + .register(plugin); - new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_EGG_NOG, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CHRISTMAS_MILK, new ItemStack(Material.EGG), null, null, null, null, null, null, null}, - new CustomItem(SlimefunItems.CHRISTMAS_EGG_NOG, 2)) - .register(plugin); + new SlimefunItem(categories.resources, SlimefunItems.DAMASCUS_STEEL_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.STEEL_INGOT, SlimefunItems.IRON_DUST, SlimefunItems.CARBON, new ItemStack(Material.IRON_INGOT), null, null, null, null, null}) + .register(plugin); - new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_APPLE_CIDER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.APPLE_JUICE, new ItemStack(Material.SUGAR), null, null, null, null, null, null, null}, - new CustomItem(SlimefunItems.CHRISTMAS_APPLE_CIDER, 2)) - .register(plugin); + new SlimefunItem(categories.resources, SlimefunItems.STEEL_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.IRON_DUST, SlimefunItems.CARBON, new ItemStack(Material.IRON_INGOT), null, null, null, null, null, null}) + .register(plugin); - new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_COOKIE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.COOKIE), new ItemStack(Material.SUGAR), new ItemStack(Material.LIME_DYE), null, null, null, null, null, null}, - new CustomItem(SlimefunItems.CHRISTMAS_COOKIE, 16)) - .register(plugin); + new SlimefunItem(categories.resources, SlimefunItems.BRONZE_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.COPPER_DUST, SlimefunItems.TIN_DUST, SlimefunItems.COPPER_INGOT, null, null, null, null, null, null}) + .register(plugin); - new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_FRUIT_CAKE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.EGG), new ItemStack(Material.APPLE), new ItemStack(Material.MELON), new ItemStack(Material.SUGAR), null, null, null, null, null}, - new CustomItem(SlimefunItems.CHRISTMAS_FRUIT_CAKE, 4)) - .register(plugin); + new SlimefunItem(categories.resources, SlimefunItems.DURALUMIN_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.ALUMINUM_DUST, SlimefunItems.COPPER_DUST, SlimefunItems.ALUMINUM_INGOT, null, null, null, null, null, null}) + .register(plugin); - new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_APPLE_PIE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.APPLE), new ItemStack(Material.EGG), null, null, null, null, null, null}, - new CustomItem(SlimefunItems.CHRISTMAS_APPLE_PIE, 2)) - .register(plugin); + new SlimefunItem(categories.resources, SlimefunItems.BILLON_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.SILVER_DUST, SlimefunItems.COPPER_DUST, SlimefunItems.SILVER_INGOT, null, null, null, null, null, null}) + .register(plugin); - new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_HOT_CHOCOLATE, RecipeType.SMELTERY, - new ItemStack[] {SlimefunItems.CHRISTMAS_CHOCOLATE_MILK, null, null, null, null, null, null, null, null}, SlimefunItems.CHRISTMAS_HOT_CHOCOLATE) - .register(plugin); + new SlimefunItem(categories.resources, SlimefunItems.BRASS_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.COPPER_DUST, SlimefunItems.ZINC_DUST, SlimefunItems.COPPER_INGOT, null, null, null, null, null, null}) + .register(plugin); - new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_CAKE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.EGG), new ItemStack(Material.SUGAR), SlimefunItems.WHEAT_FLOUR, new ItemStack(Material.MILK_BUCKET), null, null, null, null, null}, - new CustomItem(SlimefunItems.CHRISTMAS_CAKE, 4)) - .register(plugin); + new SlimefunItem(categories.resources, SlimefunItems.ALUMINUM_BRASS_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.ALUMINUM_DUST, SlimefunItems.BRASS_INGOT, SlimefunItems.ALUMINUM_INGOT, null, null, null, null, null, null}) + .register(plugin); - new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_CARAMEL, RecipeType.SMELTERY, - new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.SUGAR), null, null, null, null, null, null, null}, - new CustomItem(SlimefunItems.CHRISTMAS_CARAMEL, 4)) - .register(plugin); + new SlimefunItem(categories.resources, SlimefunItems.ALUMINUM_BRONZE_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.ALUMINUM_DUST, SlimefunItems.BRONZE_INGOT, SlimefunItems.ALUMINUM_INGOT, null, null, null, null, null, null}) + .register(plugin); - new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_CARAMEL_APPLE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.CHRISTMAS_CARAMEL, null, null, new ItemStack(Material.APPLE), null, null, new ItemStack(Material.STICK), null}, - new CustomItem(SlimefunItems.CHRISTMAS_CARAMEL_APPLE, 2)) - .register(plugin); + new SlimefunItem(categories.resources, SlimefunItems.CORINTHIAN_BRONZE_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.SILVER_DUST, SlimefunItems.GOLD_DUST, SlimefunItems.COPPER_DUST, SlimefunItems.BRONZE_INGOT, null, null, null, null, null}) + .register(plugin); - new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_CHOCOLATE_APPLE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.COCOA_BEANS), null, null, new ItemStack(Material.APPLE), null, null, new ItemStack(Material.STICK), null}, - new CustomItem(SlimefunItems.CHRISTMAS_CHOCOLATE_APPLE, 2)) - .register(plugin); + new SlimefunItem(categories.resources, SlimefunItems.SOLDER_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.LEAD_DUST, SlimefunItems.TIN_DUST, SlimefunItems.LEAD_INGOT, null, null, null, null, null, null}) + .register(plugin); - new ChristmasPresent(categories.christmas, SlimefunItems.CHRISTMAS_PRESENT, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, new ItemStack(Material.NAME_TAG), null, new ItemStack(Material.RED_WOOL), new ItemStack(Material.GREEN_WOOL), new ItemStack(Material.RED_WOOL), new ItemStack(Material.RED_WOOL), new ItemStack(Material.GREEN_WOOL), new ItemStack(Material.RED_WOOL)}, - new CustomItem(SlimefunItems.CHRISTMAS_HOT_CHOCOLATE, 1), - new CustomItem(SlimefunItems.CHRISTMAS_CHOCOLATE_APPLE, 4), - new CustomItem(SlimefunItems.CHRISTMAS_CARAMEL_APPLE, 4), - new CustomItem(SlimefunItems.CHRISTMAS_CAKE, 4), - new CustomItem(SlimefunItems.CHRISTMAS_COOKIE, 8), - new CustomItem(SlimefunItems.CHRISTMAS_PRESENT, 1), - new CustomItem(SlimefunItems.CHRISTMAS_EGG_NOG, 1), - new CustomItem(SlimefunItems.CHRISTMAS_MILK, 1), - new CustomItem(SlimefunItems.CHRISTMAS_APPLE_CIDER, 1), - new CustomItem(SlimefunItems.CHRISTMAS_FRUIT_CAKE, 4), - new CustomItem(SlimefunItems.CHRISTMAS_APPLE_PIE, 4), + new SlimefunItem(categories.resources, SlimefunItems.SYNTHETIC_SAPPHIRE, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.ALUMINUM_DUST, new ItemStack(Material.GLASS), new ItemStack(Material.GLASS_PANE), SlimefunItems.ALUMINUM_INGOT, new ItemStack(Material.LAPIS_LAZULI), null, null, null, null}) + .setUseableInWorkbench(true) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.SYNTHETIC_DIAMOND, RecipeType.PRESSURE_CHAMBER, + new ItemStack[] {SlimefunItems.CARBON_CHUNK, null, null, null, null, null, null, null, null}) + .setUseableInWorkbench(true) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.RAW_CARBONADO, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.SYNTHETIC_DIAMOND, SlimefunItems.CARBON_CHUNK, new ItemStack(Material.GLASS_PANE), null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.NICKEL_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.IRON_DUST, new ItemStack(Material.IRON_INGOT), SlimefunItems.COPPER_DUST, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.COBALT_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.IRON_DUST, SlimefunItems.COPPER_DUST, SlimefunItems.NICKEL_INGOT, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.CARBONADO, RecipeType.PRESSURE_CHAMBER, + new ItemStack[] {SlimefunItems.RAW_CARBONADO, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.FERROSILICON, RecipeType.SMELTERY, + new ItemStack[] {new ItemStack(Material.IRON_INGOT), SlimefunItems.IRON_DUST, SlimefunItems.SILICON, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.IRON_DUST, RecipeType.ORE_CRUSHER, + new ItemStack[] {new ItemStack(Material.IRON_ORE), null, null, null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.IRON_DUST, oreCrusher.isOreDoublingEnabled() ? 2 : 1)) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.GOLD_DUST, RecipeType.ORE_CRUSHER, + new ItemStack[] {new ItemStack(Material.GOLD_ORE), null, null, null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.GOLD_DUST, oreCrusher.isOreDoublingEnabled() ? 2 : 1)) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.COPPER_DUST, RecipeType.ORE_WASHER, + new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.TIN_DUST, RecipeType.ORE_WASHER, + new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.LEAD_DUST, RecipeType.ORE_WASHER, + new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.SILVER_DUST, RecipeType.ORE_WASHER, + new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.ALUMINUM_DUST, RecipeType.ORE_WASHER, + new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.ZINC_DUST, RecipeType.ORE_WASHER, + new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.MAGNESIUM_DUST, RecipeType.ORE_WASHER, + new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.COPPER_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.COPPER_DUST, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.TIN_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.TIN_DUST, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.SILVER_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.SILVER_DUST, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.LEAD_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.LEAD_DUST, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.ALUMINUM_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.ALUMINUM_DUST, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.ZINC_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.ZINC_DUST, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.MAGNESIUM_INGOT, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.MAGNESIUM_DUST, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.SULFATE, RecipeType.ORE_CRUSHER, + new ItemStack[] {new ItemStack(Material.NETHERRACK, 16), null, null, null, null, null, null, null, null}) + .register(plugin); + + new UnplaceableBlock(categories.resources, SlimefunItems.CARBON, RecipeType.COMPRESSOR, + new ItemStack[] {new ItemStack(Material.COAL, 8), null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.WHEAT_FLOUR, RecipeType.GRIND_STONE, + new ItemStack[] {new ItemStack(Material.WHEAT), null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.STEEL_PLATE, RecipeType.COMPRESSOR, + new ItemStack[] {new SlimefunItemStack(SlimefunItems.STEEL_INGOT, 8), null, null, null, null, null, null, null, null}) + .register(plugin); + + new UnplaceableBlock(categories.resources, SlimefunItems.COMPRESSED_CARBON, RecipeType.COMPRESSOR, + new ItemStack[] {new SlimefunItemStack(SlimefunItems.CARBON, 4), null, null, null, null, null, null, null, null}) + .register(plugin); + + new UnplaceableBlock(categories.resources, SlimefunItems.CARBON_CHUNK, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.COMPRESSED_CARBON, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.COMPRESSED_CARBON, new ItemStack(Material.FLINT), SlimefunItems.COMPRESSED_CARBON, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.COMPRESSED_CARBON}) + .register(plugin); + + new SlimefunItem(categories.technicalComponents, SlimefunItems.STEEL_THRUSTER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.REDSTONE), null, SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.STEEL_PLATE, new ItemStack(Material.FIRE_CHARGE), SlimefunItems.STEEL_PLATE}) + .register(plugin); + + new SlimefunItem(categories.technicalComponents, SlimefunItems.POWER_CRYSTAL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.REDSTONE), SlimefunItems.SYNTHETIC_SAPPHIRE, new ItemStack(Material.REDSTONE), SlimefunItems.SYNTHETIC_SAPPHIRE, SlimefunItems.SYNTHETIC_DIAMOND, SlimefunItems.SYNTHETIC_SAPPHIRE, new ItemStack(Material.REDSTONE), SlimefunItems.SYNTHETIC_SAPPHIRE, new ItemStack(Material.REDSTONE)}) + .register(plugin); + + new Jetpack(categories.technicalGadgets, SlimefunItems.DURALUMIN_JETPACK, + new ItemStack[] {SlimefunItems.DURALUMIN_INGOT, null, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.35, 20) + .register(plugin); + + new Jetpack(categories.technicalGadgets, SlimefunItems.SOLDER_JETPACK, + new ItemStack[] {SlimefunItems.SOLDER_INGOT, null, SlimefunItems.SOLDER_INGOT, SlimefunItems.SOLDER_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.SOLDER_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.4, 30) + .register(plugin); + + new Jetpack(categories.technicalGadgets, SlimefunItems.BILLON_JETPACK, + new ItemStack[] {SlimefunItems.BILLON_INGOT, null, SlimefunItems.BILLON_INGOT, SlimefunItems.BILLON_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.BILLON_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.45, 45) + .register(plugin); + + new Jetpack(categories.technicalGadgets, SlimefunItems.STEEL_JETPACK, + new ItemStack[] {SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.5, 60) + .register(plugin); + + new Jetpack(categories.technicalGadgets, SlimefunItems.DAMASCUS_STEEL_JETPACK, + new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_INGOT, null, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.55, 75) + .register(plugin); + + new Jetpack(categories.technicalGadgets, SlimefunItems.REINFORCED_ALLOY_JETPACK, + new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_INGOT, null, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.6, 100) + .register(plugin); + + new Jetpack(categories.technicalGadgets, SlimefunItems.CARBONADO_JETPACK, + new ItemStack[] {SlimefunItems.CARBON_CHUNK, null, SlimefunItems.CARBON_CHUNK, SlimefunItems.CARBONADO, SlimefunItems.POWER_CRYSTAL, SlimefunItems.CARBONADO, SlimefunItems.STEEL_THRUSTER, SlimefunItems.LARGE_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.7, 150) + .register(plugin); + + new Parachute(categories.technicalGadgets, SlimefunItems.PARACHUTE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.CHAIN, null, SlimefunItems.CHAIN, null, null, null}) + .register(plugin); + + new HologramProjector(categories.technicalGadgets, SlimefunItems.HOLOGRAM_PROJECTOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.POWER_CRYSTAL, null, SlimefunItems.ALUMINUM_BRASS_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_BRASS_INGOT, null, SlimefunItems.ALUMINUM_BRASS_INGOT, null}, + new SlimefunItemStack(SlimefunItems.HOLOGRAM_PROJECTOR, 3)) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.CHAIN, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null, null}, + new SlimefunItemStack(SlimefunItems.CHAIN, 8)) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.HOOK, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null, null, null}) + .register(plugin); + + new GrapplingHook(categories.tools, SlimefunItems.GRAPPLING_HOOK, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, SlimefunItems.HOOK, null, SlimefunItems.CHAIN, null, SlimefunItems.CHAIN, null, null}) + .register(plugin); + + new MagicWorkbench(categories.basicMachines, SlimefunItems.MAGIC_WORKBENCH).register(plugin); + + new SlimefunItem(categories.magicalGadgets, SlimefunItems.STAFF_ELEMENTAL, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.MAGICAL_BOOK_COVER, SlimefunItems.MAGIC_LUMP_3, null, new ItemStack(Material.STICK), SlimefunItems.MAGICAL_BOOK_COVER, SlimefunItems.MAGIC_LUMP_3, null, null}) + .register(plugin); + + new WindStaff(categories.magicalGadgets, SlimefunItems.STAFF_WIND, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, new ItemStack(Material.FEATHER), SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.STAFF_ELEMENTAL, new ItemStack(Material.FEATHER), SlimefunItems.STAFF_ELEMENTAL, null, null}) + .register(plugin); + + new WaterStaff(categories.magicalGadgets, SlimefunItems.STAFF_WATER, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, new ItemStack(Material.LILY_PAD), SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.STAFF_ELEMENTAL, new ItemStack(Material.LILY_PAD), SlimefunItems.STAFF_ELEMENTAL, null, null}) + .register(plugin); + + String[] multiToolItems = new String[] {"PORTABLE_CRAFTER", "MAGIC_EYE_OF_ENDER", "STAFF_ELEMENTAL_WIND", "GRAPPLING_HOOK"}; + + new MultiTool(categories.technicalGadgets, SlimefunItems.DURALUMIN_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.DURALUMIN_INGOT, null, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.DURALUMIN_INGOT, null, SlimefunItems.DURALUMIN_INGOT, null}, + 20, multiToolItems) + .register(plugin); + + new MultiTool(categories.technicalGadgets, SlimefunItems.SOLDER_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SOLDER_INGOT, null, SlimefunItems.SOLDER_INGOT, SlimefunItems.SOLDER_INGOT, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.SOLDER_INGOT, null, SlimefunItems.SOLDER_INGOT, null}, + 30, multiToolItems) + .register(plugin); + + new MultiTool(categories.technicalGadgets, SlimefunItems.BILLON_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.BILLON_INGOT, null, SlimefunItems.BILLON_INGOT, SlimefunItems.BILLON_INGOT, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.BILLON_INGOT, null, SlimefunItems.BILLON_INGOT, null}, + 40, multiToolItems) + .register(plugin); + + new MultiTool(categories.technicalGadgets, SlimefunItems.STEEL_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_INGOT, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, null}, + 50, multiToolItems) + .register(plugin); + + new MultiTool(categories.technicalGadgets, SlimefunItems.DAMASCUS_STEEL_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_INGOT, null, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.DAMASCUS_STEEL_INGOT, null, SlimefunItems.DAMASCUS_STEEL_INGOT, null}, + 60, multiToolItems) + .register(plugin); + + new MultiTool(categories.technicalGadgets, SlimefunItems.REINFORCED_ALLOY_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_INGOT, null, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.REINFORCED_ALLOY_INGOT, null, SlimefunItems.REINFORCED_ALLOY_INGOT, null}, + 75, multiToolItems) + .register(plugin); + + new MultiTool(categories.technicalGadgets, SlimefunItems.CARBONADO_MULTI_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CARBONADO, null, SlimefunItems.CARBONADO, SlimefunItems.CARBONADO, SlimefunItems.LARGE_CAPACITOR, SlimefunItems.CARBONADO, null, SlimefunItems.CARBONADO, null}, + 100, "PORTABLE_CRAFTER", "MAGIC_EYE_OF_ENDER", "STAFF_ELEMENTAL_WIND", "GRAPPLING_HOOK", "GOLD_PAN", "NETHER_GOLD_PAN") + .register(plugin); + + new OreWasher(categories.basicMachines, SlimefunItems.ORE_WASHER).register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.GOLD_24K, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_22K, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.GOLD_22K, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_20K, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.GOLD_20K, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_18K, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.GOLD_18K, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_16K, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.GOLD_16K, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_14K, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.GOLD_14K, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_12K, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.GOLD_12K, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_10K, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.GOLD_10K, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_8K, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.GOLD_8K, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_6K, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.GOLD_6K, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.GOLD_DUST, SlimefunItems.GOLD_4K, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.GOLD_4K, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.GOLD_DUST, null, null, null, null, null, null, null, null}) + .setUseableInWorkbench(true) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.STONE_CHUNK, RecipeType.ORE_WASHER, + new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.SILICON, RecipeType.SMELTERY, + new ItemStack[] {new ItemStack(Material.QUARTZ_BLOCK), null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.technicalComponents, SlimefunItems.SOLAR_PANEL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), SlimefunItems.SILICON, SlimefunItems.SILICON, SlimefunItems.SILICON, SlimefunItems.FERROSILICON, SlimefunItems.FERROSILICON, SlimefunItems.FERROSILICON}) + .register(plugin); + + new SolarHelmet(categories.technicalGadgets, SlimefunItems.SOLAR_HELMET, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.SOLAR_PANEL, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, null, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.MEDIUM_CAPACITOR, null, SlimefunItems.MEDIUM_CAPACITOR}, + 0.1) + .register(plugin); + + new UnplaceableBlock(categories.magicalResources, SlimefunItems.LAVA_CRYSTAL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.BLAZE_POWDER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.BLAZE_POWDER), SlimefunItems.FIRE_RUNE, new ItemStack(Material.BLAZE_POWDER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.BLAZE_POWDER), SlimefunItems.MAGIC_LUMP_1}) + .register(plugin); + + new SlimefunItem(categories.magicalGadgets, SlimefunItems.STAFF_FIRE, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, null, SlimefunItems.LAVA_CRYSTAL, null, SlimefunItems.STAFF_ELEMENTAL, null, SlimefunItems.STAFF_ELEMENTAL, null, null}) + .register(plugin); + + if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { + new StormStaff(categories.magicalGadgets, SlimefunItems.STAFF_STORM, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {SlimefunItems.LIGHTNING_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.LIGHTNING_RUNE, SlimefunItems.STAFF_WATER, SlimefunItems.MAGIC_SUGAR, SlimefunItems.STAFF_WIND, SlimefunItems.LIGHTNING_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.LIGHTNING_RUNE}) + .register(plugin); + + ItemStack weaknessPotion = new ItemStack(Material.POTION); + PotionMeta meta = (PotionMeta) weaknessPotion.getItemMeta(); + meta.setBasePotionData(new PotionData(PotionType.WEAKNESS, false, false)); + weaknessPotion.setItemMeta(meta); + + new MagicalZombiePills(categories.magicalGadgets, SlimefunItems.MAGICAL_ZOMBIE_PILLS, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {new ItemStack(Material.GOLD_INGOT), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.GOLD_INGOT), new ItemStack(Material.APPLE), weaknessPotion, new ItemStack(Material.APPLE), new ItemStack(Material.GOLD_INGOT), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.GOLD_INGOT)}, + new SlimefunItemStack(SlimefunItems.MAGICAL_ZOMBIE_PILLS, 2)) + .register(plugin); + } + + new SmeltersPickaxe(categories.tools, SlimefunItems.SMELTERS_PICKAXE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.LAVA_CRYSTAL, SlimefunItems.LAVA_CRYSTAL, SlimefunItems.LAVA_CRYSTAL, null, SlimefunItems.FERROSILICON, null, null, SlimefunItems.FERROSILICON, null}) + .register(plugin); + + new SlimefunItem(categories.magicalResources, SlimefunItems.COMMON_TALISMAN, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_2, SlimefunItems.GOLD_8K, SlimefunItems.MAGIC_LUMP_2, null, new ItemStack(Material.EMERALD), null, SlimefunItems.MAGIC_LUMP_2, SlimefunItems.GOLD_8K, SlimefunItems.MAGIC_LUMP_2}) + .register(plugin); + + new Talisman(SlimefunItems.TALISMAN_ANVIL, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.ANVIL), SlimefunItems.COMMON_TALISMAN, new ItemStack(Material.ANVIL), SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, + true, false, "anvil") + .register(plugin); + + new Talisman(SlimefunItems.TALISMAN_MINER, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.SYNTHETIC_SAPPHIRE, SlimefunItems.COMMON_TALISMAN, SlimefunItems.SIFTED_ORE, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, + false, false, null, 20) + .register(plugin); + + new Talisman(SlimefunItems.TALISMAN_HUNTER, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.SYNTHETIC_SAPPHIRE, SlimefunItems.COMMON_TALISMAN, SlimefunItems.MONSTER_JERKY, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, + false, false, "hunter", 20) + .register(plugin); + + new Talisman(SlimefunItems.TALISMAN_LAVA, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.LAVA_CRYSTAL, SlimefunItems.COMMON_TALISMAN, new ItemStack(Material.LAVA_BUCKET), SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, + true, true, "lava", new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 3600, 4)) + .register(plugin); + + new Talisman(SlimefunItems.TALISMAN_WATER, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.WATER_BUCKET), SlimefunItems.COMMON_TALISMAN, new ItemStack(Material.FISHING_ROD), SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, + true, true, "water", new PotionEffect(PotionEffectType.WATER_BREATHING, 3600, 4)) + .register(plugin); + + new Talisman(SlimefunItems.TALISMAN_ANGEL, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.FEATHER), SlimefunItems.COMMON_TALISMAN, new ItemStack(Material.FEATHER), SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, + false, true, "angel", 75) + .register(plugin); + + new Talisman(SlimefunItems.TALISMAN_FIRE, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.LAVA_CRYSTAL, SlimefunItems.COMMON_TALISMAN, SlimefunItems.LAVA_CRYSTAL, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, + true, true, "fire", new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 3600, 4)) + .register(plugin); + + new MagicianTalisman(SlimefunItems.TALISMAN_MAGICIAN, + new ItemStack[] {SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.ENCHANTING_TABLE), SlimefunItems.COMMON_TALISMAN, new ItemStack(Material.ENCHANTING_TABLE), SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3}) + .register(plugin); + + new Talisman(SlimefunItems.TALISMAN_TRAVELLER, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.STAFF_WIND, SlimefunItems.TALISMAN_ANGEL, SlimefunItems.STAFF_WIND, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, + false, false, "traveller", 60, new PotionEffect(PotionEffectType.SPEED, 3600, 2)) + .register(plugin); + + new Talisman(SlimefunItems.TALISMAN_WARRIOR, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.COMMON_TALISMAN, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, + true, true, "warrior", new PotionEffect(PotionEffectType.INCREASE_DAMAGE, 3600, 2)) + .register(plugin); + + new Talisman(SlimefunItems.TALISMAN_KNIGHT, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.GILDED_IRON, SlimefunItems.TALISMAN_WARRIOR, SlimefunItems.GILDED_IRON, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, + "knight", 30, new PotionEffect(PotionEffectType.REGENERATION, 100, 3)) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.GILDED_IRON, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.GOLD_24K, SlimefunItems.IRON_DUST, null, null, null, null, null, null, null}) + .register(plugin); + + new SyntheticEmerald(categories.resources, SlimefunItems.SYNTHETIC_EMERALD, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.SYNTHETIC_SAPPHIRE, SlimefunItems.ALUMINUM_DUST, SlimefunItems.ALUMINUM_INGOT, new ItemStack(Material.GLASS_PANE), null, null, null, null, null}) + .register(plugin); + + registerArmorSet(categories.armor, SlimefunItems.CHAIN, new ItemStack[] { + new ItemStack(Material.CHAINMAIL_HELMET), new ItemStack(Material.CHAINMAIL_CHESTPLATE), new ItemStack(Material.CHAINMAIL_LEGGINGS), new ItemStack(Material.CHAINMAIL_BOOTS) + }, "CHAIN", true, new PotionEffect[0][0], plugin); + + new Talisman(SlimefunItems.TALISMAN_WHIRLWIND, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.STAFF_WIND, SlimefunItems.TALISMAN_TRAVELLER, SlimefunItems.STAFF_WIND, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3} + , false, true, "whirlwind", 60) + .register(plugin); + + new Talisman(SlimefunItems.TALISMAN_WIZARD, + new ItemStack[] {SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3, SlimefunItems.MAGIC_EYE_OF_ENDER, SlimefunItems.TALISMAN_MAGICIAN, SlimefunItems.MAGIC_EYE_OF_ENDER, SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3}, + false, false, "wizard", 60) + .register(plugin); + + new LumberAxe(categories.tools, SlimefunItems.LUMBER_AXE, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {SlimefunItems.SYNTHETIC_DIAMOND, SlimefunItems.SYNTHETIC_DIAMOND, null, SlimefunItems.SYNTHETIC_EMERALD, SlimefunItems.GILDED_IRON, null, null, SlimefunItems.GILDED_IRON, null}) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.SALT, RecipeType.ORE_WASHER, + new ItemStack[] {new ItemStack(Material.SAND, 2), null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.HEAVY_CREAM, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.MILK_BUCKET), null, null, null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.HEAVY_CREAM, 2)) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.CHEESE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.MILK_BUCKET), SlimefunItems.SALT, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.BUTTER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.HEAVY_CREAM, SlimefunItems.SALT, null, null, null, null, null, null, null}) + .register(plugin); + + registerArmorSet(categories.armor, SlimefunItems.GILDED_IRON, new ItemStack[] { + SlimefunItems.GILDED_IRON_HELMET, SlimefunItems.GILDED_IRON_CHESTPLATE, SlimefunItems.GILDED_IRON_LEGGINGS, SlimefunItems.GILDED_IRON_BOOTS + }, "GILDED_IRON", false, new PotionEffect[0][0], plugin); + + new SlimefunItem(categories.technicalComponents, SlimefunItems.REINFORCED_CLOTH, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.CLOTH, null, SlimefunItems.CLOTH, SlimefunItems.LEAD_INGOT, SlimefunItems.CLOTH, null, SlimefunItems.CLOTH, null}, new SlimefunItemStack(SlimefunItems.REINFORCED_CLOTH, 2)) + .register(plugin); + + new HazmatArmorPiece(categories.armor, SlimefunItems.SCUBA_HELMET, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.ORANGE_WOOL), SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.ORANGE_WOOL), SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.GLASS_PANE), SlimefunItems.REINFORCED_CLOTH, null, null, null}, + new PotionEffect[] {new PotionEffect(PotionEffectType.WATER_BREATHING, 300, 1)}) + .register(plugin); + + new HazmatArmorPiece(categories.armor, SlimefunItems.HAZMAT_CHESTPLATE, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.ORANGE_WOOL), null, new ItemStack(Material.ORANGE_WOOL), SlimefunItems.REINFORCED_CLOTH, SlimefunItems.REINFORCED_CLOTH, SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.BLACK_WOOL), SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.BLACK_WOOL)}, + new PotionEffect[] {new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 300, 1)}) + .register(plugin); + + new HazmatArmorPiece(categories.armor, SlimefunItems.HAZMAT_LEGGINGS, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.BLACK_WOOL), SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.BLACK_WOOL), SlimefunItems.REINFORCED_CLOTH, null, SlimefunItems.REINFORCED_CLOTH, SlimefunItems.REINFORCED_CLOTH, null, SlimefunItems.REINFORCED_CLOTH}, new PotionEffect[0]) + .register(plugin); + + new HazmatArmorPiece(categories.armor, SlimefunItems.HAZMAT_BOOTS, RecipeType.ARMOR_FORGE, + new ItemStack[] {SlimefunItems.REINFORCED_CLOTH, null, SlimefunItems.REINFORCED_CLOTH, SlimefunItems.REINFORCED_CLOTH, null, SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.BLACK_WOOL), null, new ItemStack(Material.BLACK_WOOL)}, new PotionEffect[0]) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.CRUSHED_ORE, RecipeType.ORE_CRUSHER, + new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.PULVERIZED_ORE, RecipeType.ORE_CRUSHER, + new ItemStack[] {SlimefunItems.CRUSHED_ORE, null, null, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.PURE_ORE_CLUSTER, RecipeType.ORE_WASHER, + new ItemStack[] {SlimefunItems.PULVERIZED_ORE, null, null, null, null, null, null, null, null}) + .register(plugin); + + new UnplaceableBlock(categories.misc, SlimefunItems.TINY_URANIUM, RecipeType.ORE_CRUSHER, + new ItemStack[] {SlimefunItems.PURE_ORE_CLUSTER, null, null, null, null, null, null, null, null}) + .register(plugin); + + new RadioactiveItem(categories.misc, Radioactivity.MODERATE, SlimefunItems.SMALL_URANIUM, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM, SlimefunItems.TINY_URANIUM}) + .register(plugin); + + new RadioactiveItem(categories.resources, Radioactivity.HIGH, SlimefunItems.URANIUM, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SMALL_URANIUM, SlimefunItems.SMALL_URANIUM, null, SlimefunItems.SMALL_URANIUM, SlimefunItems.SMALL_URANIUM, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.REDSTONE_ALLOY, RecipeType.SMELTERY, + new ItemStack[] {new ItemStack(Material.REDSTONE), new ItemStack(Material.REDSTONE_BLOCK), SlimefunItems.FERROSILICON, SlimefunItems.HARDENED_METAL_INGOT, null, null, null, null, null}) + .register(plugin); + + registerArmorSet(categories.armor, SlimefunItems.GOLD_12K, new ItemStack[] { + SlimefunItems.GOLDEN_HELMET_12K, SlimefunItems.GOLDEN_CHESTPLATE_12K, SlimefunItems.GOLDEN_LEGGINGS_12K, SlimefunItems.GOLDEN_BOOTS_12K + }, "GOLD_12K", false, new PotionEffect[0][0], plugin); + + new SlimefunItem(categories.misc, SlimefunItems.CLOTH, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.WHITE_WOOL), null, null, null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.CLOTH, 8)) + .register(plugin); + + new Bandage(categories.usefulItems, SlimefunItems.RAG, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.CLOTH, new ItemStack(Material.STRING), null, new ItemStack(Material.STRING), SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.CLOTH}, + new SlimefunItemStack(SlimefunItems.RAG, 2), 0) + .register(plugin); + + new Bandage(categories.usefulItems, SlimefunItems.BANDAGE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.RAG, new ItemStack(Material.STRING), SlimefunItems.RAG, null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.BANDAGE, 4), 1) + .register(plugin); + + new Splint(categories.usefulItems, SlimefunItems.SPLINT, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.STICK), new ItemStack(Material.STICK), new ItemStack(Material.STICK), null, new ItemStack(Material.IRON_INGOT), null}, + new SlimefunItemStack(SlimefunItems.SPLINT, 4)) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.TIN_CAN, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, null, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT, SlimefunItems.TIN_INGOT}, + new SlimefunItemStack(SlimefunItems.TIN_CAN, 8)) + .register(plugin); + + new Vitamins(categories.usefulItems, SlimefunItems.VITAMINS, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.TIN_CAN, new ItemStack(Material.APPLE), new ItemStack(Material.RED_MUSHROOM), new ItemStack(Material.SUGAR), null, null, null, null, null}) + .register(plugin); + + new Medicine(categories.usefulItems, SlimefunItems.MEDICINE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.VITAMINS, new ItemStack(Material.GLASS_BOTTLE), SlimefunItems.HEAVY_CREAM, null, null, null, null, null, null}) + .register(plugin); + + new SlimefunArmorPiece(categories.technicalGadgets, SlimefunItems.NIGHT_VISION_GOGGLES, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.COAL_BLOCK), new ItemStack(Material.COAL_BLOCK), new ItemStack(Material.COAL_BLOCK), new ItemStack(Material.LIME_STAINED_GLASS_PANE), new ItemStack(Material.COAL_BLOCK), new ItemStack(Material.LIME_STAINED_GLASS_PANE), new ItemStack(Material.COAL_BLOCK), null, new ItemStack(Material.COAL_BLOCK)}, + new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 20)}) + .register(plugin); + + new PickaxeOfContainment(categories.tools, SlimefunItems.PICKAXE_OF_CONTAINMENT, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {SlimefunItems.FERROSILICON, SlimefunItems.FERROSILICON, SlimefunItems.FERROSILICON, null, SlimefunItems.GILDED_IRON, null, null, SlimefunItems.GILDED_IRON, null}) + .register(plugin); + + new HerculesPickaxe(categories.tools, SlimefunItems.HERCULES_PICKAXE, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.HARDENED_METAL_INGOT, null, SlimefunItems.FERROSILICON, null, null, SlimefunItems.FERROSILICON, null}) + .register(plugin); + + if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { + new TableSaw(categories.basicMachines, SlimefunItems.TABLE_SAW).register(plugin); + } + + new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_HELMET_STEEL, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), null, null, null}, null) + .register(plugin); + + new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_CHESTPLATE_STEEL, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL)}, null) + .register(plugin); + + new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_LEGGINGS_STEEL, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL)}, + new PotionEffect[] {new PotionEffect(PotionEffectType.SPEED, 300, 2)}) + .register(plugin); + + new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_BOOTS_STEEL, RecipeType.ARMOR_FORGE, + new ItemStack[] {null, null, null, new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL)}, + new PotionEffect[] {new PotionEffect(PotionEffectType.JUMP, 300, 5)}) + .register(plugin); + + new VampireBlade(categories.weapons, SlimefunItems.BLADE_OF_VAMPIRES, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, null, new ItemStack(Material.BLAZE_ROD), null}) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.GOLD_24K_BLOCK, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K, SlimefunItems.GOLD_24K}) + .register(plugin); + + new Composter(categories.basicMachines, SlimefunItems.COMPOSTER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.OAK_SLAB), null, new ItemStack(Material.OAK_SLAB), new ItemStack(Material.OAK_SLAB), null, new ItemStack(Material.OAK_SLAB), new ItemStack(Material.OAK_SLAB), new ItemStack(Material.CAULDRON), new ItemStack(Material.OAK_SLAB)}) + .register(plugin); + + new SlimefunItem(categories.magicalArmor, SlimefunItems.FARMER_SHOES, RecipeType.ARMOR_FORGE, + new ItemStack[] {null, null, null, new ItemStack(Material.HAY_BLOCK), null, new ItemStack(Material.HAY_BLOCK), new ItemStack(Material.HAY_BLOCK), null, new ItemStack(Material.HAY_BLOCK)}) + .register(plugin); + + new ExplosivePickaxe(categories.tools, SlimefunItems.EXPLOSIVE_PICKAXE, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {new ItemStack(Material.TNT), SlimefunItems.SYNTHETIC_DIAMOND, new ItemStack(Material.TNT), null, SlimefunItems.FERROSILICON, null, null, SlimefunItems.FERROSILICON, null}) + .register(plugin); + + new ExplosiveShovel(categories.tools, SlimefunItems.EXPLOSIVE_SHOVEL, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.SYNTHETIC_DIAMOND, null, null, new ItemStack(Material.TNT), null, null, SlimefunItems.FERROSILICON, null}) + .register(plugin); + + new AutomatedPanningMachine(categories.basicMachines, SlimefunItems.AUTOMATED_PANNING_MACHINE).register(plugin); + + new IndustrialMiner(categories.basicMachines, SlimefunItems.INDUSTRIAL_MINER, Material.IRON_BLOCK, false, 3).register(plugin); + new AdvancedIndustrialMiner(categories.basicMachines, SlimefunItems.ADVANCED_INDUSTRIAL_MINER).register(plugin); + + new SlimefunItem(categories.magicalArmor, SlimefunItems.BOOTS_OF_THE_STOMPER, RecipeType.ARMOR_FORGE, + new ItemStack[] {null, null, null, new ItemStack(Material.YELLOW_WOOL), null, new ItemStack(Material.YELLOW_WOOL), new ItemStack(Material.PISTON), null, new ItemStack(Material.PISTON)}) + .register(plugin); + + new PickaxeOfTheSeeker(categories.tools, SlimefunItems.PICKAXE_OF_THE_SEEKER, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {new ItemStack(Material.COMPASS), SlimefunItems.SYNTHETIC_DIAMOND, new ItemStack(Material.COMPASS), null, SlimefunItems.FERROSILICON, null, null, SlimefunItems.FERROSILICON, null}) + .register(plugin); + + new SlimefunBackpack(9, categories.usefulItems, SlimefunItems.BACKPACK_SMALL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.LEATHER), null, new ItemStack(Material.LEATHER), SlimefunItems.GOLD_6K, new ItemStack(Material.CHEST), SlimefunItems.GOLD_6K, new ItemStack(Material.LEATHER), new ItemStack(Material.LEATHER), new ItemStack(Material.LEATHER)}) + .register(plugin); + + new SlimefunBackpack(18, categories.usefulItems, SlimefunItems.BACKPACK_MEDIUM, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.LEATHER), null, new ItemStack(Material.LEATHER), SlimefunItems.GOLD_10K, SlimefunItems.BACKPACK_SMALL, SlimefunItems.GOLD_10K, new ItemStack(Material.LEATHER), new ItemStack(Material.LEATHER), new ItemStack(Material.LEATHER)}) + .register(plugin); + + new SlimefunBackpack(27, categories.usefulItems, SlimefunItems.BACKPACK_LARGE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.LEATHER), null, new ItemStack(Material.LEATHER), SlimefunItems.GOLD_14K, SlimefunItems.BACKPACK_MEDIUM, SlimefunItems.GOLD_14K, new ItemStack(Material.LEATHER), new ItemStack(Material.LEATHER), new ItemStack(Material.LEATHER)}) + .register(plugin); + + new SlimefunBackpack(36, categories.usefulItems, SlimefunItems.WOVEN_BACKPACK, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CLOTH, null, SlimefunItems.CLOTH, SlimefunItems.GOLD_16K, SlimefunItems.BACKPACK_LARGE, SlimefunItems.GOLD_16K, SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.CLOTH}) + .register(plugin); + + new Crucible(categories.basicMachines, SlimefunItems.CRUCIBLE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.TERRACOTTA), null, new ItemStack(Material.TERRACOTTA), new ItemStack(Material.TERRACOTTA), null, new ItemStack(Material.TERRACOTTA), new ItemStack(Material.TERRACOTTA), new ItemStack(Material.FLINT_AND_STEEL), new ItemStack(Material.TERRACOTTA)}) + .register(plugin); + + new SlimefunBackpack(45, categories.usefulItems, SlimefunItems.GILDED_BACKPACK, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.GOLD_22K, null, SlimefunItems.GOLD_22K, new ItemStack(Material.LEATHER), SlimefunItems.WOVEN_BACKPACK, new ItemStack(Material.LEATHER), SlimefunItems.GOLD_22K, null, SlimefunItems.GOLD_22K}) + .register(plugin); + + new SlimefunBackpack(54, categories.usefulItems, SlimefunItems.RADIANT_BACKPACK, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.GOLD_24K, null, SlimefunItems.GOLD_24K, new ItemStack(Material.LEATHER), SlimefunItems.GILDED_BACKPACK, new ItemStack(Material.LEATHER), SlimefunItems.GOLD_24K, null, SlimefunItems.GOLD_24K}) + .register(plugin); + + new RestoredBackpack(categories.usefulItems).register(plugin); + + new SlimefunItem(categories.technicalComponents, SlimefunItems.MAGNET, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.NICKEL_INGOT, SlimefunItems.ALUMINUM_DUST, SlimefunItems.IRON_DUST, SlimefunItems.COBALT_INGOT, null, null, null, null, null}) + .register(plugin); + + new InfusedMagnet(categories.magicalGadgets, SlimefunItems.INFUSED_MAGNET, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ENDER_LUMP_2, SlimefunItems.MAGNET, SlimefunItems.ENDER_LUMP_2, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}) + .register(plugin); + + new SlimefunItem(categories.tools, SlimefunItems.COBALT_PICKAXE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.COBALT_INGOT, SlimefunItems.COBALT_INGOT, SlimefunItems.COBALT_INGOT, null, SlimefunItems.NICKEL_INGOT, null, null, SlimefunItems.NICKEL_INGOT, null}) + .register(plugin); + + new SlimefunItem(categories.magicalResources, SlimefunItems.NECROTIC_SKULL, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}) + .register(plugin); + + new SlimefunItem(categories.magicalResources, SlimefunItems.ESSENCE_OF_AFTERLIFE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {SlimefunItems.ENDER_LUMP_3, SlimefunItems.AIR_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.EARTH_RUNE, SlimefunItems.NECROTIC_SKULL, SlimefunItems.FIRE_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.WATER_RUNE, SlimefunItems.ENDER_LUMP_3}) + .register(plugin); + + new SoulboundBackpack(36, categories.magicalGadgets, SlimefunItems.BOUND_BACKPACK, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {SlimefunItems.ENDER_LUMP_2, null, SlimefunItems.ENDER_LUMP_2, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.WOVEN_BACKPACK, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.ENDER_LUMP_2, null, SlimefunItems.ENDER_LUMP_2}) + .register(plugin); + + new JetBoots(categories.technicalGadgets, SlimefunItems.DURALUMIN_JETBOOTS, + new ItemStack[] {null, null, null, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.35, 20) + .register(plugin); + + new JetBoots(categories.technicalGadgets, SlimefunItems.SOLDER_JETBOOTS, + new ItemStack[] {null, null, null, SlimefunItems.SOLDER_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.SOLDER_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.4, 30) + .register(plugin); + + new JetBoots(categories.technicalGadgets, SlimefunItems.BILLON_JETBOOTS, + new ItemStack[] {null, null, null, SlimefunItems.BILLON_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.BILLON_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.45, 40) + .register(plugin); + + new JetBoots(categories.technicalGadgets, SlimefunItems.STEEL_JETBOOTS, + new ItemStack[] {null, null, null, SlimefunItems.STEEL_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.5, 50) + .register(plugin); + + new JetBoots(categories.technicalGadgets, SlimefunItems.DAMASCUS_STEEL_JETBOOTS, + new ItemStack[] {null, null, null, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.55, 75) + .register(plugin); + + new JetBoots(categories.technicalGadgets, SlimefunItems.REINFORCED_ALLOY_JETBOOTS, + new ItemStack[] {null, null, null, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.STEEL_THRUSTER, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.6, 100) + .register(plugin); + + new JetBoots(categories.technicalGadgets, SlimefunItems.CARBONADO_JETBOOTS, + new ItemStack[] {null, null, null, SlimefunItems.CARBONADO, SlimefunItems.POWER_CRYSTAL, SlimefunItems.CARBONADO, SlimefunItems.STEEL_THRUSTER, SlimefunItems.LARGE_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.7, 125) + .register(plugin); + + new JetBoots(categories.technicalGadgets, SlimefunItems.ARMORED_JETBOOTS, + new ItemStack[] {null, null, null, SlimefunItems.STEEL_PLATE, SlimefunItems.POWER_CRYSTAL, SlimefunItems.STEEL_PLATE, SlimefunItems.STEEL_THRUSTER, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.STEEL_THRUSTER}, + 0.45, 50) + .register(plugin); + + new SeismicAxe(categories.weapons, SlimefunItems.SEISMIC_AXE, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.HARDENED_METAL_INGOT, null, SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.STAFF_ELEMENTAL, null, null, SlimefunItems.STAFF_ELEMENTAL, null}) + .register(plugin); + + new PickaxeOfVeinMining(categories.tools, SlimefunItems.PICKAXE_OF_VEIN_MINING, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {new ItemStack(Material.EMERALD_ORE), SlimefunItems.SYNTHETIC_DIAMOND, new ItemStack(Material.EMERALD_ORE), null, SlimefunItems.GILDED_IRON, null, null, SlimefunItems.GILDED_IRON, null}) + .register(plugin); + + new SoulboundItem(categories.weapons, SlimefunItems.SOULBOUND_SWORD, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_SWORD), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) + .register(plugin); + + new SoulboundItem(categories.weapons, SlimefunItems.SOULBOUND_TRIDENT, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.TRIDENT), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) + .register(plugin); + + new SoulboundItem(categories.weapons, SlimefunItems.SOULBOUND_BOW, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.BOW), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) + .register(plugin); + + new SoulboundItem(categories.tools, SlimefunItems.SOULBOUND_PICKAXE, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_PICKAXE), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) + .register(plugin); + + new SoulboundItem(categories.tools, SlimefunItems.SOULBOUND_AXE, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_AXE), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) + .register(plugin); + + new SoulboundItem(categories.tools, SlimefunItems.SOULBOUND_SHOVEL, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_SHOVEL), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) + .register(plugin); + + new SoulboundItem(categories.tools, SlimefunItems.SOULBOUND_HOE, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_HOE), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) + .register(plugin); + + new SoulboundItem(categories.magicalArmor, SlimefunItems.SOULBOUND_HELMET, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_HELMET), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) + .register(plugin); + + new SoulboundItem(categories.magicalArmor, SlimefunItems.SOULBOUND_CHESTPLATE, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_CHESTPLATE), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) + .register(plugin); + + new SoulboundItem(categories.magicalArmor, SlimefunItems.SOULBOUND_LEGGINGS, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_LEGGINGS), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) + .register(plugin); + + new SoulboundItem(categories.magicalArmor, SlimefunItems.SOULBOUND_BOOTS, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null, null, new ItemStack(Material.DIAMOND_BOOTS), null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) + .register(plugin); + + new Juicer(categories.basicMachines, SlimefunItems.JUICER).register(plugin); + + new Juice(categories.food, SlimefunItems.APPLE_JUICE, RecipeType.JUICER, + new ItemStack[] {new ItemStack(Material.APPLE), null, null, null, null, null, null, null, null}) + .register(plugin); + + new Juice(categories.food, SlimefunItems.CARROT_JUICE, RecipeType.JUICER, + new ItemStack[] {new ItemStack(Material.CARROT), null, null, null, null, null, null, null, null}) + .register(plugin); + + new Juice(categories.food, SlimefunItems.MELON_JUICE, RecipeType.JUICER, + new ItemStack[] {new ItemStack(Material.MELON_SLICE), null, null, null, null, null, null, null, null}) + .register(plugin); + + new Juice(categories.food, SlimefunItems.PUMPKIN_JUICE, RecipeType.JUICER, + new ItemStack[] {new ItemStack(Material.PUMPKIN), null, null, null, null, null, null, null, null}) + .register(plugin); + + if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { + new Juice(categories.food, SlimefunItems.SWEET_BERRY_JUICE, RecipeType.JUICER, + new ItemStack[] {new ItemStack(Material.SWEET_BERRIES), null, null, null, null, null, null, null, null}) + .register(plugin); + } + + new Juice(categories.food, SlimefunItems.GOLDEN_APPLE_JUICE, RecipeType.JUICER, + new ItemStack[] {new ItemStack(Material.GOLDEN_APPLE), null, null, null, null, null, null, null, null}) + .register(plugin); + + new BrokenSpawner(categories.magicalResources, SlimefunItems.BROKEN_SPAWNER, new RecipeType(new NamespacedKey(plugin, "pickaxe_of_containment"), SlimefunItems.PICKAXE_OF_CONTAINMENT), + new ItemStack[] {null, null, null, null, new ItemStack(Material.SPAWNER), null, null, null, null}) + .register(plugin); + + new RepairedSpawner(categories.magicalGadgets, SlimefunItems.REPAIRED_SPAWNER, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {SlimefunItems.ENDER_RUNE, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.BROKEN_SPAWNER, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.ENDER_RUNE}) + .register(plugin); + + new EnhancedFurnace(categories.basicMachines, 1, 1, 1, SlimefunItems.ENHANCED_FURNACE, + new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, new ItemStack(Material.FURNACE), SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) + .register(plugin); + + new EnhancedFurnace(categories.basicMachines, 2, 1, 1, SlimefunItems.ENHANCED_FURNACE_2, + new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) + .register(plugin); + + new EnhancedFurnace(categories.basicMachines, 2, 2, 1, SlimefunItems.ENHANCED_FURNACE_3, + new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_2, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) + .register(plugin); + + new EnhancedFurnace(categories.basicMachines, 3, 2, 1, SlimefunItems.ENHANCED_FURNACE_4, + new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_3, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) + .register(plugin); + + new EnhancedFurnace(categories.basicMachines, 3, 2, 2, SlimefunItems.ENHANCED_FURNACE_5, + new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_4, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) + .register(plugin); + + new EnhancedFurnace(categories.basicMachines, 3, 3, 2, SlimefunItems.ENHANCED_FURNACE_6, + new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_5, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) + .register(plugin); + + new EnhancedFurnace(categories.basicMachines, 4, 3, 2, SlimefunItems.ENHANCED_FURNACE_7, + new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_6, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) + .register(plugin); + + new EnhancedFurnace(categories.basicMachines, 4, 4, 2, SlimefunItems.ENHANCED_FURNACE_8, + new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_7, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) + .register(plugin); + + new EnhancedFurnace(categories.basicMachines, 5, 4, 2, SlimefunItems.ENHANCED_FURNACE_9, + new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_8, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) + .register(plugin); + + new EnhancedFurnace(categories.basicMachines, 5, 5, 2, SlimefunItems.ENHANCED_FURNACE_10, + new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_9, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) + .register(plugin); + + new EnhancedFurnace(categories.basicMachines, 5, 5, 3, SlimefunItems.ENHANCED_FURNACE_11, + new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.ENHANCED_FURNACE_10, SlimefunItems.HEATING_COIL, null, SlimefunItems.ELECTRIC_MOTOR, null}) + .register(plugin); + + new EnhancedFurnace(categories.basicMachines, 10, 10, 3, SlimefunItems.REINFORCED_FURNACE, + new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.ENHANCED_FURNACE_11, SlimefunItems.HEATING_COIL, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT}) + .register(plugin); + + new EnhancedFurnace(categories.basicMachines, 20, 10, 3, SlimefunItems.CARBONADO_EDGED_FURNACE, + new ItemStack[] {SlimefunItems.CARBONADO, SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.CARBONADO, SlimefunItems.HEATING_COIL, SlimefunItems.REINFORCED_FURNACE, SlimefunItems.HEATING_COIL, SlimefunItems.CARBONADO, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.CARBONADO}) + .register(plugin); + + new SlimefunItem(categories.technicalComponents, SlimefunItems.ELECTRO_MAGNET, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.NICKEL_INGOT, SlimefunItems.MAGNET, SlimefunItems.COBALT_INGOT, null, SlimefunItems.BATTERY, null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.technicalComponents, SlimefunItems.ELECTRIC_MOTOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, null, SlimefunItems.ELECTRO_MAGNET, null, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE}) + .register(plugin); + + new SlimefunItem(categories.technicalComponents, SlimefunItems.HEATING_COIL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE, SlimefunItems.COPPER_WIRE}) + .register(plugin); + + new SlimefunItem(categories.technicalComponents, SlimefunItems.COPPER_WIRE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, null, SlimefunItems.COPPER_INGOT, SlimefunItems.COPPER_INGOT, SlimefunItems.COPPER_INGOT, null, null, null}, + new SlimefunItemStack(SlimefunItems.COPPER_WIRE, 8)) + .register(plugin); + + new BlockPlacer(categories.basicMachines, SlimefunItems.BLOCK_PLACER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.GOLD_4K, new ItemStack(Material.PISTON), SlimefunItems.GOLD_4K, new ItemStack(Material.IRON_INGOT), SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.IRON_INGOT), SlimefunItems.GOLD_4K, new ItemStack(Material.PISTON), SlimefunItems.GOLD_4K}) + .register(plugin); + + new TelepositionScroll(categories.magicalGadgets, SlimefunItems.SCROLL_OF_DIMENSIONAL_TELEPOSITION, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, SlimefunItems.ENDER_LUMP_3, SlimefunItems.MAGIC_EYE_OF_ENDER, SlimefunItems.ENDER_LUMP_3, SlimefunItems.MAGICAL_BOOK_COVER, SlimefunItems.ENDER_LUMP_3, SlimefunItems.MAGIC_EYE_OF_ENDER, SlimefunItems.ENDER_LUMP_3, null}) + .register(plugin); + + new ExplosiveBow(categories.weapons, SlimefunItems.EXPLOSIVE_BOW, + new ItemStack[] {null, new ItemStack(Material.STICK), new ItemStack(Material.GUNPOWDER), SlimefunItems.STAFF_FIRE, null, SlimefunItems.SULFATE, null, new ItemStack(Material.STICK), new ItemStack(Material.GUNPOWDER)}) + .register(plugin); + + new IcyBow(categories.weapons, SlimefunItems.ICY_BOW, + new ItemStack[] {null, new ItemStack(Material.STICK), new ItemStack(Material.ICE), SlimefunItems.STAFF_WATER, null, new ItemStack(Material.PACKED_ICE), null, new ItemStack(Material.STICK), new ItemStack(Material.ICE)}) + .register(plugin); + + new KnowledgeTome(categories.magicalGadgets, SlimefunItems.TOME_OF_KNOWLEDGE_SHARING, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, new ItemStack(Material.FEATHER), null, new ItemStack(Material.INK_SAC), SlimefunItems.MAGICAL_BOOK_COVER, new ItemStack(Material.GLASS_BOTTLE), null, new ItemStack(Material.WRITABLE_BOOK), null}) + .register(plugin); + + new KnowledgeFlask(categories.magicalGadgets, SlimefunItems.FLASK_OF_KNOWLEDGE, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, null, null, SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.GLASS_PANE), SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, null}, + new SlimefunItemStack(SlimefunItems.FLASK_OF_KNOWLEDGE, 8)) + .register(plugin); + + new BirthdayCake(categories.birthday, new SlimefunItemStack("BIRTHDAY_CAKE", Material.CAKE, "&bBirthday Cake"), RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.TORCH), null, new ItemStack(Material.SUGAR), new ItemStack(Material.CAKE), new ItemStack(Material.SUGAR), null, null, null}) + .register(plugin); + + new Juice(categories.christmas, SlimefunItems.CHRISTMAS_MILK, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.MILK_BUCKET), new ItemStack(Material.GLASS_BOTTLE), null, null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.CHRISTMAS_MILK, 4)) + .register(plugin); + + new Juice(categories.christmas, SlimefunItems.CHRISTMAS_CHOCOLATE_MILK, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CHRISTMAS_MILK, new ItemStack(Material.COCOA_BEANS), null, null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.CHRISTMAS_CHOCOLATE_MILK, 2)) + .register(plugin); + + new Juice(categories.christmas, SlimefunItems.CHRISTMAS_EGG_NOG, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CHRISTMAS_MILK, new ItemStack(Material.EGG), null, null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.CHRISTMAS_EGG_NOG, 2)) + .register(plugin); + + new Juice(categories.christmas, SlimefunItems.CHRISTMAS_APPLE_CIDER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.APPLE_JUICE, new ItemStack(Material.SUGAR), null, null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.CHRISTMAS_APPLE_CIDER, 2)) + .register(plugin); + + new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_COOKIE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.COOKIE), new ItemStack(Material.SUGAR), new ItemStack(Material.LIME_DYE), null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.CHRISTMAS_COOKIE, 16)) + .register(plugin); + + new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_FRUIT_CAKE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.EGG), new ItemStack(Material.APPLE), new ItemStack(Material.MELON), new ItemStack(Material.SUGAR), null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.CHRISTMAS_FRUIT_CAKE, 4)) + .register(plugin); + + new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_APPLE_PIE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.APPLE), new ItemStack(Material.EGG), null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.CHRISTMAS_APPLE_PIE, 2)) + .register(plugin); + + new Juice(categories.christmas, SlimefunItems.CHRISTMAS_HOT_CHOCOLATE, RecipeType.SMELTERY, + new ItemStack[] {SlimefunItems.CHRISTMAS_CHOCOLATE_MILK, null, null, null, null, null, null, null, null}, SlimefunItems.CHRISTMAS_HOT_CHOCOLATE) + .register(plugin); + + new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_CAKE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.EGG), new ItemStack(Material.SUGAR), SlimefunItems.WHEAT_FLOUR, new ItemStack(Material.MILK_BUCKET), null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.CHRISTMAS_CAKE, 4)) + .register(plugin); + + new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_CARAMEL, RecipeType.SMELTERY, + new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.SUGAR), null, null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.CHRISTMAS_CARAMEL, 4)) + .register(plugin); + + new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_CARAMEL_APPLE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.CHRISTMAS_CARAMEL, null, null, new ItemStack(Material.APPLE), null, null, new ItemStack(Material.STICK), null}, + new SlimefunItemStack(SlimefunItems.CHRISTMAS_CARAMEL_APPLE, 2)) + .register(plugin); + + new SlimefunItem(categories.christmas, SlimefunItems.CHRISTMAS_CHOCOLATE_APPLE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.COCOA_BEANS), null, null, new ItemStack(Material.APPLE), null, null, new ItemStack(Material.STICK), null}, + new SlimefunItemStack(SlimefunItems.CHRISTMAS_CHOCOLATE_APPLE, 2)) + .register(plugin); + + new ChristmasPresent(categories.christmas, SlimefunItems.CHRISTMAS_PRESENT, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, new ItemStack(Material.NAME_TAG), null, new ItemStack(Material.RED_WOOL), new ItemStack(Material.GREEN_WOOL), new ItemStack(Material.RED_WOOL), new ItemStack(Material.RED_WOOL), new ItemStack(Material.GREEN_WOOL), new ItemStack(Material.RED_WOOL)}, + new SlimefunItemStack(SlimefunItems.CHRISTMAS_HOT_CHOCOLATE, 1), + new SlimefunItemStack(SlimefunItems.CHRISTMAS_CHOCOLATE_APPLE, 4), + new SlimefunItemStack(SlimefunItems.CHRISTMAS_CARAMEL_APPLE, 4), + new SlimefunItemStack(SlimefunItems.CHRISTMAS_CAKE, 4), + new SlimefunItemStack(SlimefunItems.CHRISTMAS_COOKIE, 8), + new SlimefunItemStack(SlimefunItems.CHRISTMAS_PRESENT, 1), + new SlimefunItemStack(SlimefunItems.CHRISTMAS_EGG_NOG, 1), + new SlimefunItemStack(SlimefunItems.CHRISTMAS_MILK, 1), + new SlimefunItemStack(SlimefunItems.CHRISTMAS_APPLE_CIDER, 1), + new SlimefunItemStack(SlimefunItems.CHRISTMAS_FRUIT_CAKE, 4), + new SlimefunItemStack(SlimefunItems.CHRISTMAS_APPLE_PIE, 4), new ItemStack(Material.EMERALD) - ).register(plugin); - - new SlimefunItem(categories.easter, SlimefunItems.EASTER_CARROT_PIE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.CARROT), new ItemStack(Material.EGG), null, null, null, null, null, null}, - new CustomItem(SlimefunItems.EASTER_CARROT_PIE, 2)) - .register(plugin); - - new SlimefunItem(categories.easter, SlimefunItems.EASTER_APPLE_PIE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.APPLE), new ItemStack(Material.EGG), null, null, null, null, null, null}, - new CustomItem(SlimefunItems.CHRISTMAS_APPLE_PIE, 2)) - .register(plugin); - - new EasterEgg(categories.easter, SlimefunItems.EASTER_EGG, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, null, new ItemStack(Material.LIME_DYE), new ItemStack(Material.EGG), new ItemStack(Material.PURPLE_DYE), null, null, null}, - new CustomItem(SlimefunItems.EASTER_EGG, 2), - // Gifts: - new CustomItem(SlimefunItems.EASTER_CARROT_PIE, 4), - new CustomItem(SlimefunItems.CARROT_JUICE, 1), - new ItemStack(Material.EMERALD), - new ItemStack(Material.CAKE), - new ItemStack(Material.RABBIT_FOOT), - new ItemStack(Material.GOLDEN_CARROT, 4) - ).register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.REINFORCED_PLATE, RecipeType.COMPRESSOR, - new ItemStack[] {new CustomItem(SlimefunItems.REINFORCED_ALLOY_INGOT, 8), null, null, null, null, null, null, null, null}) - .register(plugin); - - new HardenedGlass(categories.technicalComponents, SlimefunItems.HARDENED_GLASS, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), SlimefunItems.REINFORCED_PLATE, new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS)}, - new CustomItem(SlimefunItems.HARDENED_GLASS, 16)) - .register(plugin); - - new SlimefunItem(categories.technicalComponents, SlimefunItems.COOLING_UNIT, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.ICE), new ItemStack(Material.ICE), new ItemStack(Material.ICE), SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_INGOT, new ItemStack(Material.ICE), new ItemStack(Material.ICE), new ItemStack(Material.ICE)}) - .register(plugin); - - new Cooler(27, categories.usefulItems, SlimefunItems.COOLER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.COOLING_UNIT, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ALUMINUM_INGOT}) - .register(plugin); - - new WitherProofBlock(categories.technicalComponents, SlimefunItems.WITHER_PROOF_OBSIDIAN, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.LEAD_INGOT, new ItemStack(Material.OBSIDIAN), SlimefunItems.LEAD_INGOT, new ItemStack(Material.OBSIDIAN), SlimefunItems.HARDENED_GLASS, new ItemStack(Material.OBSIDIAN), SlimefunItems.LEAD_INGOT, new ItemStack(Material.OBSIDIAN), SlimefunItems.LEAD_INGOT}, - new CustomItem(SlimefunItems.WITHER_PROOF_OBSIDIAN, 4)) - .register(plugin); - - new AncientPedestal(categories.magicalResources, SlimefunItems.ANCIENT_PEDESTAL, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {new ItemStack(Material.OBSIDIAN), SlimefunItems.GOLD_8K, new ItemStack(Material.OBSIDIAN), null, new ItemStack(Material.STONE), null, new ItemStack(Material.OBSIDIAN), SlimefunItems.GOLD_8K, new ItemStack(Material.OBSIDIAN)}, - new CustomItem(SlimefunItems.ANCIENT_PEDESTAL, 4)) - .register(plugin); - - new AncientAltar(categories.magicalGadgets, 8, SlimefunItems.ANCIENT_ALTAR, RecipeType.MAGIC_WORKBENCH, - new ItemStack[] {null, new ItemStack(Material.ENCHANTING_TABLE), null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.GOLD_8K, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.OBSIDIAN), SlimefunItems.GOLD_8K, new ItemStack(Material.OBSIDIAN)}) - .register(plugin); - - new EnergyRegulator(categories.electricity, SlimefunItems.ENERGY_REGULATOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SILVER_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.SILVER_INGOT}) - .register(plugin); - - new SlimefunItem(categories.misc, SlimefunItems.DUCT_TAPE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.ALUMINUM_DUST, SlimefunItems.ALUMINUM_DUST, SlimefunItems.ALUMINUM_DUST, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.PAPER), new ItemStack(Material.PAPER), new ItemStack(Material.PAPER)}, - new CustomItem(SlimefunItems.DUCT_TAPE, 2)) - .register(plugin); - - new Capacitor(categories.electricity, 128, SlimefunItems.SMALL_CAPACITOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.DURALUMIN_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.DURALUMIN_INGOT, new ItemStack(Material.REDSTONE), SlimefunItems.SULFATE, new ItemStack(Material.REDSTONE), SlimefunItems.DURALUMIN_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.DURALUMIN_INGOT}) - .register(plugin); - - new Capacitor(categories.electricity, 512, SlimefunItems.MEDIUM_CAPACITOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.BILLON_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.BILLON_INGOT, new ItemStack(Material.REDSTONE), SlimefunItems.SMALL_CAPACITOR, new ItemStack(Material.REDSTONE), SlimefunItems.BILLON_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.BILLON_INGOT}) - .register(plugin); - - new Capacitor(categories.electricity, 1024, SlimefunItems.BIG_CAPACITOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.STEEL_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.STEEL_INGOT, new ItemStack(Material.REDSTONE), SlimefunItems.MEDIUM_CAPACITOR, new ItemStack(Material.REDSTONE), SlimefunItems.STEEL_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.STEEL_INGOT}) - .register(plugin); - - new Capacitor(categories.electricity, 8192, SlimefunItems.LARGE_CAPACITOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.REINFORCED_ALLOY_INGOT, new ItemStack(Material.REDSTONE), SlimefunItems.BIG_CAPACITOR, new ItemStack(Material.REDSTONE), SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.REINFORCED_ALLOY_INGOT}) - .register(plugin); - - new Capacitor(categories.electricity, 65536, SlimefunItems.CARBONADO_EDGED_CAPACITOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CARBONADO, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.CARBONADO, new ItemStack(Material.REDSTONE), SlimefunItems.LARGE_CAPACITOR, new ItemStack(Material.REDSTONE), SlimefunItems.CARBONADO, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.CARBONADO}) - .register(plugin); - - new SolarGenerator(categories.electricity, 2, 0, SlimefunItems.SOLAR_GENERATOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SOLAR_PANEL, SlimefunItems.SOLAR_PANEL, SlimefunItems.SOLAR_PANEL, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_INGOT, null, SlimefunItems.ALUMINUM_INGOT, null}) - .register(plugin); - - new SolarGenerator(categories.electricity, 8, 0, SlimefunItems.SOLAR_GENERATOR_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SOLAR_GENERATOR, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR, SlimefunItems.ALUMINUM_INGOT, new ItemStack(Material.REDSTONE), SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR}) - .register(plugin); - - new SolarGenerator(categories.electricity, 32, 0, SlimefunItems.SOLAR_GENERATOR_3, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SOLAR_GENERATOR_2, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR_2, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.CARBONADO, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR_2, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR_2}) - .register(plugin); - - new SolarGenerator(categories.electricity, 128, 64, SlimefunItems.SOLAR_GENERATOR_4, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3}) - .register(plugin); - - new ChargingBench(categories.electricity, SlimefunItems.CHARGING_BENCH, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.ELECTRO_MAGNET, null, SlimefunItems.BATTERY, new ItemStack(Material.CRAFTING_TABLE), SlimefunItems.BATTERY, null, SlimefunItems.SMALL_CAPACITOR, null}) - .register(plugin); - - new ElectricFurnace(categories.electricity, SlimefunItems.ELECTRIC_FURNACE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.FURNACE), null, SlimefunItems.GILDED_IRON, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON, SlimefunItems.GILDED_IRON, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.GILDED_IRON}) { - - @Override - public int getEnergyConsumption() { - return 2; - } - - @Override - public int getCapacity() { - return 64; - } - - @Override - public int getSpeed() { - return 1; - } - - }.register(plugin); - - new ElectricFurnace(categories.electricity, SlimefunItems.ELECTRIC_FURNACE_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.ELECTRIC_MOTOR, null, SlimefunItems.GILDED_IRON, SlimefunItems.ELECTRIC_FURNACE, SlimefunItems.GILDED_IRON, SlimefunItems.GILDED_IRON, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON}) { - - @Override - public int getEnergyConsumption() { - return 3; - } - - @Override - public int getCapacity() { - return 128; - } - - @Override - public int getSpeed() { - return 2; - } - - }.register(plugin); - - new ElectricFurnace(categories.electricity, SlimefunItems.ELECTRIC_FURNACE_3, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.ELECTRIC_MOTOR, null, SlimefunItems.STEEL_INGOT, SlimefunItems.ELECTRIC_FURNACE_2, SlimefunItems.STEEL_INGOT, SlimefunItems.GILDED_IRON, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON}) { - - @Override - public int getEnergyConsumption() { - return 5; - } - - @Override - public int getCapacity() { - return 128; - } - - @Override - public int getSpeed() { - return 4; - } - - }.register(plugin); - - new ElectricGoldPan(categories.electricity, SlimefunItems.ELECTRIC_GOLD_PAN, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.GOLD_PAN, null, new ItemStack(Material.FLINT), SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.FLINT), SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ALUMINUM_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 1; - } - - @Override - public int getCapacity() { - return 128; - } - - @Override - public int getSpeed() { - return 1; - } - - }.register(plugin); - - new ElectricGoldPan(categories.electricity, SlimefunItems.ELECTRIC_GOLD_PAN_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.GOLD_PAN, null, new ItemStack(Material.IRON_INGOT), SlimefunItems.ELECTRIC_GOLD_PAN, new ItemStack(Material.IRON_INGOT), SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 2; - } - - @Override - public int getCapacity() { - return 128; - } - - @Override - public int getSpeed() { - return 3; - } - - }.register(plugin); - - new ElectricGoldPan(categories.electricity, SlimefunItems.ELECTRIC_GOLD_PAN_3, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.GOLD_PAN, null, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ELECTRIC_GOLD_PAN_2, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.COBALT_INGOT, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.COBALT_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 7; - } - - @Override - public int getCapacity() { - return 512; - } - - @Override - public int getSpeed() { - return 10; - } - - }.register(plugin); - - new ElectricDustWasher(categories.electricity, SlimefunItems.ELECTRIC_DUST_WASHER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.WATER_BUCKET), null, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.ELECTRIC_GOLD_PAN, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.COPPER_INGOT, SlimefunItems.COPPER_INGOT, SlimefunItems.COPPER_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 3; - } - - @Override - public int getCapacity() { - return 128; - } - - @Override - public int getSpeed() { - return 1; - } - - }.register(plugin); - - new ElectricDustWasher(categories.electricity, SlimefunItems.ELECTRIC_DUST_WASHER_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.WATER_BUCKET), null, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.ELECTRIC_DUST_WASHER, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 5; - } - - @Override - public int getCapacity() { - return 128; - } - - @Override - public int getSpeed() { - return 2; - } - - }.register(plugin); - - new ElectricDustWasher(categories.electricity, SlimefunItems.ELECTRIC_DUST_WASHER_3, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.WATER_BUCKET), null, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.ELECTRIC_DUST_WASHER_2, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.CORINTHIAN_BRONZE_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 15; - } - - @Override - public int getCapacity() { - return 512; - } - - @Override - public int getSpeed() { - return 10; - } - - }.register(plugin); - - new ElectricIngotFactory(categories.electricity, SlimefunItems.ELECTRIC_INGOT_FACTORY, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.FLINT_AND_STEEL), null, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRIC_DUST_WASHER, SlimefunItems.HEATING_COIL, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.DAMASCUS_STEEL_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 4; - } - - @Override - public int getCapacity() { - return 256; - } - - @Override - public int getSpeed() { - return 1; - } - - }.register(plugin); - - new ElectricIngotFactory(categories.electricity, SlimefunItems.ELECTRIC_INGOT_FACTORY_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.GILDED_IRON, new ItemStack(Material.FLINT_AND_STEEL), SlimefunItems.GILDED_IRON, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRIC_INGOT_FACTORY, SlimefunItems.HEATING_COIL, SlimefunItems.BRASS_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.BRASS_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 7; - } - - @Override - public int getCapacity() { - return 256; - } - - @Override - public int getSpeed() { - return 2; - } - - }.register(plugin); - - new ElectricIngotFactory(categories.electricity, SlimefunItems.ELECTRIC_INGOT_FACTORY_3, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.GILDED_IRON, new ItemStack(Material.FLINT_AND_STEEL), SlimefunItems.GILDED_IRON, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRIC_INGOT_FACTORY_2, SlimefunItems.HEATING_COIL, SlimefunItems.BRASS_INGOT, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.BRASS_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 20; - } - - @Override - public int getCapacity() { - return 512; - } - - @Override - public int getSpeed() { - return 8; - } - - }.register(plugin); - - new ElectrifiedCrucible(categories.electricity, SlimefunItems.ELECTRIFIED_CRUCIBLE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.LEAD_INGOT, SlimefunItems.CRUCIBLE, SlimefunItems.LEAD_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.LARGE_CAPACITOR, SlimefunItems.LEAD_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 24; - } - - @Override - public int getCapacity() { - return 1024; - } - - @Override - public int getSpeed() { - return 1; - } - - }.register(plugin); - - new ElectrifiedCrucible(categories.electricity, SlimefunItems.ELECTRIFIED_CRUCIBLE_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.ELECTRIFIED_CRUCIBLE, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.LEAD_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 40; - } - - @Override - public int getCapacity() { - return 1024; - } - - @Override - public int getSpeed() { - return 2; - } - - }.register(plugin); - - new ElectrifiedCrucible(categories.electricity, SlimefunItems.ELECTRIFIED_CRUCIBLE_3, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.ELECTRIFIED_CRUCIBLE_2, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.STEEL_PLATE, SlimefunItems.POWER_CRYSTAL, SlimefunItems.STEEL_PLATE, SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 60; - } - - @Override - public int getCapacity() { - return 1024; - } - - @Override - public int getSpeed() { - return 4; - } - - }.register(plugin); - - new ElectricOreGrinder(categories.electricity, SlimefunItems.ELECTRIC_ORE_GRINDER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.DIAMOND_PICKAXE), null, SlimefunItems.GILDED_IRON, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON, SlimefunItems.GILDED_IRON, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.GILDED_IRON}) { - - @Override - public int getEnergyConsumption() { - return 6; - } - - @Override - public int getCapacity() { - return 128; - } - - @Override - public int getSpeed() { - return 1; - } - - }.register(plugin); - - new ElectricOreGrinder(categories.electricity, SlimefunItems.ELECTRIC_ORE_GRINDER_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.DIAMOND_PICKAXE), null, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRIC_ORE_GRINDER, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.GILDED_IRON}) { - - @Override - public int getEnergyConsumption() { - return 15; - } - - @Override - public int getCapacity() { - return 512; - } - - @Override - public int getSpeed() { - return 4; - } - - }.register(plugin); - - new HeatedPressureChamber(categories.electricity, SlimefunItems.HEATED_PRESSURE_CHAMBER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.LEAD_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, new ItemStack(Material.GLASS), SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.LEAD_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 5; - } - - @Override - public int getCapacity() { - return 128; - } - - @Override - public int getSpeed() { - return 1; - } - - }.register(plugin); - - new HeatedPressureChamber(categories.electricity, SlimefunItems.HEATED_PRESSURE_CHAMBER_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.LEAD_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.HEATED_PRESSURE_CHAMBER, SlimefunItems.LEAD_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.REINFORCED_ALLOY_INGOT}) { - - @Override - public int getEnergyConsumption() { - return 22; - } - - @Override - public int getCapacity() { - return 256; - } - - @Override - public int getSpeed() { - return 5; - } - - }.register(plugin); - - new ElectricIngotPulverizer(categories.electricity, SlimefunItems.ELECTRIC_INGOT_PULVERIZER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.ELECTRIC_ORE_GRINDER, null, SlimefunItems.LEAD_INGOT, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.LEAD_INGOT}) - .register(plugin); - - new CoalGenerator(categories.electricity, SlimefunItems.COAL_GENERATOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.HEATING_COIL, new ItemStack(Material.FURNACE), SlimefunItems.HEATING_COIL, SlimefunItems.NICKEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.NICKEL_INGOT, null, SlimefunItems.NICKEL_INGOT, null}) { - - @Override - public int getEnergyProduction() { - return 8; - } - - @Override - public int getCapacity() { - return 64; - } - - }.register(plugin); - - new CoalGenerator(categories.electricity, SlimefunItems.COAL_GENERATOR_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.MAGMA_BLOCK), SlimefunItems.HEATING_COIL, new ItemStack(Material.MAGMA_BLOCK), SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.COAL_GENERATOR, SlimefunItems.HARDENED_METAL_INGOT, null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public int getEnergyProduction() { - return 15; - } - - @Override - public int getCapacity() { - return 256; - } - - }.register(plugin); - - new BioGenerator(categories.electricity, SlimefunItems.BIO_REACTOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.HEATING_COIL, SlimefunItems.COMPOSTER, SlimefunItems.HEATING_COIL, SlimefunItems.ALUMINUM_BRASS_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_BRASS_INGOT, null, SlimefunItems.ALUMINUM_BRASS_INGOT, null}) { - - @Override - public int getEnergyProduction() { - return 4; - } - - @Override - public int getCapacity() { - return 128; - } - - }.register(plugin); - - if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { - new AutoDrier(categories.electricity, SlimefunItems.AUTO_DRIER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[]{null, null, null, SlimefunItems.HEATING_COIL, new ItemStack(Material.SMOKER), SlimefunItems.HEATING_COIL, null, new ItemStack(Material.CAMPFIRE), null}) - .register(plugin); - } - else { - new AutoDrier(categories.electricity, SlimefunItems.AUTO_DRIER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[]{null, null, null, SlimefunItems.HEATING_COIL, new ItemStack(Material.FURNACE), SlimefunItems.HEATING_COIL, null, new ItemStack(Material.TORCH), null}) - .register(plugin); - } - - new AutoBrewer(categories.electricity, SlimefunItems.AUTO_BREWER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.HEATING_COIL, null, SlimefunItems.REINFORCED_PLATE, new ItemStack(Material.BREWING_STAND), SlimefunItems.REINFORCED_PLATE, null, SlimefunItems.ELECTRIC_MOTOR, null}) { + ).register(plugin); + + new SlimefunItem(categories.easter, SlimefunItems.EASTER_CARROT_PIE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.CARROT), new ItemStack(Material.EGG), null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.EASTER_CARROT_PIE, 2)) + .register(plugin); + + new SlimefunItem(categories.easter, SlimefunItems.EASTER_APPLE_PIE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.SUGAR), new ItemStack(Material.APPLE), new ItemStack(Material.EGG), null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.CHRISTMAS_APPLE_PIE, 2)) + .register(plugin); + + new EasterEgg(categories.easter, SlimefunItems.EASTER_EGG, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, null, new ItemStack(Material.LIME_DYE), new ItemStack(Material.EGG), new ItemStack(Material.PURPLE_DYE), null, null, null}, + new SlimefunItemStack(SlimefunItems.EASTER_EGG, 2), + // Gifts: + new SlimefunItemStack(SlimefunItems.EASTER_CARROT_PIE, 4), + new SlimefunItemStack(SlimefunItems.CARROT_JUICE, 1), + new ItemStack(Material.EMERALD), + new ItemStack(Material.CAKE), + new ItemStack(Material.RABBIT_FOOT), + new ItemStack(Material.GOLDEN_CARROT, 4) + ).register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.REINFORCED_PLATE, RecipeType.COMPRESSOR, + new ItemStack[] {new SlimefunItemStack(SlimefunItems.REINFORCED_ALLOY_INGOT, 8), null, null, null, null, null, null, null, null}) + .register(plugin); + + new HardenedGlass(categories.technicalComponents, SlimefunItems.HARDENED_GLASS, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), SlimefunItems.REINFORCED_PLATE, new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS)}, + new SlimefunItemStack(SlimefunItems.HARDENED_GLASS, 16)) + .register(plugin); + + new SlimefunItem(categories.technicalComponents, SlimefunItems.COOLING_UNIT, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.ICE), new ItemStack(Material.ICE), new ItemStack(Material.ICE), SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_INGOT, new ItemStack(Material.ICE), new ItemStack(Material.ICE), new ItemStack(Material.ICE)}) + .register(plugin); + + new Cooler(27, categories.usefulItems, SlimefunItems.COOLER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.CLOTH, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.COOLING_UNIT, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ALUMINUM_INGOT}) + .register(plugin); + + new WitherProofBlock(categories.technicalComponents, SlimefunItems.WITHER_PROOF_OBSIDIAN, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.LEAD_INGOT, new ItemStack(Material.OBSIDIAN), SlimefunItems.LEAD_INGOT, new ItemStack(Material.OBSIDIAN), SlimefunItems.HARDENED_GLASS, new ItemStack(Material.OBSIDIAN), SlimefunItems.LEAD_INGOT, new ItemStack(Material.OBSIDIAN), SlimefunItems.LEAD_INGOT}, + new SlimefunItemStack(SlimefunItems.WITHER_PROOF_OBSIDIAN, 4)) + .register(plugin); + + new AncientPedestal(categories.magicalResources, SlimefunItems.ANCIENT_PEDESTAL, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {new ItemStack(Material.OBSIDIAN), SlimefunItems.GOLD_8K, new ItemStack(Material.OBSIDIAN), null, new ItemStack(Material.STONE), null, new ItemStack(Material.OBSIDIAN), SlimefunItems.GOLD_8K, new ItemStack(Material.OBSIDIAN)}, + new SlimefunItemStack(SlimefunItems.ANCIENT_PEDESTAL, 4)) + .register(plugin); + + new AncientAltar(categories.magicalGadgets, 8, SlimefunItems.ANCIENT_ALTAR, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {null, new ItemStack(Material.ENCHANTING_TABLE), null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.GOLD_8K, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.OBSIDIAN), SlimefunItems.GOLD_8K, new ItemStack(Material.OBSIDIAN)}) + .register(plugin); + + new EnergyRegulator(categories.electricity, SlimefunItems.ENERGY_REGULATOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SILVER_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.SILVER_INGOT}) + .register(plugin); + + new SlimefunItem(categories.misc, SlimefunItems.DUCT_TAPE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.ALUMINUM_DUST, SlimefunItems.ALUMINUM_DUST, SlimefunItems.ALUMINUM_DUST, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.PAPER), new ItemStack(Material.PAPER), new ItemStack(Material.PAPER)}, + new SlimefunItemStack(SlimefunItems.DUCT_TAPE, 2)) + .register(plugin); + + new Capacitor(categories.electricity, 128, SlimefunItems.SMALL_CAPACITOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.DURALUMIN_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.DURALUMIN_INGOT, new ItemStack(Material.REDSTONE), SlimefunItems.SULFATE, new ItemStack(Material.REDSTONE), SlimefunItems.DURALUMIN_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.DURALUMIN_INGOT}) + .register(plugin); + + new Capacitor(categories.electricity, 512, SlimefunItems.MEDIUM_CAPACITOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.BILLON_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.BILLON_INGOT, new ItemStack(Material.REDSTONE), SlimefunItems.SMALL_CAPACITOR, new ItemStack(Material.REDSTONE), SlimefunItems.BILLON_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.BILLON_INGOT}) + .register(plugin); + + new Capacitor(categories.electricity, 1024, SlimefunItems.BIG_CAPACITOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.STEEL_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.STEEL_INGOT, new ItemStack(Material.REDSTONE), SlimefunItems.MEDIUM_CAPACITOR, new ItemStack(Material.REDSTONE), SlimefunItems.STEEL_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.STEEL_INGOT}) + .register(plugin); + + new Capacitor(categories.electricity, 8192, SlimefunItems.LARGE_CAPACITOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.REINFORCED_ALLOY_INGOT, new ItemStack(Material.REDSTONE), SlimefunItems.BIG_CAPACITOR, new ItemStack(Material.REDSTONE), SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.REINFORCED_ALLOY_INGOT}) + .register(plugin); + + new Capacitor(categories.electricity, 65536, SlimefunItems.CARBONADO_EDGED_CAPACITOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CARBONADO, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.CARBONADO, new ItemStack(Material.REDSTONE), SlimefunItems.LARGE_CAPACITOR, new ItemStack(Material.REDSTONE), SlimefunItems.CARBONADO, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.CARBONADO}) + .register(plugin); + + new SolarGenerator(categories.electricity, 2, 0, SlimefunItems.SOLAR_GENERATOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SOLAR_PANEL, SlimefunItems.SOLAR_PANEL, SlimefunItems.SOLAR_PANEL, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_INGOT, null, SlimefunItems.ALUMINUM_INGOT, null}) + .register(plugin); + + new SolarGenerator(categories.electricity, 8, 0, SlimefunItems.SOLAR_GENERATOR_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SOLAR_GENERATOR, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR, SlimefunItems.ALUMINUM_INGOT, new ItemStack(Material.REDSTONE), SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR}) + .register(plugin); + + new SolarGenerator(categories.electricity, 32, 0, SlimefunItems.SOLAR_GENERATOR_3, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SOLAR_GENERATOR_2, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR_2, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.CARBONADO, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR_2, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR_2}) + .register(plugin); + + new SolarGenerator(categories.electricity, 128, 64, SlimefunItems.SOLAR_GENERATOR_4, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3}) + .register(plugin); + + new ChargingBench(categories.electricity, SlimefunItems.CHARGING_BENCH, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.ELECTRO_MAGNET, null, SlimefunItems.BATTERY, new ItemStack(Material.CRAFTING_TABLE), SlimefunItems.BATTERY, null, SlimefunItems.SMALL_CAPACITOR, null}) + .register(plugin); + + new ElectricFurnace(categories.electricity, SlimefunItems.ELECTRIC_FURNACE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.FURNACE), null, SlimefunItems.GILDED_IRON, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON, SlimefunItems.GILDED_IRON, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.GILDED_IRON}) { + + @Override + public int getEnergyConsumption() { + return 2; + } + + @Override + public int getCapacity() { + return 64; + } + + @Override + public int getSpeed() { + return 1; + } + + }.register(plugin); + + new ElectricFurnace(categories.electricity, SlimefunItems.ELECTRIC_FURNACE_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.ELECTRIC_MOTOR, null, SlimefunItems.GILDED_IRON, SlimefunItems.ELECTRIC_FURNACE, SlimefunItems.GILDED_IRON, SlimefunItems.GILDED_IRON, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON}) { + + @Override + public int getEnergyConsumption() { + return 3; + } + + @Override + public int getCapacity() { + return 128; + } + + @Override + public int getSpeed() { + return 2; + } + + }.register(plugin); + + new ElectricFurnace(categories.electricity, SlimefunItems.ELECTRIC_FURNACE_3, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.ELECTRIC_MOTOR, null, SlimefunItems.STEEL_INGOT, SlimefunItems.ELECTRIC_FURNACE_2, SlimefunItems.STEEL_INGOT, SlimefunItems.GILDED_IRON, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON}) { + + @Override + public int getEnergyConsumption() { + return 5; + } + + @Override + public int getCapacity() { + return 128; + } + + @Override + public int getSpeed() { + return 4; + } + + }.register(plugin); + + new ElectricGoldPan(categories.electricity, SlimefunItems.ELECTRIC_GOLD_PAN, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.GOLD_PAN, null, new ItemStack(Material.FLINT), SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.FLINT), SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ALUMINUM_INGOT}) { + + @Override + public int getEnergyConsumption() { + return 1; + } + + @Override + public int getCapacity() { + return 128; + } @Override public int getSpeed() { return 1; } - }.register(plugin); + }.register(plugin); - new ElectricPress(categories.electricity, SlimefunItems.ELECTRIC_PRESS, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.PISTON), SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.PISTON), null, SlimefunItems.MEDIUM_CAPACITOR, null, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT}) { + new ElectricGoldPan(categories.electricity, SlimefunItems.ELECTRIC_GOLD_PAN_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.GOLD_PAN, null, new ItemStack(Material.IRON_INGOT), SlimefunItems.ELECTRIC_GOLD_PAN, new ItemStack(Material.IRON_INGOT), SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT}) { - @Override - public int getEnergyConsumption() { - return 8; - } + @Override + public int getEnergyConsumption() { + return 2; + } - @Override - public int getCapacity() { - return 256; - } + @Override + public int getCapacity() { + return 128; + } - @Override - public int getSpeed() { - return 1; - } + @Override + public int getSpeed() { + return 3; + } + + }.register(plugin); - }.register(plugin); + new ElectricGoldPan(categories.electricity, SlimefunItems.ELECTRIC_GOLD_PAN_3, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.GOLD_PAN, null, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ELECTRIC_GOLD_PAN_2, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.COBALT_INGOT, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.COBALT_INGOT}) { - new ElectricPress(categories.electricity, SlimefunItems.ELECTRIC_PRESS_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.STICKY_PISTON), SlimefunItems.ELECTRIC_PRESS, new ItemStack(Material.STICKY_PISTON), SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.BIG_CAPACITOR, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT}) { + @Override + public int getEnergyConsumption() { + return 7; + } - @Override - public int getEnergyConsumption() { - return 20; - } + @Override + public int getCapacity() { + return 512; + } - @Override - public int getCapacity() { - return 1024; - } + @Override + public int getSpeed() { + return 10; + } + + }.register(plugin); - @Override - public int getSpeed() { - return 3; - } + new ElectricDustWasher(categories.electricity, SlimefunItems.ELECTRIC_DUST_WASHER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.WATER_BUCKET), null, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.ELECTRIC_GOLD_PAN, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.COPPER_INGOT, SlimefunItems.COPPER_INGOT, SlimefunItems.COPPER_INGOT}) { - }.register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.MAGNESIUM_SALT, RecipeType.HEATED_PRESSURE_CHAMBER, - new ItemStack[] {SlimefunItems.MAGNESIUM_DUST, SlimefunItems.SALT, null, null, null, null, null, null, null}) - .register(plugin); - - new MagnesiumGenerator(categories.electricity, SlimefunItems.MAGNESIUM_GENERATOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.ELECTRIC_MOTOR, null, SlimefunItems.COMPRESSED_CARBON, new ItemStack(Material.WATER_BUCKET), SlimefunItems.COMPRESSED_CARBON, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT}) { - - @Override - public int getEnergyProduction() { - return 18; - } + @Override + public int getEnergyConsumption() { + return 3; + } - @Override - public int getCapacity() { - return 128; - } + @Override + public int getCapacity() { + return 128; + } - }.register(plugin); + @Override + public int getSpeed() { + return 1; + } + + }.register(plugin); - new AutoEnchanter(categories.electricity, SlimefunItems.AUTO_ENCHANTER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.ENCHANTING_TABLE), null, SlimefunItems.CARBONADO, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.CARBONADO, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.WITHER_PROOF_OBSIDIAN}) - .register(plugin); + new ElectricDustWasher(categories.electricity, SlimefunItems.ELECTRIC_DUST_WASHER_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.WATER_BUCKET), null, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.ELECTRIC_DUST_WASHER, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT}) { - new AutoDisenchanter(categories.electricity, SlimefunItems.AUTO_DISENCHANTER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.REDSTONE), new ItemStack(Material.ANVIL), new ItemStack(Material.REDSTONE), SlimefunItems.CARBONADO, SlimefunItems.AUTO_ENCHANTER, SlimefunItems.CARBONADO, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.WITHER_PROOF_OBSIDIAN}) - .register(plugin); + @Override + public int getEnergyConsumption() { + return 5; + } - new AutoAnvil(categories.electricity, SlimefunItems.AUTO_ANVIL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.ANVIL), null, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT, new ItemStack(Material.IRON_BLOCK), new ItemStack(Material.IRON_BLOCK), new ItemStack(Material.IRON_BLOCK)}) { + @Override + public int getCapacity() { + return 128; + } - @Override - public int getRepairFactor() { - return 10; - } + @Override + public int getSpeed() { + return 2; + } + + }.register(plugin); - @Override - public int getCapacity() { - return 128; - } + new ElectricDustWasher(categories.electricity, SlimefunItems.ELECTRIC_DUST_WASHER_3, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.WATER_BUCKET), null, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.ELECTRIC_DUST_WASHER_2, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.CORINTHIAN_BRONZE_INGOT}) { - @Override - public int getEnergyConsumption() { - return 12; - } + @Override + public int getEnergyConsumption() { + return 15; + } - }.register(plugin); + @Override + public int getCapacity() { + return 512; + } - new AutoAnvil(categories.electricity, SlimefunItems.AUTO_ANVIL_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.AUTO_ANVIL, null, SlimefunItems.STEEL_PLATE, SlimefunItems.HEATING_COIL, SlimefunItems.STEEL_PLATE, new ItemStack(Material.IRON_BLOCK), new ItemStack(Material.IRON_BLOCK), new ItemStack(Material.IRON_BLOCK)}) { + @Override + public int getSpeed() { + return 10; + } + + }.register(plugin); - @Override - public int getRepairFactor() { - return 4; - } + new ElectricIngotFactory(categories.electricity, SlimefunItems.ELECTRIC_INGOT_FACTORY, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.FLINT_AND_STEEL), null, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRIC_DUST_WASHER, SlimefunItems.HEATING_COIL, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.DAMASCUS_STEEL_INGOT}) { + + @Override + public int getEnergyConsumption() { + return 4; + } - @Override - public int getCapacity() { - return 256; - } + @Override + public int getCapacity() { + return 256; + } - @Override - public int getEnergyConsumption() { - return 16; - } + @Override + public int getSpeed() { + return 1; + } - }.register(plugin); + }.register(plugin); - new Multimeter(categories.technicalGadgets, SlimefunItems.MULTIMETER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.COPPER_INGOT, null, SlimefunItems.COPPER_INGOT, null, SlimefunItems.REDSTONE_ALLOY, null, null, SlimefunItems.GOLD_6K, null}) - .register(plugin); + new ElectricIngotFactory(categories.electricity, SlimefunItems.ELECTRIC_INGOT_FACTORY_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.GILDED_IRON, new ItemStack(Material.FLINT_AND_STEEL), SlimefunItems.GILDED_IRON, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRIC_INGOT_FACTORY, SlimefunItems.HEATING_COIL, SlimefunItems.BRASS_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.BRASS_INGOT}) { - new SlimefunItem(categories.technicalComponents, SlimefunItems.PLASTIC_SHEET, RecipeType.HEATED_PRESSURE_CHAMBER, - new ItemStack[] {null, null, null, null, SlimefunItems.OIL_BUCKET, null, null, null, null}) - .register(plugin); + @Override + public int getEnergyConsumption() { + return 7; + } - new UnplaceableBlock(categories.technicalComponents, SlimefunItems.ANDROID_MEMORY_CORE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.BRASS_INGOT, new ItemStack(Material.ORANGE_STAINED_GLASS), SlimefunItems.BRASS_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.TIN_DUST, SlimefunItems.POWER_CRYSTAL, SlimefunItems.BRASS_INGOT, new ItemStack(Material.ORANGE_STAINED_GLASS), SlimefunItems.BRASS_INGOT}) - .register(plugin); + @Override + public int getCapacity() { + return 256; + } - new GPSTransmitter(categories.gps, SlimefunItems.GPS_TRANSMITTER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.STEEL_INGOT, SlimefunItems.ADVANCED_CIRCUIT_BOARD, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.STEEL_INGOT}) { - - @Override - public int getMultiplier(int y) { - return y; - } + @Override + public int getSpeed() { + return 2; + } - @Override - public int getCapacity() { - return 16; - } + }.register(plugin); - @Override - public int getEnergyConsumption() { - return 1; - } + new ElectricIngotFactory(categories.electricity, SlimefunItems.ELECTRIC_INGOT_FACTORY_3, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.GILDED_IRON, new ItemStack(Material.FLINT_AND_STEEL), SlimefunItems.GILDED_IRON, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRIC_INGOT_FACTORY_2, SlimefunItems.HEATING_COIL, SlimefunItems.BRASS_INGOT, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.BRASS_INGOT}) { - }.register(plugin); + @Override + public int getEnergyConsumption() { + return 20; + } - new GPSTransmitter(categories.gps, SlimefunItems.GPS_TRANSMITTER_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.GPS_TRANSMITTER, SlimefunItems.BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER, SlimefunItems.BRONZE_INGOT, SlimefunItems.CARBON, SlimefunItems.BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER, SlimefunItems.BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER}) { - - @Override - public int getMultiplier(int y) { - return y * 4 + 100; - } + @Override + public int getCapacity() { + return 512; + } - @Override - public int getCapacity() { - return 64; - } + @Override + public int getSpeed() { + return 8; + } - @Override - public int getEnergyConsumption() { - return 3; - } + }.register(plugin); - }.register(plugin); + new ElectrifiedCrucible(categories.electricity, SlimefunItems.ELECTRIFIED_CRUCIBLE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.LEAD_INGOT, SlimefunItems.CRUCIBLE, SlimefunItems.LEAD_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.LARGE_CAPACITOR, SlimefunItems.LEAD_INGOT}) { - new GPSTransmitter(categories.gps, SlimefunItems.GPS_TRANSMITTER_3, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.GPS_TRANSMITTER_2, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER_2, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.CARBONADO, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER_2, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER_2}) { - - @Override - public int getMultiplier(int y) { - return y * 16 + 500; - } + @Override + public int getEnergyConsumption() { + return 24; + } - @Override - public int getCapacity() { - return 256; - } + @Override + public int getCapacity() { + return 1024; + } - @Override - public int getEnergyConsumption() { - return 11; - } + @Override + public int getSpeed() { + return 1; + } - }.register(plugin); + }.register(plugin); - new GPSTransmitter(categories.gps, SlimefunItems.GPS_TRANSMITTER_4, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.GPS_TRANSMITTER_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.GPS_TRANSMITTER_3, SlimefunItems.NICKEL_INGOT, SlimefunItems.CARBONADO, SlimefunItems.NICKEL_INGOT, SlimefunItems.GPS_TRANSMITTER_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.GPS_TRANSMITTER_3}) { - - @Override - public int getMultiplier(int y) { - return y * 64 + 600; - } + new ElectrifiedCrucible(categories.electricity, SlimefunItems.ELECTRIFIED_CRUCIBLE_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.ELECTRIFIED_CRUCIBLE, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.LEAD_INGOT}) { - @Override - public int getCapacity() { - return 1024; - } + @Override + public int getEnergyConsumption() { + return 40; + } - @Override - public int getEnergyConsumption() { - return 46; - } - - }.register(plugin); + @Override + public int getCapacity() { + return 1024; + } - new GPSControlPanel(categories.gps, SlimefunItems.GPS_CONTROL_PANEL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.COBALT_INGOT, SlimefunItems.ADVANCED_CIRCUIT_BOARD, SlimefunItems.COBALT_INGOT, SlimefunItems.ALUMINUM_BRASS_INGOT, SlimefunItems.ALUMINUM_BRASS_INGOT, SlimefunItems.ALUMINUM_BRASS_INGOT}) - .register(plugin); + @Override + public int getSpeed() { + return 2; + } - new GPSMarkerTool(categories.gps, SlimefunItems.GPS_MARKER_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.ELECTRO_MAGNET, null, new ItemStack(Material.LAPIS_LAZULI), SlimefunItems.BASIC_CIRCUIT_BOARD, new ItemStack(Material.LAPIS_LAZULI), new ItemStack(Material.REDSTONE), SlimefunItems.REDSTONE_ALLOY, new ItemStack(Material.REDSTONE)}) - .register(plugin); + }.register(plugin); - new SlimefunItem(categories.gps, SlimefunItems.GPS_EMERGENCY_TRANSMITTER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.ELECTRO_MAGNET, null, null, SlimefunItems.GPS_TRANSMITTER, null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) - .register(plugin); + new ElectrifiedCrucible(categories.electricity, SlimefunItems.ELECTRIFIED_CRUCIBLE_3, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.ELECTRIFIED_CRUCIBLE_2, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.STEEL_PLATE, SlimefunItems.POWER_CRYSTAL, SlimefunItems.STEEL_PLATE, SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT}) { + + @Override + public int getEnergyConsumption() { + return 60; + } + + @Override + public int getCapacity() { + return 1024; + } + + @Override + public int getSpeed() { + return 4; + } + + }.register(plugin); + + new ElectricOreGrinder(categories.electricity, SlimefunItems.ELECTRIC_ORE_GRINDER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.DIAMOND_PICKAXE), null, SlimefunItems.GILDED_IRON, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON, SlimefunItems.GILDED_IRON, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.GILDED_IRON}) { + + @Override + public int getEnergyConsumption() { + return 6; + } + + @Override + public int getCapacity() { + return 128; + } + + @Override + public int getSpeed() { + return 1; + } + + }.register(plugin); + + new ElectricOreGrinder(categories.electricity, SlimefunItems.ELECTRIC_ORE_GRINDER_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.DIAMOND_PICKAXE), null, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRIC_ORE_GRINDER, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.GILDED_IRON}) { + + @Override + public int getEnergyConsumption() { + return 15; + } + + @Override + public int getCapacity() { + return 512; + } + + @Override + public int getSpeed() { + return 4; + } + + }.register(plugin); + + new HeatedPressureChamber(categories.electricity, SlimefunItems.HEATED_PRESSURE_CHAMBER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.LEAD_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, new ItemStack(Material.GLASS), SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.LEAD_INGOT}) { + + @Override + public int getEnergyConsumption() { + return 5; + } + + @Override + public int getCapacity() { + return 128; + } + + @Override + public int getSpeed() { + return 1; + } + + }.register(plugin); + + new HeatedPressureChamber(categories.electricity, SlimefunItems.HEATED_PRESSURE_CHAMBER_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.LEAD_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.HEATED_PRESSURE_CHAMBER, SlimefunItems.LEAD_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.REINFORCED_ALLOY_INGOT}) { + + @Override + public int getEnergyConsumption() { + return 22; + } + + @Override + public int getCapacity() { + return 256; + } + + @Override + public int getSpeed() { + return 5; + } + + }.register(plugin); + + new ElectricIngotPulverizer(categories.electricity, SlimefunItems.ELECTRIC_INGOT_PULVERIZER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.ELECTRIC_ORE_GRINDER, null, SlimefunItems.LEAD_INGOT, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.LEAD_INGOT}) + .register(plugin); + + new CoalGenerator(categories.electricity, SlimefunItems.COAL_GENERATOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.HEATING_COIL, new ItemStack(Material.FURNACE), SlimefunItems.HEATING_COIL, SlimefunItems.NICKEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.NICKEL_INGOT, null, SlimefunItems.NICKEL_INGOT, null}) { + + @Override + public int getEnergyProduction() { + return 8; + } + + @Override + public int getCapacity() { + return 64; + } + + }.register(plugin); + + new CoalGenerator(categories.electricity, SlimefunItems.COAL_GENERATOR_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.MAGMA_BLOCK), SlimefunItems.HEATING_COIL, new ItemStack(Material.MAGMA_BLOCK), SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.COAL_GENERATOR, SlimefunItems.HARDENED_METAL_INGOT, null, SlimefunItems.ELECTRIC_MOTOR, null}) { + + @Override + public int getEnergyProduction() { + return 15; + } + + @Override + public int getCapacity() { + return 256; + } + + }.register(plugin); + + new BioGenerator(categories.electricity, SlimefunItems.BIO_REACTOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.HEATING_COIL, SlimefunItems.COMPOSTER, SlimefunItems.HEATING_COIL, SlimefunItems.ALUMINUM_BRASS_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_BRASS_INGOT, null, SlimefunItems.ALUMINUM_BRASS_INGOT, null}) { + + @Override + public int getEnergyProduction() { + return 4; + } + + @Override + public int getCapacity() { + return 128; + } + + }.register(plugin); + + if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { + new AutoDrier(categories.electricity, SlimefunItems.AUTO_DRIER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[]{null, null, null, SlimefunItems.HEATING_COIL, new ItemStack(Material.SMOKER), SlimefunItems.HEATING_COIL, null, new ItemStack(Material.CAMPFIRE), null}) + .register(plugin); + } + else { + new AutoDrier(categories.electricity, SlimefunItems.AUTO_DRIER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[]{null, null, null, SlimefunItems.HEATING_COIL, new ItemStack(Material.FURNACE), SlimefunItems.HEATING_COIL, null, new ItemStack(Material.TORCH), null}) + .register(plugin); + } + + new AutoBrewer(categories.electricity, SlimefunItems.AUTO_BREWER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.HEATING_COIL, null, SlimefunItems.REINFORCED_PLATE, new ItemStack(Material.BREWING_STAND), SlimefunItems.REINFORCED_PLATE, null, SlimefunItems.ELECTRIC_MOTOR, null}) { + + @Override + public int getSpeed() { + return 1; + } + + }.register(plugin); + + new ElectricPress(categories.electricity, SlimefunItems.ELECTRIC_PRESS, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.PISTON), SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.PISTON), null, SlimefunItems.MEDIUM_CAPACITOR, null, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT}) { + + @Override + public int getEnergyConsumption() { + return 8; + } + + @Override + public int getCapacity() { + return 256; + } + + @Override + public int getSpeed() { + return 1; + } + + }.register(plugin); + + new ElectricPress(categories.electricity, SlimefunItems.ELECTRIC_PRESS_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.STICKY_PISTON), SlimefunItems.ELECTRIC_PRESS, new ItemStack(Material.STICKY_PISTON), SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.BIG_CAPACITOR, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.DAMASCUS_STEEL_INGOT}) { + + @Override + public int getEnergyConsumption() { + return 20; + } + + @Override + public int getCapacity() { + return 1024; + } + + @Override + public int getSpeed() { + return 3; + } + + }.register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.MAGNESIUM_SALT, RecipeType.HEATED_PRESSURE_CHAMBER, + new ItemStack[] {SlimefunItems.MAGNESIUM_DUST, SlimefunItems.SALT, null, null, null, null, null, null, null}) + .register(plugin); + + new MagnesiumGenerator(categories.electricity, SlimefunItems.MAGNESIUM_GENERATOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.ELECTRIC_MOTOR, null, SlimefunItems.COMPRESSED_CARBON, new ItemStack(Material.WATER_BUCKET), SlimefunItems.COMPRESSED_CARBON, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT, SlimefunItems.DURALUMIN_INGOT}) { + + @Override + public int getEnergyProduction() { + return 18; + } + + @Override + public int getCapacity() { + return 128; + } + + }.register(plugin); + + new AutoEnchanter(categories.electricity, SlimefunItems.AUTO_ENCHANTER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.ENCHANTING_TABLE), null, SlimefunItems.CARBONADO, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.CARBONADO, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.WITHER_PROOF_OBSIDIAN}) + .register(plugin); + + new AutoDisenchanter(categories.electricity, SlimefunItems.AUTO_DISENCHANTER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.REDSTONE), new ItemStack(Material.ANVIL), new ItemStack(Material.REDSTONE), SlimefunItems.CARBONADO, SlimefunItems.AUTO_ENCHANTER, SlimefunItems.CARBONADO, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.WITHER_PROOF_OBSIDIAN}) + .register(plugin); + + new AutoAnvil(categories.electricity, SlimefunItems.AUTO_ANVIL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.ANVIL), null, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT, new ItemStack(Material.IRON_BLOCK), new ItemStack(Material.IRON_BLOCK), new ItemStack(Material.IRON_BLOCK)}) { + + @Override + public int getRepairFactor() { + return 10; + } + + @Override + public int getCapacity() { + return 128; + } + + @Override + public int getEnergyConsumption() { + return 12; + } + + }.register(plugin); + + new AutoAnvil(categories.electricity, SlimefunItems.AUTO_ANVIL_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.AUTO_ANVIL, null, SlimefunItems.STEEL_PLATE, SlimefunItems.HEATING_COIL, SlimefunItems.STEEL_PLATE, new ItemStack(Material.IRON_BLOCK), new ItemStack(Material.IRON_BLOCK), new ItemStack(Material.IRON_BLOCK)}) { + + @Override + public int getRepairFactor() { + return 4; + } + + @Override + public int getCapacity() { + return 256; + } + + @Override + public int getEnergyConsumption() { + return 16; + } + + }.register(plugin); + + new Multimeter(categories.technicalGadgets, SlimefunItems.MULTIMETER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.COPPER_INGOT, null, SlimefunItems.COPPER_INGOT, null, SlimefunItems.REDSTONE_ALLOY, null, null, SlimefunItems.GOLD_6K, null}) + .register(plugin); + + new SlimefunItem(categories.technicalComponents, SlimefunItems.PLASTIC_SHEET, RecipeType.HEATED_PRESSURE_CHAMBER, + new ItemStack[] {null, null, null, null, SlimefunItems.OIL_BUCKET, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.PLASTIC_SHEET, 8)) + .register(plugin); + + new UnplaceableBlock(categories.technicalComponents, SlimefunItems.ANDROID_MEMORY_CORE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.BRASS_INGOT, new ItemStack(Material.ORANGE_STAINED_GLASS), SlimefunItems.BRASS_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.TIN_DUST, SlimefunItems.POWER_CRYSTAL, SlimefunItems.BRASS_INGOT, new ItemStack(Material.ORANGE_STAINED_GLASS), SlimefunItems.BRASS_INGOT}) + .register(plugin); + + new GPSTransmitter(categories.gps, SlimefunItems.GPS_TRANSMITTER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.STEEL_INGOT, SlimefunItems.ADVANCED_CIRCUIT_BOARD, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.STEEL_INGOT}) { + + @Override + public int getMultiplier(int y) { + return y; + } + + @Override + public int getCapacity() { + return 16; + } + + @Override + public int getEnergyConsumption() { + return 1; + } + + }.register(plugin); + + new GPSTransmitter(categories.gps, SlimefunItems.GPS_TRANSMITTER_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.GPS_TRANSMITTER, SlimefunItems.BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER, SlimefunItems.BRONZE_INGOT, SlimefunItems.CARBON, SlimefunItems.BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER, SlimefunItems.BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER}) { + + @Override + public int getMultiplier(int y) { + return y * 4 + 100; + } + + @Override + public int getCapacity() { + return 64; + } + + @Override + public int getEnergyConsumption() { + return 3; + } + + }.register(plugin); + + new GPSTransmitter(categories.gps, SlimefunItems.GPS_TRANSMITTER_3, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.GPS_TRANSMITTER_2, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER_2, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.CARBONADO, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER_2, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.GPS_TRANSMITTER_2}) { + + @Override + public int getMultiplier(int y) { + return y * 16 + 500; + } + + @Override + public int getCapacity() { + return 256; + } + + @Override + public int getEnergyConsumption() { + return 11; + } + + }.register(plugin); + + new GPSTransmitter(categories.gps, SlimefunItems.GPS_TRANSMITTER_4, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.GPS_TRANSMITTER_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.GPS_TRANSMITTER_3, SlimefunItems.NICKEL_INGOT, SlimefunItems.CARBONADO, SlimefunItems.NICKEL_INGOT, SlimefunItems.GPS_TRANSMITTER_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.GPS_TRANSMITTER_3}) { + + @Override + public int getMultiplier(int y) { + return y * 64 + 600; + } + + @Override + public int getCapacity() { + return 1024; + } + + @Override + public int getEnergyConsumption() { + return 46; + } + + }.register(plugin); + + new GPSControlPanel(categories.gps, SlimefunItems.GPS_CONTROL_PANEL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.COBALT_INGOT, SlimefunItems.ADVANCED_CIRCUIT_BOARD, SlimefunItems.COBALT_INGOT, SlimefunItems.ALUMINUM_BRASS_INGOT, SlimefunItems.ALUMINUM_BRASS_INGOT, SlimefunItems.ALUMINUM_BRASS_INGOT}) + .register(plugin); + + new GPSMarkerTool(categories.gps, SlimefunItems.GPS_MARKER_TOOL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.ELECTRO_MAGNET, null, new ItemStack(Material.LAPIS_LAZULI), SlimefunItems.BASIC_CIRCUIT_BOARD, new ItemStack(Material.LAPIS_LAZULI), new ItemStack(Material.REDSTONE), SlimefunItems.REDSTONE_ALLOY, new ItemStack(Material.REDSTONE)}) + .register(plugin); + + new SlimefunItem(categories.gps, SlimefunItems.GPS_EMERGENCY_TRANSMITTER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.ELECTRO_MAGNET, null, null, SlimefunItems.GPS_TRANSMITTER, null, null, SlimefunItems.ESSENCE_OF_AFTERLIFE, null}) + .register(plugin); new SlimefunItem(categories.androids, SlimefunItems.ANDROID_INTERFACE_ITEMS, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] {SlimefunItems.PLASTIC_SHEET, SlimefunItems.STEEL_INGOT, SlimefunItems.PLASTIC_SHEET, SlimefunItems.STEEL_INGOT, SlimefunItems.BASIC_CIRCUIT_BOARD, new ItemStack(Material.BLUE_STAINED_GLASS), SlimefunItems.PLASTIC_SHEET, SlimefunItems.STEEL_INGOT, SlimefunItems.PLASTIC_SHEET}) @@ -2202,1051 +2203,1037 @@ public final class SlimefunItemSetup { new ItemStack[] {SlimefunItems.PLASTIC_SHEET, SlimefunItems.STEEL_INGOT, SlimefunItems.PLASTIC_SHEET, new ItemStack(Material.RED_STAINED_GLASS), SlimefunItems.BASIC_CIRCUIT_BOARD, SlimefunItems.STEEL_INGOT, SlimefunItems.PLASTIC_SHEET, SlimefunItems.STEEL_INGOT, SlimefunItems.PLASTIC_SHEET}) .register(plugin); - new ProgrammableAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.PLASTIC_SHEET, SlimefunItems.ANDROID_MEMORY_CORE, SlimefunItems.PLASTIC_SHEET, SlimefunItems.COAL_GENERATOR, SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.CHEST), SlimefunItems.PLASTIC_SHEET, SlimefunItems.PLASTIC_SHEET, SlimefunItems.PLASTIC_SHEET}) { + new ProgrammableAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.PLASTIC_SHEET, SlimefunItems.ANDROID_MEMORY_CORE, SlimefunItems.PLASTIC_SHEET, SlimefunItems.COAL_GENERATOR, SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.CHEST), SlimefunItems.PLASTIC_SHEET, SlimefunItems.PLASTIC_SHEET, SlimefunItems.PLASTIC_SHEET}) { - @Override - public AndroidType getAndroidType() { - return AndroidType.NONE; - } - - @Override - public float getFuelEfficiency() { - return 1; - } - - @Override - public int getTier() { - return 1; - } - - } - .register(plugin); - - new MinerAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_MINER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, null, new ItemStack(Material.DIAMOND_PICKAXE), SlimefunItems.PROGRAMMABLE_ANDROID, new ItemStack(Material.DIAMOND_PICKAXE), null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public float getFuelEfficiency() { - return 1; - } - - @Override - public int getTier() { - return 1; - } - - } - .register(plugin); - - new FarmerAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_FARMER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, null, new ItemStack(Material.DIAMOND_HOE), SlimefunItems.PROGRAMMABLE_ANDROID, new ItemStack(Material.DIAMOND_HOE), null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public float getFuelEfficiency() { - return 1; - } - - @Override - public int getTier() { - return 1; - } - - } - .register(plugin); - - new WoodcutterAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_WOODCUTTER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, null, new ItemStack(Material.DIAMOND_AXE), SlimefunItems.PROGRAMMABLE_ANDROID, new ItemStack(Material.DIAMOND_AXE), null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public float getFuelEfficiency() { - return 1; - } - - @Override - public int getTier() { - return 1; - } - - } - .register(plugin); - - new FisherAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_FISHERMAN, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, null, new ItemStack(Material.FISHING_ROD), SlimefunItems.PROGRAMMABLE_ANDROID, new ItemStack(Material.FISHING_ROD), null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public float getFuelEfficiency() { - return 1; - } - - @Override - public int getTier() { - return 1; - } - - } - .register(plugin); - - new ButcherAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_BUTCHER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.GPS_TRANSMITTER, null, new ItemStack(Material.DIAMOND_SWORD), SlimefunItems.PROGRAMMABLE_ANDROID, new ItemStack(Material.DIAMOND_SWORD), null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public float getFuelEfficiency() { - return 1; - } - - @Override - public int getTier() { - return 1; - } - - } - .register(plugin); - - new ProgrammableAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.PLASTIC_SHEET, SlimefunItems.ANDROID_MEMORY_CORE, SlimefunItems.PLASTIC_SHEET, SlimefunItems.COMBUSTION_REACTOR, SlimefunItems.PROGRAMMABLE_ANDROID, new ItemStack(Material.CHEST), SlimefunItems.PLASTIC_SHEET, SlimefunItems.POWER_CRYSTAL, SlimefunItems.PLASTIC_SHEET}) { - - @Override - public AndroidType getAndroidType() { - return AndroidType.NONE; - } - - @Override - public float getFuelEfficiency() { - return 1.5F; - } - - @Override - public int getTier() { - return 2; - } - - } - .register(plugin); - - new FisherAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_2_FISHERMAN, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, null, new ItemStack(Material.FISHING_ROD), SlimefunItems.PROGRAMMABLE_ANDROID_2, new ItemStack(Material.FISHING_ROD), null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public float getFuelEfficiency() { - return 1.5F; - } - - @Override - public int getTier() { - return 2; - } - - } - .register(plugin); - - new ButcherAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_2_BUTCHER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.GPS_TRANSMITTER, null, new ItemStack(Material.DIAMOND_SWORD), SlimefunItems.PROGRAMMABLE_ANDROID_2, new ItemStack(Material.DIAMOND_SWORD), null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public float getFuelEfficiency() { - return 1.5F; - } - - @Override - public int getTier() { - return 2; - } - - } - .register(plugin); - - new AdvancedFarmerAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_2_FARMER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.GPS_TRANSMITTER, null, new ItemStack(Material.DIAMOND_HOE), SlimefunItems.PROGRAMMABLE_ANDROID_2, new ItemStack(Material.DIAMOND_HOE), null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public float getFuelEfficiency() { - return 1.5F; - } - - @Override - public int getTier() { - return 2; - } - - } - .register(plugin); - - new ProgrammableAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_3, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.PLASTIC_SHEET, SlimefunItems.ANDROID_MEMORY_CORE, SlimefunItems.PLASTIC_SHEET, SlimefunItems.NUCLEAR_REACTOR, SlimefunItems.PROGRAMMABLE_ANDROID_2, new ItemStack(Material.CHEST), SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.POWER_CRYSTAL, SlimefunItems.BLISTERING_INGOT_3}) { - - @Override - public AndroidType getAndroidType() { - return AndroidType.NONE; - } - - @Override - public float getFuelEfficiency() { - return 1F; - } - - @Override - public int getTier() { - return 3; - } - - } - .register(plugin); - - new FisherAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_3_FISHERMAN, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, null, new ItemStack(Material.FISHING_ROD), SlimefunItems.PROGRAMMABLE_ANDROID_3, new ItemStack(Material.FISHING_ROD), null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public float getFuelEfficiency() { - return 1F; - } - - @Override - public int getTier() { - return 3; - } - - } - .register(plugin); - - new ButcherAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_3_BUTCHER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.GPS_TRANSMITTER_3, null, new ItemStack(Material.DIAMOND_SWORD), SlimefunItems.PROGRAMMABLE_ANDROID_3, new ItemStack(Material.DIAMOND_SWORD), null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public float getFuelEfficiency() { - return 1F; - } - - @Override - public int getTier() { - return 3; - } - - } - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.BLANK_RUNE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.STONE), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.STONE), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.OBSIDIAN), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.STONE), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.STONE)}) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.AIR_RUNE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.FEATHER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.FEATHER), new ItemStack(Material.GHAST_TEAR), SlimefunItems.BLANK_RUNE, new ItemStack(Material.GHAST_TEAR), new ItemStack(Material.FEATHER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.FEATHER)}, - new CustomItem(SlimefunItems.AIR_RUNE, 4)) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.EARTH_RUNE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.DIRT), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.STONE), new ItemStack(Material.OBSIDIAN), SlimefunItems.BLANK_RUNE, new ItemStack(Material.OBSIDIAN), new ItemStack(Material.STONE), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.DIRT)}, - new CustomItem(SlimefunItems.EARTH_RUNE, 4)) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.FIRE_RUNE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.FIRE_CHARGE), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.FIRE_CHARGE), new ItemStack(Material.BLAZE_POWDER), SlimefunItems.EARTH_RUNE, new ItemStack(Material.FLINT_AND_STEEL), new ItemStack(Material.FIRE_CHARGE), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.FIRE_CHARGE)}, - new CustomItem(SlimefunItems.FIRE_RUNE, 4)) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.WATER_RUNE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.SALMON), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.WATER_BUCKET), new ItemStack(Material.SAND), SlimefunItems.BLANK_RUNE, new ItemStack(Material.SAND), new ItemStack(Material.WATER_BUCKET), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.COD)}, - new CustomItem(SlimefunItems.WATER_RUNE, 4)) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.ENDER_RUNE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.ENDER_PEARL), new ItemStack(Material.ENDER_EYE), SlimefunItems.BLANK_RUNE, new ItemStack(Material.ENDER_EYE), new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.ENDER_PEARL)}, - new CustomItem(SlimefunItems.ENDER_RUNE, 6)) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.LIGHTNING_RUNE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.IRON_INGOT), SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.IRON_INGOT), SlimefunItems.AIR_RUNE, new ItemStack(Material.PHANTOM_MEMBRANE), SlimefunItems.WATER_RUNE, new ItemStack(Material.IRON_INGOT), SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.IRON_INGOT)}, - new CustomItem(SlimefunItems.LIGHTNING_RUNE, 4)) - .register(plugin); - - new SlimefunItem(categories.magicalResources, SlimefunItems.RAINBOW_RUNE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.CYAN_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.ENDER_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(YELLOW_DYE), SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.MAGENTA_DYE)}) - .register(plugin); - - new SoulboundRune(categories.magicalResources, SlimefunItems.SOULBOUND_RUNE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ENDER_LUMP_3, SlimefunItems.ENDER_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.MAGIC_LUMP_3}) - .register(plugin); - - new EnchantmentRune(categories.magicalResources, SlimefunItems.ENCHANTMENT_RUNE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.LIGHTNING_RUNE, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3}) - .register(plugin); - - new InfernalBonemeal(categories.magicalGadgets, SlimefunItems.INFERNAL_BONEMEAL, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.NETHER_WART), SlimefunItems.EARTH_RUNE, new ItemStack(Material.NETHER_WART), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.BONE_MEAL), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.NETHER_WART), new ItemStack(Material.BLAZE_POWDER), new ItemStack(Material.NETHER_WART)}, - new CustomItem(SlimefunItems.INFERNAL_BONEMEAL, 8)) - .register(plugin); - - new SlimefunItem(categories.magicalGadgets, SlimefunItems.ELYTRA_SCALE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {SlimefunItems.ENDER_LUMP_3, SlimefunItems.AIR_RUNE, SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.PHANTOM_MEMBRANE), new ItemStack(Material.FEATHER), new ItemStack(Material.PHANTOM_MEMBRANE), SlimefunItems.ENDER_LUMP_3, SlimefunItems.AIR_RUNE, SlimefunItems.ENDER_LUMP_3}) - .register(plugin); - - new VanillaItem(categories.magicalGadgets, new ItemStack(Material.ELYTRA), "ELYTRA", RecipeType.ANCIENT_ALTAR, - new ItemStack[] {SlimefunItems.ELYTRA_SCALE, SlimefunItems.AIR_RUNE, SlimefunItems.ELYTRA_SCALE, SlimefunItems.AIR_RUNE, new ItemStack(Material.LEATHER_CHESTPLATE), SlimefunItems.AIR_RUNE, SlimefunItems.ELYTRA_SCALE, SlimefunItems.AIR_RUNE, SlimefunItems.ELYTRA_SCALE}) - .register(plugin); - - new SlimefunItem(categories.magicalGadgets, SlimefunItems.INFUSED_ELYTRA, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ELYTRA_SCALE, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.FLASK_OF_KNOWLEDGE, new ItemStack(Material.ELYTRA), SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ELYTRA_SCALE, SlimefunItems.FLASK_OF_KNOWLEDGE}) - .register(plugin); - - new SoulboundItem(categories.magicalGadgets, SlimefunItems.SOULBOUND_ELYTRA, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ELYTRA_SCALE, new ItemStack(Material.ELYTRA), SlimefunItems.ELYTRA_SCALE, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.FLASK_OF_KNOWLEDGE}) - .register(plugin); - - new VanillaItem(categories.magicalGadgets, new ItemStack(Material.TOTEM_OF_UNDYING), "TOTEM_OF_UNDYING", RecipeType.ANCIENT_ALTAR, - new ItemStack[] {SlimefunItems.ESSENCE_OF_AFTERLIFE, new ItemStack(Material.EMERALD_BLOCK), SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.COMMON_TALISMAN, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ESSENCE_OF_AFTERLIFE, new ItemStack(Material.EMERALD_BLOCK), SlimefunItems.ESSENCE_OF_AFTERLIFE}) - .register(plugin); - - new RainbowBlock(categories.magicalGadgets, SlimefunItems.RAINBOW_WOOL, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL)}, - new CustomItem(SlimefunItems.RAINBOW_WOOL, 8), new RainbowTickHandler(MaterialCollections.getAllWoolColors())) - .register(plugin); - - new RainbowBlock(categories.magicalGadgets, SlimefunItems.RAINBOW_GLASS, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS)}, - new CustomItem(SlimefunItems.RAINBOW_GLASS, 8), new RainbowTickHandler(MaterialCollections.getAllStainedGlassColors())) - .register(plugin); - - new RainbowBlock(categories.magicalGadgets, SlimefunItems.RAINBOW_GLASS_PANE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE)}, - new CustomItem(SlimefunItems.RAINBOW_GLASS_PANE, 8), new RainbowTickHandler(MaterialCollections.getAllStainedGlassPaneColors())) - .register(plugin); - - new RainbowBlock(categories.magicalGadgets, SlimefunItems.RAINBOW_CLAY, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA)}, - new CustomItem(SlimefunItems.RAINBOW_CLAY, 8), new RainbowTickHandler(MaterialCollections.getAllTerracottaColors())) - .register(plugin); - - new RainbowBlock(categories.magicalGadgets, SlimefunItems.RAINBOW_CONCRETE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE)}, - new CustomItem(SlimefunItems.RAINBOW_CONCRETE, 8), new RainbowTickHandler(MaterialCollections.getAllConcreteColors())) - .register(plugin); - - new RainbowBlock(categories.magicalGadgets, SlimefunItems.RAINBOW_GLAZED_TERRACOTTA, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA)}, - new CustomItem(SlimefunItems.RAINBOW_GLAZED_TERRACOTTA, 8), new RainbowTickHandler(MaterialCollections.getAllGlazedTerracottaColors())) - .register(plugin); - - // Christmas - - new RainbowBlock(categories.christmas, SlimefunItems.RAINBOW_WOOL_XMAS, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(GREEN_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(RED_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_WOOL_XMAS, 2), new RainbowTickHandler(Material.RED_WOOL, Material.GREEN_WOOL)) - .register(plugin); - - new RainbowBlock(categories.christmas, SlimefunItems.RAINBOW_GLASS_XMAS, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(GREEN_DYE), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(RED_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_GLASS_XMAS, 2), new RainbowTickHandler(Material.RED_STAINED_GLASS, Material.GREEN_STAINED_GLASS)) - .register(plugin); - - new RainbowBlock(categories.christmas, SlimefunItems.RAINBOW_GLASS_PANE_XMAS, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(GREEN_DYE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(RED_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_GLASS_PANE_XMAS, 2), new RainbowTickHandler(Material.RED_STAINED_GLASS_PANE, Material.GREEN_STAINED_GLASS_PANE)) - .register(plugin); - - new RainbowBlock(categories.christmas, SlimefunItems.RAINBOW_CLAY_XMAS, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(GREEN_DYE), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(RED_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_CLAY_XMAS, 2), new RainbowTickHandler(Material.RED_TERRACOTTA, Material.GREEN_TERRACOTTA)) - .register(plugin); - - new RainbowBlock(categories.christmas, SlimefunItems.RAINBOW_CONCRETE_XMAS, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(GREEN_DYE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(RED_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_CONCRETE_XMAS, 2), new RainbowTickHandler(Material.RED_CONCRETE, Material.GREEN_CONCRETE)) - .register(plugin); - - new RainbowBlock(categories.christmas, SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_XMAS, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(GREEN_DYE), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(RED_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_XMAS, 2), new RainbowTickHandler(Material.RED_GLAZED_TERRACOTTA, Material.GREEN_GLAZED_TERRACOTTA)) - .register(plugin); - - // Valentines Day - - new RainbowBlock(categories.valentinesDay, SlimefunItems.RAINBOW_WOOL_VALENTINE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(RED_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_WOOL_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_WOOL, Material.PINK_WOOL)) - .register(plugin); - - new RainbowBlock(categories.valentinesDay, SlimefunItems.RAINBOW_GLASS_VALENTINE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(RED_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_GLASS_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_STAINED_GLASS, Material.PINK_STAINED_GLASS)) - .register(plugin); - - new RainbowBlock(categories.valentinesDay, SlimefunItems.RAINBOW_GLASS_PANE_VALENTINE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(RED_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_GLASS_PANE_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_STAINED_GLASS_PANE, Material.PINK_STAINED_GLASS_PANE)) - .register(plugin); - - new RainbowBlock(categories.valentinesDay, SlimefunItems.RAINBOW_CLAY_VALENTINE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(RED_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_CLAY_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_TERRACOTTA, Material.PINK_TERRACOTTA)) - .register(plugin); - - new RainbowBlock(categories.valentinesDay, SlimefunItems.RAINBOW_CONCRETE_VALENTINE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(RED_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_CONCRETE_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_CONCRETE, Material.PINK_CONCRETE)) - .register(plugin); - - new RainbowBlock(categories.valentinesDay, SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_VALENTINE, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(RED_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_GLAZED_TERRACOTTA, Material.PINK_GLAZED_TERRACOTTA)) - .register(plugin); - - // Halloween - - new RainbowBlock(categories.halloween, SlimefunItems.RAINBOW_WOOL_HALLOWEEN, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(BLACK_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_WOOL_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_WOOL, Material.BLACK_WOOL)) - .register(plugin); - - new RainbowBlock(categories.halloween, SlimefunItems.RAINBOW_GLASS_HALLOWEEN, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(BLACK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_GLASS_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_STAINED_GLASS, Material.BLACK_STAINED_GLASS)) - .register(plugin); - - new RainbowBlock(categories.halloween, SlimefunItems.RAINBOW_GLASS_PANE_HALLOWEEN, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(BLACK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_GLASS_PANE_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_STAINED_GLASS_PANE, Material.BLACK_STAINED_GLASS_PANE)) - .register(plugin); - - new RainbowBlock(categories.halloween, SlimefunItems.RAINBOW_CLAY_HALLOWEEN, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(BLACK_DYE), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_CLAY_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_TERRACOTTA, Material.BLACK_TERRACOTTA)) - .register(plugin); - - new RainbowBlock(categories.halloween, SlimefunItems.RAINBOW_CONCRETE_HALLOWEEN, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(BLACK_DYE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_CONCRETE_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_CONCRETE, Material.BLACK_CONCRETE)) - .register(plugin); - - new RainbowBlock(categories.halloween, SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_HALLOWEEN, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(BLACK_DYE), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)}, - new CustomItem(SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_GLAZED_TERRACOTTA, Material.BLACK_GLAZED_TERRACOTTA)) - .register(plugin); - - new WitherProofBlock(categories.technicalComponents, SlimefunItems.WITHER_PROOF_GLASS, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.LEAD_INGOT, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.LEAD_INGOT, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.HARDENED_GLASS, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.LEAD_INGOT, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.LEAD_INGOT}, - new CustomItem(SlimefunItems.WITHER_PROOF_GLASS, 4)) - .register(plugin); - - new GEOScanner(categories.gps, SlimefunItems.GPS_GEO_SCANNER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, null, SlimefunItems.ELECTRO_MAGNET, null, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_INGOT, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ELECTRO_MAGNET}) - .register(plugin); - - new PortableGEOScanner(categories.gps, SlimefunItems.PORTABLE_GEO_SCANNER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.ELECTRO_MAGNET, new ItemStack(Material.COMPASS), SlimefunItems.ELECTRO_MAGNET, SlimefunItems.STEEL_INGOT, SlimefunItems.GPS_MARKER_TOOL, SlimefunItems.STEEL_INGOT, SlimefunItems.SOLDER_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.SOLDER_INGOT}) - .register(plugin); - - new OilPump(categories.gps, SlimefunItems.OIL_PUMP, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.STEEL_INGOT, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.STEEL_INGOT, null, new ItemStack(Material.BUCKET), null}) { - - @Override - public int getEnergyConsumption() { - return 14; - } - - @Override - public int getCapacity() { - return 256; - } - - @Override - public int getSpeed() { - return 1; - } - - }.register(plugin); - - new GEOMiner(categories.gps, SlimefunItems.GEO_MINER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.DIAMOND_PICKAXE), SlimefunItems.MEDIUM_CAPACITOR, new ItemStack(Material.DIAMOND_PICKAXE), SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.OIL_PUMP, SlimefunItems.REINFORCED_ALLOY_INGOT, null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public int getSpeed() { - return 1; - } - - @Override - public int getCapacity() { - return 512; - } - - @Override - public int getEnergyConsumption() { - return 24; - } - - }.register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.OIL_BUCKET, new RecipeType(new NamespacedKey(plugin, "oil_pump"), SlimefunItems.OIL_PUMP), - new ItemStack[] {null, null, null, null, new ItemStack(Material.BUCKET), null, null, null, null}) - .register(plugin); - - new SlimefunItem(categories.resources, SlimefunItems.FUEL_BUCKET, RecipeType.REFINERY, - new ItemStack[] {null, null, null, null, SlimefunItems.OIL_BUCKET, null, null, null, null}) - .register(plugin); - - new RadioactiveItem(categories.resources, Radioactivity.MODERATE, SlimefunItems.NETHER_ICE, RecipeType.GEO_MINER, - new ItemStack[] {null, null, null, null, null, null, null, null, null}) - .register(plugin); - - new Refinery(categories.electricity, SlimefunItems.REFINERY, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.HARDENED_GLASS, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.HARDENED_GLASS, SlimefunItems.HARDENED_GLASS, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.HARDENED_GLASS, new ItemStack(Material.PISTON), SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.PISTON)}) { - - @Override - public int getEnergyConsumption() { - return 16; - } - - @Override - public int getCapacity() { - return 256; - } - - @Override - public int getSpeed() { - return 1; - } - - }.register(plugin); - - new LavaGenerator(categories.electricity, SlimefunItems.LAVA_GENERATOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.GOLD_16K, null, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.HEATING_COIL}) { - - @Override - public int getEnergyProduction() { - return 10; - } - - @Override - public int getCapacity() { - return 512; - } - - }.register(plugin); - - new LavaGenerator(categories.electricity, SlimefunItems.LAVA_GENERATOR_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.LAVA_GENERATOR, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.HEATING_COIL, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.HEATING_COIL}) { - - @Override - public int getEnergyProduction() { - return 20; - } - - @Override - public int getCapacity() { - return 1024; - } - - }.register(plugin); - - new CombustionGenerator(categories.electricity, SlimefunItems.COMBUSTION_REACTOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.STEEL_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.STEEL_INGOT, SlimefunItems.HEATING_COIL}) { - - @Override - public int getEnergyProduction() { - return 12; - } - - @Override - public int getCapacity() { - return 256; - } - - }.register(plugin); - - new TeleporterPylon(categories.gps, SlimefunItems.GPS_TELEPORTER_PYLON, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.ZINC_INGOT, new ItemStack(Material.GLASS), SlimefunItems.ZINC_INGOT, new ItemStack(Material.GLASS), SlimefunItems.HEATING_COIL, new ItemStack(Material.GLASS), SlimefunItems.ZINC_INGOT, new ItemStack(Material.GLASS), SlimefunItems.ZINC_INGOT}, - new CustomItem(SlimefunItems.GPS_TELEPORTER_PYLON, 8)) - .register(plugin); - - new Teleporter(categories.gps, SlimefunItems.GPS_TELEPORTATION_MATRIX, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.GPS_TELEPORTER_PYLON, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.GPS_TELEPORTER_PYLON, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.GPS_CONTROL_PANEL, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.GPS_TELEPORTER_PYLON, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.GPS_TELEPORTER_PYLON}) - .register(plugin); - - new SlimefunItem(categories.gps, SlimefunItems.GPS_ACTIVATION_DEVICE_SHARED, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.STONE_PRESSURE_PLATE), null, new ItemStack(Material.REDSTONE), SlimefunItems.GPS_TRANSMITTER, new ItemStack(Material.REDSTONE), SlimefunItems.BILLON_INGOT, SlimefunItems.BILLON_INGOT, SlimefunItems.BILLON_INGOT}) - .register(plugin); - - new PersonalActivationPlate(categories.gps, SlimefunItems.GPS_ACTIVATION_DEVICE_PERSONAL, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.LEAD_INGOT, null, SlimefunItems.COBALT_INGOT, SlimefunItems.GPS_ACTIVATION_DEVICE_SHARED, SlimefunItems.COBALT_INGOT, null, SlimefunItems.LEAD_INGOT, null}) - .register(plugin); - - new InfusedHopper(categories.magicalGadgets, SlimefunItems.INFUSED_HOPPER, RecipeType.ANCIENT_ALTAR, - new ItemStack[] {new ItemStack(Material.OBSIDIAN), SlimefunItems.EARTH_RUNE, new ItemStack(Material.HOPPER), SlimefunItems.ENDER_RUNE, SlimefunItems.INFUSED_MAGNET, SlimefunItems.ENDER_RUNE, new ItemStack(Material.HOPPER), SlimefunItems.EARTH_RUNE, new ItemStack(Material.OBSIDIAN)}) - .register(plugin); - - new RadioactiveItem(categories.resources, Radioactivity.HIGH, SlimefunItems.BLISTERING_INGOT, RecipeType.HEATED_PRESSURE_CHAMBER, - new ItemStack[] {SlimefunItems.GOLD_24K, SlimefunItems.URANIUM, null, null, null, null, null, null, null}) - .register(plugin); - - new RadioactiveItem(categories.resources, Radioactivity.VERY_HIGH, SlimefunItems.BLISTERING_INGOT_2, RecipeType.HEATED_PRESSURE_CHAMBER, - new ItemStack[] {SlimefunItems.BLISTERING_INGOT, SlimefunItems.CARBONADO, null, null, null, null, null, null, null}) - .register(plugin); - - new RadioactiveItem(categories.resources, Radioactivity.VERY_HIGH, SlimefunItems.BLISTERING_INGOT_3, RecipeType.HEATED_PRESSURE_CHAMBER, - new ItemStack[] {SlimefunItems.BLISTERING_INGOT_2, new ItemStack(Material.NETHER_STAR), null, null, null, null, null, null, null}) - .register(plugin); - - new RadioactiveItem(categories.resources, Radioactivity.VERY_HIGH, SlimefunItems.ENRICHED_NETHER_ICE, RecipeType.HEATED_PRESSURE_CHAMBER, - new ItemStack[] {SlimefunItems.NETHER_ICE, SlimefunItems.PLUTONIUM, null, null, null, null, null, null, null}) - .register(plugin); - - new ElevatorPlate(categories.gps, SlimefunItems.ELEVATOR_PLATE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.STONE_PRESSURE_PLATE), null, new ItemStack(Material.PISTON), SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.PISTON), SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.ALUMINUM_BRONZE_INGOT}, - new CustomItem(SlimefunItems.ELEVATOR_PLATE, 2)) - .register(plugin); - - new FoodFabricator(categories.electricity, SlimefunItems.FOOD_FABRICATOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.BILLON_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.BILLON_INGOT, SlimefunItems.TIN_CAN, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.TIN_CAN, null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public int getEnergyConsumption() { - return 7; - } - - @Override - public int getCapacity() { - return 256; - } - - @Override - public int getSpeed() { - return 1; - } - - }.register(plugin); - - new FoodFabricator(categories.electricity, SlimefunItems.FOOD_FABRICATOR_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.FOOD_FABRICATOR, SlimefunItems.ELECTRIC_MOTOR, null, SlimefunItems.ELECTRO_MAGNET, null}) { - - @Override - public int getEnergyConsumption() { - return 24; - } - - @Override - public int getCapacity() { - return 512; - } - - @Override - public int getSpeed() { - return 6; - } + @Override + public float getFuelEfficiency() { + return 1; + } + + @Override + public int getTier() { + return 1; + } - }.register(plugin); + } + .register(plugin); - new OrganicFood(categories.misc, SlimefunItems.WHEAT_ORGANIC_FOOD, Material.WHEAT) - .register(plugin); + new MinerAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_MINER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, null, new ItemStack(Material.DIAMOND_PICKAXE), SlimefunItems.PROGRAMMABLE_ANDROID, new ItemStack(Material.DIAMOND_PICKAXE), null, SlimefunItems.ELECTRIC_MOTOR, null}) { - new OrganicFood(categories.misc, SlimefunItems.CARROT_ORGANIC_FOOD, Material.CARROT) - .register(plugin); + @Override + public float getFuelEfficiency() { + return 1; + } + + @Override + public int getTier() { + return 1; + } - new OrganicFood(categories.misc, SlimefunItems.POTATO_ORGANIC_FOOD, Material.POTATO) - .register(plugin); + } + .register(plugin); - new OrganicFood(categories.misc, SlimefunItems.SEEDS_ORGANIC_FOOD, Material.WHEAT_SEEDS) - .register(plugin); + new FarmerAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_FARMER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, null, new ItemStack(Material.DIAMOND_HOE), SlimefunItems.PROGRAMMABLE_ANDROID, new ItemStack(Material.DIAMOND_HOE), null, SlimefunItems.ELECTRIC_MOTOR, null}) { - new OrganicFood(categories.misc, SlimefunItems.BEETROOT_ORGANIC_FOOD, Material.BEETROOT) - .register(plugin); + @Override + public float getFuelEfficiency() { + return 1; + } + + @Override + public int getTier() { + return 1; + } - new OrganicFood(categories.misc, SlimefunItems.MELON_ORGANIC_FOOD, Material.MELON_SLICE) - .register(plugin); + } + .register(plugin); - new OrganicFood(categories.misc, SlimefunItems.APPLE_ORGANIC_FOOD, Material.APPLE) - .register(plugin); + new WoodcutterAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_WOODCUTTER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, null, new ItemStack(Material.DIAMOND_AXE), SlimefunItems.PROGRAMMABLE_ANDROID, new ItemStack(Material.DIAMOND_AXE), null, SlimefunItems.ELECTRIC_MOTOR, null}) { - if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { - new OrganicFood(categories.misc, SlimefunItems.SWEET_BERRIES_ORGANIC_FOOD, Material.SWEET_BERRIES) - .register(plugin); - } + @Override + public float getFuelEfficiency() { + return 1; + } + + @Override + public int getTier() { + return 1; + } - new OrganicFood(categories.misc, SlimefunItems.KELP_ORGANIC_FOOD, Material.DRIED_KELP) - .register(plugin); + } + .register(plugin); + + new FisherAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_FISHERMAN, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, null, new ItemStack(Material.FISHING_ROD), SlimefunItems.PROGRAMMABLE_ANDROID, new ItemStack(Material.FISHING_ROD), null, SlimefunItems.ELECTRIC_MOTOR, null}) { + + @Override + public float getFuelEfficiency() { + return 1; + } + + @Override + public int getTier() { + return 1; + } + + } + .register(plugin); + + new ButcherAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_BUTCHER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.GPS_TRANSMITTER, null, new ItemStack(Material.DIAMOND_SWORD), SlimefunItems.PROGRAMMABLE_ANDROID, new ItemStack(Material.DIAMOND_SWORD), null, SlimefunItems.ELECTRIC_MOTOR, null}) { + + @Override + public float getFuelEfficiency() { + return 1; + } + + @Override + public int getTier() { + return 1; + } + + } + .register(plugin); + + new ProgrammableAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.PLASTIC_SHEET, SlimefunItems.ANDROID_MEMORY_CORE, SlimefunItems.PLASTIC_SHEET, SlimefunItems.COMBUSTION_REACTOR, SlimefunItems.PROGRAMMABLE_ANDROID, new ItemStack(Material.CHEST), SlimefunItems.PLASTIC_SHEET, SlimefunItems.POWER_CRYSTAL, SlimefunItems.PLASTIC_SHEET}) { + + @Override + public float getFuelEfficiency() { + return 1.5F; + } + + @Override + public int getTier() { + return 2; + } + + } + .register(plugin); + + new FisherAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_2_FISHERMAN, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, null, new ItemStack(Material.FISHING_ROD), SlimefunItems.PROGRAMMABLE_ANDROID_2, new ItemStack(Material.FISHING_ROD), null, SlimefunItems.ELECTRIC_MOTOR, null}) { + + @Override + public float getFuelEfficiency() { + return 1.5F; + } + + @Override + public int getTier() { + return 2; + } + + } + .register(plugin); + + new ButcherAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_2_BUTCHER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.GPS_TRANSMITTER, null, new ItemStack(Material.DIAMOND_SWORD), SlimefunItems.PROGRAMMABLE_ANDROID_2, new ItemStack(Material.DIAMOND_SWORD), null, SlimefunItems.ELECTRIC_MOTOR, null}) { + + @Override + public float getFuelEfficiency() { + return 1.5F; + } + + @Override + public int getTier() { + return 2; + } + + } + .register(plugin); + + new AdvancedFarmerAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_2_FARMER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.GPS_TRANSMITTER, null, new ItemStack(Material.DIAMOND_HOE), SlimefunItems.PROGRAMMABLE_ANDROID_2, new ItemStack(Material.DIAMOND_HOE), null, SlimefunItems.ELECTRIC_MOTOR, null}) { + + @Override + public float getFuelEfficiency() { + return 1.5F; + } + + @Override + public int getTier() { + return 2; + } + + } + .register(plugin); + + new ProgrammableAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_3, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.PLASTIC_SHEET, SlimefunItems.ANDROID_MEMORY_CORE, SlimefunItems.PLASTIC_SHEET, SlimefunItems.NUCLEAR_REACTOR, SlimefunItems.PROGRAMMABLE_ANDROID_2, new ItemStack(Material.CHEST), SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.POWER_CRYSTAL, SlimefunItems.BLISTERING_INGOT_3}) { + + @Override + public float getFuelEfficiency() { + return 1F; + } + + @Override + public int getTier() { + return 3; + } + + } + .register(plugin); + + new FisherAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_3_FISHERMAN, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, null, new ItemStack(Material.FISHING_ROD), SlimefunItems.PROGRAMMABLE_ANDROID_3, new ItemStack(Material.FISHING_ROD), null, SlimefunItems.ELECTRIC_MOTOR, null}) { + + @Override + public float getFuelEfficiency() { + return 1F; + } + + @Override + public int getTier() { + return 3; + } + + } + .register(plugin); + + new ButcherAndroid(categories.androids, SlimefunItems.PROGRAMMABLE_ANDROID_3_BUTCHER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.GPS_TRANSMITTER_3, null, new ItemStack(Material.DIAMOND_SWORD), SlimefunItems.PROGRAMMABLE_ANDROID_3, new ItemStack(Material.DIAMOND_SWORD), null, SlimefunItems.ELECTRIC_MOTOR, null}) { + + @Override + public float getFuelEfficiency() { + return 1F; + } + + @Override + public int getTier() { + return 3; + } + + } + .register(plugin); + + new SlimefunItem(categories.magicalResources, SlimefunItems.BLANK_RUNE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.STONE), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.STONE), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.OBSIDIAN), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.STONE), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.STONE)}) + .register(plugin); + + new SlimefunItem(categories.magicalResources, SlimefunItems.AIR_RUNE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.FEATHER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.FEATHER), new ItemStack(Material.GHAST_TEAR), SlimefunItems.BLANK_RUNE, new ItemStack(Material.GHAST_TEAR), new ItemStack(Material.FEATHER), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.FEATHER)}, + new SlimefunItemStack(SlimefunItems.AIR_RUNE, 4)) + .register(plugin); + + new SlimefunItem(categories.magicalResources, SlimefunItems.EARTH_RUNE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.DIRT), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.STONE), new ItemStack(Material.OBSIDIAN), SlimefunItems.BLANK_RUNE, new ItemStack(Material.OBSIDIAN), new ItemStack(Material.STONE), SlimefunItems.MAGIC_LUMP_1, new ItemStack(Material.DIRT)}, + new SlimefunItemStack(SlimefunItems.EARTH_RUNE, 4)) + .register(plugin); + + new SlimefunItem(categories.magicalResources, SlimefunItems.FIRE_RUNE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.FIRE_CHARGE), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.FIRE_CHARGE), new ItemStack(Material.BLAZE_POWDER), SlimefunItems.EARTH_RUNE, new ItemStack(Material.FLINT_AND_STEEL), new ItemStack(Material.FIRE_CHARGE), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.FIRE_CHARGE)}, + new SlimefunItemStack(SlimefunItems.FIRE_RUNE, 4)) + .register(plugin); + + new SlimefunItem(categories.magicalResources, SlimefunItems.WATER_RUNE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.SALMON), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.WATER_BUCKET), new ItemStack(Material.SAND), SlimefunItems.BLANK_RUNE, new ItemStack(Material.SAND), new ItemStack(Material.WATER_BUCKET), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.COD)}, + new SlimefunItemStack(SlimefunItems.WATER_RUNE, 4)) + .register(plugin); + + new SlimefunItem(categories.magicalResources, SlimefunItems.ENDER_RUNE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.ENDER_PEARL), new ItemStack(Material.ENDER_EYE), SlimefunItems.BLANK_RUNE, new ItemStack(Material.ENDER_EYE), new ItemStack(Material.ENDER_PEARL), SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.ENDER_PEARL)}, + new SlimefunItemStack(SlimefunItems.ENDER_RUNE, 6)) + .register(plugin); + + new SlimefunItem(categories.magicalResources, SlimefunItems.LIGHTNING_RUNE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.IRON_INGOT), SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.IRON_INGOT), SlimefunItems.AIR_RUNE, new ItemStack(Material.PHANTOM_MEMBRANE), SlimefunItems.WATER_RUNE, new ItemStack(Material.IRON_INGOT), SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.IRON_INGOT)}, + new SlimefunItemStack(SlimefunItems.LIGHTNING_RUNE, 4)) + .register(plugin); + + new SlimefunItem(categories.magicalResources, SlimefunItems.RAINBOW_RUNE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.CYAN_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.ENDER_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(YELLOW_DYE), SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.MAGENTA_DYE)}) + .register(plugin); + + new SoulboundRune(categories.magicalResources, SlimefunItems.SOULBOUND_RUNE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ENDER_LUMP_3, SlimefunItems.ENDER_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.MAGIC_LUMP_3}) + .register(plugin); + + new EnchantmentRune(categories.magicalResources, SlimefunItems.ENCHANTMENT_RUNE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.LIGHTNING_RUNE, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3}) + .register(plugin); + + new InfernalBonemeal(categories.magicalGadgets, SlimefunItems.INFERNAL_BONEMEAL, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.NETHER_WART), SlimefunItems.EARTH_RUNE, new ItemStack(Material.NETHER_WART), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.BONE_MEAL), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.NETHER_WART), new ItemStack(Material.BLAZE_POWDER), new ItemStack(Material.NETHER_WART)}, + new SlimefunItemStack(SlimefunItems.INFERNAL_BONEMEAL, 8)) + .register(plugin); + + new SlimefunItem(categories.magicalGadgets, SlimefunItems.ELYTRA_SCALE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {SlimefunItems.ENDER_LUMP_3, SlimefunItems.AIR_RUNE, SlimefunItems.ENDER_LUMP_3, new ItemStack(Material.PHANTOM_MEMBRANE), new ItemStack(Material.FEATHER), new ItemStack(Material.PHANTOM_MEMBRANE), SlimefunItems.ENDER_LUMP_3, SlimefunItems.AIR_RUNE, SlimefunItems.ENDER_LUMP_3}) + .register(plugin); + + new VanillaItem(categories.magicalGadgets, new ItemStack(Material.ELYTRA), "ELYTRA", RecipeType.ANCIENT_ALTAR, + new ItemStack[] {SlimefunItems.ELYTRA_SCALE, SlimefunItems.AIR_RUNE, SlimefunItems.ELYTRA_SCALE, SlimefunItems.AIR_RUNE, new ItemStack(Material.LEATHER_CHESTPLATE), SlimefunItems.AIR_RUNE, SlimefunItems.ELYTRA_SCALE, SlimefunItems.AIR_RUNE, SlimefunItems.ELYTRA_SCALE}) + .register(plugin); + + new SlimefunItem(categories.magicalGadgets, SlimefunItems.INFUSED_ELYTRA, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ELYTRA_SCALE, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.FLASK_OF_KNOWLEDGE, new ItemStack(Material.ELYTRA), SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ELYTRA_SCALE, SlimefunItems.FLASK_OF_KNOWLEDGE}) + .register(plugin); + + new SoulboundItem(categories.magicalGadgets, SlimefunItems.SOULBOUND_ELYTRA, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ELYTRA_SCALE, new ItemStack(Material.ELYTRA), SlimefunItems.ELYTRA_SCALE, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.FLASK_OF_KNOWLEDGE}) + .register(plugin); + + new VanillaItem(categories.magicalGadgets, new ItemStack(Material.TOTEM_OF_UNDYING), "TOTEM_OF_UNDYING", RecipeType.ANCIENT_ALTAR, + new ItemStack[] {SlimefunItems.ESSENCE_OF_AFTERLIFE, new ItemStack(Material.EMERALD_BLOCK), SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.COMMON_TALISMAN, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ESSENCE_OF_AFTERLIFE, new ItemStack(Material.EMERALD_BLOCK), SlimefunItems.ESSENCE_OF_AFTERLIFE}) + .register(plugin); + + new RainbowBlock(categories.magicalGadgets, SlimefunItems.RAINBOW_WOOL, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.WHITE_WOOL)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_WOOL, 8), new RainbowTickHandler(MaterialCollections.getAllWoolColors())) + .register(plugin); + + new RainbowBlock(categories.magicalGadgets, SlimefunItems.RAINBOW_GLASS, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.WHITE_STAINED_GLASS)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS, 8), new RainbowTickHandler(MaterialCollections.getAllStainedGlassColors())) + .register(plugin); + + new RainbowBlock(categories.magicalGadgets, SlimefunItems.RAINBOW_GLASS_PANE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_PANE, 8), new RainbowTickHandler(MaterialCollections.getAllStainedGlassPaneColors())) + .register(plugin); + + new RainbowBlock(categories.magicalGadgets, SlimefunItems.RAINBOW_CLAY, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_CLAY, 8), new RainbowTickHandler(MaterialCollections.getAllTerracottaColors())) + .register(plugin); + + new RainbowBlock(categories.magicalGadgets, SlimefunItems.RAINBOW_CONCRETE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_CONCRETE, 8), new RainbowTickHandler(MaterialCollections.getAllConcreteColors())) + .register(plugin); + + new RainbowBlock(categories.magicalGadgets, SlimefunItems.RAINBOW_GLAZED_TERRACOTTA, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_GLAZED_TERRACOTTA, 8), new RainbowTickHandler(MaterialCollections.getAllGlazedTerracottaColors())) + .register(plugin); + + // Christmas + + new RainbowBlock(categories.christmas, SlimefunItems.RAINBOW_WOOL_XMAS, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(GREEN_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(RED_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_WOOL_XMAS, 2), new RainbowTickHandler(Material.RED_WOOL, Material.GREEN_WOOL)) + .register(plugin); + + new RainbowBlock(categories.christmas, SlimefunItems.RAINBOW_GLASS_XMAS, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(GREEN_DYE), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(RED_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_XMAS, 2), new RainbowTickHandler(Material.RED_STAINED_GLASS, Material.GREEN_STAINED_GLASS)) + .register(plugin); + + new RainbowBlock(categories.christmas, SlimefunItems.RAINBOW_GLASS_PANE_XMAS, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(GREEN_DYE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(RED_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_PANE_XMAS, 2), new RainbowTickHandler(Material.RED_STAINED_GLASS_PANE, Material.GREEN_STAINED_GLASS_PANE)) + .register(plugin); + + new RainbowBlock(categories.christmas, SlimefunItems.RAINBOW_CLAY_XMAS, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(GREEN_DYE), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(RED_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_CLAY_XMAS, 2), new RainbowTickHandler(Material.RED_TERRACOTTA, Material.GREEN_TERRACOTTA)) + .register(plugin); + + new RainbowBlock(categories.christmas, SlimefunItems.RAINBOW_CONCRETE_XMAS, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(GREEN_DYE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(RED_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_CONCRETE_XMAS, 2), new RainbowTickHandler(Material.RED_CONCRETE, Material.GREEN_CONCRETE)) + .register(plugin); + + new RainbowBlock(categories.christmas, SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_XMAS, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(RED_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(GREEN_DYE), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(GREEN_DYE), SlimefunItems.CHRISTMAS_COOKIE, new ItemStack(RED_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_XMAS, 2), new RainbowTickHandler(Material.RED_GLAZED_TERRACOTTA, Material.GREEN_GLAZED_TERRACOTTA)) + .register(plugin); + + // Valentines Day + + new RainbowBlock(categories.valentinesDay, SlimefunItems.RAINBOW_WOOL_VALENTINE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(RED_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_WOOL_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_WOOL, Material.PINK_WOOL)) + .register(plugin); + + new RainbowBlock(categories.valentinesDay, SlimefunItems.RAINBOW_GLASS_VALENTINE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(RED_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_STAINED_GLASS, Material.PINK_STAINED_GLASS)) + .register(plugin); + + new RainbowBlock(categories.valentinesDay, SlimefunItems.RAINBOW_GLASS_PANE_VALENTINE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(RED_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_PANE_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_STAINED_GLASS_PANE, Material.PINK_STAINED_GLASS_PANE)) + .register(plugin); + + new RainbowBlock(categories.valentinesDay, SlimefunItems.RAINBOW_CLAY_VALENTINE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(RED_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_CLAY_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_TERRACOTTA, Material.PINK_TERRACOTTA)) + .register(plugin); + + new RainbowBlock(categories.valentinesDay, SlimefunItems.RAINBOW_CONCRETE_VALENTINE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(RED_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_CONCRETE_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_CONCRETE, Material.PINK_CONCRETE)) + .register(plugin); + + new RainbowBlock(categories.valentinesDay, SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_VALENTINE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(RED_DYE), new ItemStack(Material.POPPY), new ItemStack(Material.PINK_DYE), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(Material.PINK_DYE), new ItemStack(Material.POPPY), new ItemStack(RED_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_VALENTINE, 2), new RainbowTickHandler(Material.MAGENTA_GLAZED_TERRACOTTA, Material.PINK_GLAZED_TERRACOTTA)) + .register(plugin); + + // Halloween + + new RainbowBlock(categories.halloween, SlimefunItems.RAINBOW_WOOL_HALLOWEEN, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(BLACK_DYE), new ItemStack(Material.WHITE_WOOL), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_WOOL), new ItemStack(BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_WOOL_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_WOOL, Material.BLACK_WOOL)) + .register(plugin); + + new RainbowBlock(categories.halloween, SlimefunItems.RAINBOW_GLASS_HALLOWEEN, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(BLACK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS), new ItemStack(BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_STAINED_GLASS, Material.BLACK_STAINED_GLASS)) + .register(plugin); + + new RainbowBlock(categories.halloween, SlimefunItems.RAINBOW_GLASS_PANE_HALLOWEEN, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(BLACK_DYE), new ItemStack(Material.WHITE_STAINED_GLASS_PANE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_STAINED_GLASS_PANE), new ItemStack(BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_GLASS_PANE_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_STAINED_GLASS_PANE, Material.BLACK_STAINED_GLASS_PANE)) + .register(plugin); + + new RainbowBlock(categories.halloween, SlimefunItems.RAINBOW_CLAY_HALLOWEEN, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(BLACK_DYE), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_CLAY_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_TERRACOTTA, Material.BLACK_TERRACOTTA)) + .register(plugin); + + new RainbowBlock(categories.halloween, SlimefunItems.RAINBOW_CONCRETE_HALLOWEEN, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(BLACK_DYE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_CONCRETE_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_CONCRETE, Material.BLACK_CONCRETE)) + .register(plugin); + + new RainbowBlock(categories.halloween, SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_HALLOWEEN, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.ORANGE_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(BLACK_DYE), new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_GLAZED_TERRACOTTA), new ItemStack(BLACK_DYE), new ItemStack(Material.PUMPKIN), new ItemStack(Material.ORANGE_DYE)}, + new SlimefunItemStack(SlimefunItems.RAINBOW_GLAZED_TERRACOTTA_HALLOWEEN, 2), new RainbowTickHandler(Material.ORANGE_GLAZED_TERRACOTTA, Material.BLACK_GLAZED_TERRACOTTA)) + .register(plugin); + + new WitherProofBlock(categories.technicalComponents, SlimefunItems.WITHER_PROOF_GLASS, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.LEAD_INGOT, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.LEAD_INGOT, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.HARDENED_GLASS, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.LEAD_INGOT, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.LEAD_INGOT}, + new SlimefunItemStack(SlimefunItems.WITHER_PROOF_GLASS, 4)) + .register(plugin); + + new GEOScanner(categories.gps, SlimefunItems.GPS_GEO_SCANNER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, null, SlimefunItems.ELECTRO_MAGNET, null, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_INGOT, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ELECTRO_MAGNET}) + .register(plugin); + + new PortableGEOScanner(categories.gps, SlimefunItems.PORTABLE_GEO_SCANNER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.ELECTRO_MAGNET, new ItemStack(Material.COMPASS), SlimefunItems.ELECTRO_MAGNET, SlimefunItems.STEEL_INGOT, SlimefunItems.GPS_MARKER_TOOL, SlimefunItems.STEEL_INGOT, SlimefunItems.SOLDER_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.SOLDER_INGOT}) + .register(plugin); + + new OilPump(categories.gps, SlimefunItems.OIL_PUMP, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.STEEL_INGOT, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.STEEL_INGOT, SlimefunItems.STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.STEEL_INGOT, null, new ItemStack(Material.BUCKET), null}) { + + @Override + public int getEnergyConsumption() { + return 14; + } + + @Override + public int getCapacity() { + return 256; + } + + @Override + public int getSpeed() { + return 1; + } + + }.register(plugin); + + new GEOMiner(categories.gps, SlimefunItems.GEO_MINER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.DIAMOND_PICKAXE), SlimefunItems.MEDIUM_CAPACITOR, new ItemStack(Material.DIAMOND_PICKAXE), SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.OIL_PUMP, SlimefunItems.REINFORCED_ALLOY_INGOT, null, SlimefunItems.ELECTRIC_MOTOR, null}) { + + @Override + public int getSpeed() { + return 1; + } + + @Override + public int getCapacity() { + return 512; + } + + @Override + public int getEnergyConsumption() { + return 24; + } + + }.register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.OIL_BUCKET, new RecipeType(new NamespacedKey(plugin, "oil_pump"), SlimefunItems.OIL_PUMP), + new ItemStack[] {null, null, null, null, new ItemStack(Material.BUCKET), null, null, null, null}) + .register(plugin); + + new SlimefunItem(categories.resources, SlimefunItems.FUEL_BUCKET, RecipeType.REFINERY, + new ItemStack[] {null, null, null, null, SlimefunItems.OIL_BUCKET, null, null, null, null}) + .register(plugin); + + new RadioactiveItem(categories.resources, Radioactivity.MODERATE, SlimefunItems.NETHER_ICE, RecipeType.GEO_MINER, + new ItemStack[] {null, null, null, null, null, null, null, null, null}) + .register(plugin); + + new Refinery(categories.electricity, SlimefunItems.REFINERY, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.HARDENED_GLASS, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.HARDENED_GLASS, SlimefunItems.HARDENED_GLASS, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.HARDENED_GLASS, new ItemStack(Material.PISTON), SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.PISTON)}) { + + @Override + public int getEnergyConsumption() { + return 16; + } + + @Override + public int getCapacity() { + return 256; + } + + @Override + public int getSpeed() { + return 1; + } + + }.register(plugin); + + new LavaGenerator(categories.electricity, SlimefunItems.LAVA_GENERATOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.GOLD_16K, null, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.HEATING_COIL}) { + + @Override + public int getEnergyProduction() { + return 10; + } + + @Override + public int getCapacity() { + return 512; + } + + }.register(plugin); + + new LavaGenerator(categories.electricity, SlimefunItems.LAVA_GENERATOR_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.LAVA_GENERATOR, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.HEATING_COIL, SlimefunItems.COMPRESSED_CARBON, SlimefunItems.HEATING_COIL}) { + + @Override + public int getEnergyProduction() { + return 20; + } + + @Override + public int getCapacity() { + return 1024; + } + + }.register(plugin); + + new CombustionGenerator(categories.electricity, SlimefunItems.COMBUSTION_REACTOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.STEEL_INGOT, null, SlimefunItems.STEEL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.STEEL_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.STEEL_INGOT, SlimefunItems.HEATING_COIL}) { + + @Override + public int getEnergyProduction() { + return 12; + } + + @Override + public int getCapacity() { + return 256; + } + + }.register(plugin); + + new TeleporterPylon(categories.gps, SlimefunItems.GPS_TELEPORTER_PYLON, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.ZINC_INGOT, new ItemStack(Material.GLASS), SlimefunItems.ZINC_INGOT, new ItemStack(Material.GLASS), SlimefunItems.HEATING_COIL, new ItemStack(Material.GLASS), SlimefunItems.ZINC_INGOT, new ItemStack(Material.GLASS), SlimefunItems.ZINC_INGOT}, + new SlimefunItemStack(SlimefunItems.GPS_TELEPORTER_PYLON, 8)) + .register(plugin); + + new Teleporter(categories.gps, SlimefunItems.GPS_TELEPORTATION_MATRIX, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.GPS_TELEPORTER_PYLON, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.GPS_TELEPORTER_PYLON, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.GPS_CONTROL_PANEL, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.GPS_TELEPORTER_PYLON, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.GPS_TELEPORTER_PYLON}) + .register(plugin); + + new SlimefunItem(categories.gps, SlimefunItems.GPS_ACTIVATION_DEVICE_SHARED, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.STONE_PRESSURE_PLATE), null, new ItemStack(Material.REDSTONE), SlimefunItems.GPS_TRANSMITTER, new ItemStack(Material.REDSTONE), SlimefunItems.BILLON_INGOT, SlimefunItems.BILLON_INGOT, SlimefunItems.BILLON_INGOT}) + .register(plugin); + + new PersonalActivationPlate(categories.gps, SlimefunItems.GPS_ACTIVATION_DEVICE_PERSONAL, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.LEAD_INGOT, null, SlimefunItems.COBALT_INGOT, SlimefunItems.GPS_ACTIVATION_DEVICE_SHARED, SlimefunItems.COBALT_INGOT, null, SlimefunItems.LEAD_INGOT, null}) + .register(plugin); + + new InfusedHopper(categories.magicalGadgets, SlimefunItems.INFUSED_HOPPER, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {new ItemStack(Material.OBSIDIAN), SlimefunItems.EARTH_RUNE, new ItemStack(Material.HOPPER), SlimefunItems.ENDER_RUNE, SlimefunItems.INFUSED_MAGNET, SlimefunItems.ENDER_RUNE, new ItemStack(Material.HOPPER), SlimefunItems.EARTH_RUNE, new ItemStack(Material.OBSIDIAN)}) + .register(plugin); + + new RadioactiveItem(categories.resources, Radioactivity.HIGH, SlimefunItems.BLISTERING_INGOT, RecipeType.HEATED_PRESSURE_CHAMBER, + new ItemStack[] {SlimefunItems.GOLD_24K, SlimefunItems.URANIUM, null, null, null, null, null, null, null}) + .register(plugin); + + new RadioactiveItem(categories.resources, Radioactivity.VERY_HIGH, SlimefunItems.BLISTERING_INGOT_2, RecipeType.HEATED_PRESSURE_CHAMBER, + new ItemStack[] {SlimefunItems.BLISTERING_INGOT, SlimefunItems.CARBONADO, null, null, null, null, null, null, null}) + .register(plugin); + + new RadioactiveItem(categories.resources, Radioactivity.VERY_HIGH, SlimefunItems.BLISTERING_INGOT_3, RecipeType.HEATED_PRESSURE_CHAMBER, + new ItemStack[] {SlimefunItems.BLISTERING_INGOT_2, new ItemStack(Material.NETHER_STAR), null, null, null, null, null, null, null}) + .register(plugin); + + new RadioactiveItem(categories.resources, Radioactivity.VERY_HIGH, SlimefunItems.ENRICHED_NETHER_ICE, RecipeType.HEATED_PRESSURE_CHAMBER, + new ItemStack[] {SlimefunItems.NETHER_ICE, SlimefunItems.PLUTONIUM, null, null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.ENRICHED_NETHER_ICE, 4)) + .register(plugin); + + new ElevatorPlate(categories.gps, SlimefunItems.ELEVATOR_PLATE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.STONE_PRESSURE_PLATE), null, new ItemStack(Material.PISTON), SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.PISTON), SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.ALUMINUM_BRONZE_INGOT}, + new SlimefunItemStack(SlimefunItems.ELEVATOR_PLATE, 2)) + .register(plugin); + + new FoodFabricator(categories.electricity, SlimefunItems.FOOD_FABRICATOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.BILLON_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.BILLON_INGOT, SlimefunItems.TIN_CAN, SlimefunItems.SMALL_CAPACITOR, SlimefunItems.TIN_CAN, null, SlimefunItems.ELECTRIC_MOTOR, null}) { + + @Override + public int getEnergyConsumption() { + return 7; + } + + @Override + public int getCapacity() { + return 256; + } + + @Override + public int getSpeed() { + return 1; + } + + }.register(plugin); + + new FoodFabricator(categories.electricity, SlimefunItems.FOOD_FABRICATOR_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.FOOD_FABRICATOR, SlimefunItems.ELECTRIC_MOTOR, null, SlimefunItems.ELECTRO_MAGNET, null}) { + + @Override + public int getEnergyConsumption() { + return 24; + } + + @Override + public int getCapacity() { + return 512; + } + + @Override + public int getSpeed() { + return 6; + } + + }.register(plugin); + + new OrganicFood(categories.misc, SlimefunItems.WHEAT_ORGANIC_FOOD, Material.WHEAT) + .register(plugin); + + new OrganicFood(categories.misc, SlimefunItems.CARROT_ORGANIC_FOOD, Material.CARROT) + .register(plugin); + + new OrganicFood(categories.misc, SlimefunItems.POTATO_ORGANIC_FOOD, Material.POTATO) + .register(plugin); + + new OrganicFood(categories.misc, SlimefunItems.SEEDS_ORGANIC_FOOD, Material.WHEAT_SEEDS) + .register(plugin); + + new OrganicFood(categories.misc, SlimefunItems.BEETROOT_ORGANIC_FOOD, Material.BEETROOT) + .register(plugin); + + new OrganicFood(categories.misc, SlimefunItems.MELON_ORGANIC_FOOD, Material.MELON_SLICE) + .register(plugin); + + new OrganicFood(categories.misc, SlimefunItems.APPLE_ORGANIC_FOOD, Material.APPLE) + .register(plugin); + + if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { + new OrganicFood(categories.misc, SlimefunItems.SWEET_BERRIES_ORGANIC_FOOD, Material.SWEET_BERRIES) + .register(plugin); + } + + new OrganicFood(categories.misc, SlimefunItems.KELP_ORGANIC_FOOD, Material.DRIED_KELP) + .register(plugin); new OrganicFood(categories.misc, SlimefunItems.COCOA_ORGANIC_FOOD, Material.COCOA_BEANS) .register(plugin); - new AutoBreeder(categories.electricity, SlimefunItems.AUTO_BREEDER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.GOLD_18K, SlimefunItems.TIN_CAN, SlimefunItems.GOLD_18K, SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.HAY_BLOCK), SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.LEAD_INGOT, SlimefunItems.FOOD_FABRICATOR, SlimefunItems.LEAD_INGOT}) - .register(plugin); + new AutoBreeder(categories.electricity, SlimefunItems.AUTO_BREEDER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.GOLD_18K, SlimefunItems.TIN_CAN, SlimefunItems.GOLD_18K, SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.HAY_BLOCK), SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.LEAD_INGOT, SlimefunItems.FOOD_FABRICATOR, SlimefunItems.LEAD_INGOT}) + .register(plugin); - new AnimalGrowthAccelerator(categories.electricity, SlimefunItems.ANIMAL_GROWTH_ACCELERATOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.BLISTERING_INGOT_3, null, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.WHEAT_ORGANIC_FOOD, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.AUTO_BREEDER, SlimefunItems.REINFORCED_ALLOY_INGOT}) - .register(plugin); + new AnimalGrowthAccelerator(categories.electricity, SlimefunItems.ANIMAL_GROWTH_ACCELERATOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.BLISTERING_INGOT_3, null, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.WHEAT_ORGANIC_FOOD, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.AUTO_BREEDER, SlimefunItems.REINFORCED_ALLOY_INGOT}) + .register(plugin); new TreeGrowthAccelerator(categories.electricity, SlimefunItems.TREE_GROWTH_ACCELERATOR, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] {null, SlimefunItems.CARBONADO, null, SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.DIAMOND_AXE), SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.MAGNESIUM_SALT, SlimefunItems.BIG_CAPACITOR, SlimefunItems.MAGNESIUM_SALT}) .register(plugin); - + new XPCollector(categories.electricity, SlimefunItems.EXP_COLLECTOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.BLISTERING_INGOT_3, null, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.AUTO_ENCHANTER, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_BRONZE_INGOT}) - .register(plugin); + new ItemStack[] {null, SlimefunItems.BLISTERING_INGOT_3, null, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.AUTO_ENCHANTER, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_BRONZE_INGOT}) + .register(plugin); - new FoodComposter(categories.electricity, SlimefunItems.FOOD_COMPOSTER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.FOOD_FABRICATOR, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.TIN_CAN, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.TIN_CAN, null, SlimefunItems.ELECTRIC_MOTOR, null}) { - - @Override - public int getEnergyConsumption() { - return 8; - } + new FoodComposter(categories.electricity, SlimefunItems.FOOD_COMPOSTER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.FOOD_FABRICATOR, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.TIN_CAN, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.TIN_CAN, null, SlimefunItems.ELECTRIC_MOTOR, null}) { + + @Override + public int getEnergyConsumption() { + return 8; + } - @Override - public int getCapacity() { - return 256; - } + @Override + public int getCapacity() { + return 256; + } - @Override - public int getSpeed() { - return 1; - } + @Override + public int getSpeed() { + return 1; + } - }.register(plugin); + }.register(plugin); - new FoodComposter(categories.electricity, SlimefunItems.FOOD_COMPOSTER_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.FOOD_COMPOSTER, SlimefunItems.ELECTRIC_MOTOR, null, SlimefunItems.ELECTRO_MAGNET, null}) { + new FoodComposter(categories.electricity, SlimefunItems.FOOD_COMPOSTER_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.FOOD_COMPOSTER, SlimefunItems.ELECTRIC_MOTOR, null, SlimefunItems.ELECTRO_MAGNET, null}) { - @Override - public int getEnergyConsumption() { - return 26; - } + @Override + public int getEnergyConsumption() { + return 26; + } - @Override - public int getCapacity() { - return 512; - } + @Override + public int getCapacity() { + return 512; + } - @Override - public int getSpeed() { - return 10; - } + @Override + public int getSpeed() { + return 10; + } - }.register(plugin); + }.register(plugin); - new OrganicFertilizer(categories.misc, SlimefunItems.WHEAT_FERTILIZER, SlimefunItems.WHEAT_ORGANIC_FOOD) - .register(plugin); + new OrganicFertilizer(categories.misc, SlimefunItems.WHEAT_FERTILIZER, SlimefunItems.WHEAT_ORGANIC_FOOD) + .register(plugin); - new OrganicFertilizer(categories.misc, SlimefunItems.CARROT_FERTILIZER, SlimefunItems.CARROT_ORGANIC_FOOD) - .register(plugin); + new OrganicFertilizer(categories.misc, SlimefunItems.CARROT_FERTILIZER, SlimefunItems.CARROT_ORGANIC_FOOD) + .register(plugin); - new OrganicFertilizer(categories.misc, SlimefunItems.POTATO_FERTILIZER, SlimefunItems.POTATO_ORGANIC_FOOD) - .register(plugin); + new OrganicFertilizer(categories.misc, SlimefunItems.POTATO_FERTILIZER, SlimefunItems.POTATO_ORGANIC_FOOD) + .register(plugin); - new OrganicFertilizer(categories.misc, SlimefunItems.SEEDS_FERTILIZER, SlimefunItems.SEEDS_ORGANIC_FOOD) - .register(plugin); + new OrganicFertilizer(categories.misc, SlimefunItems.SEEDS_FERTILIZER, SlimefunItems.SEEDS_ORGANIC_FOOD) + .register(plugin); - new OrganicFertilizer(categories.misc, SlimefunItems.BEETROOT_FERTILIZER, SlimefunItems.BEETROOT_ORGANIC_FOOD) - .register(plugin); + new OrganicFertilizer(categories.misc, SlimefunItems.BEETROOT_FERTILIZER, SlimefunItems.BEETROOT_ORGANIC_FOOD) + .register(plugin); - new OrganicFertilizer(categories.misc, SlimefunItems.MELON_FERTILIZER, SlimefunItems.MELON_ORGANIC_FOOD) - .register(plugin); + new OrganicFertilizer(categories.misc, SlimefunItems.MELON_FERTILIZER, SlimefunItems.MELON_ORGANIC_FOOD) + .register(plugin); - new OrganicFertilizer(categories.misc, SlimefunItems.APPLE_FERTILIZER, SlimefunItems.APPLE_ORGANIC_FOOD) - .register(plugin); + new OrganicFertilizer(categories.misc, SlimefunItems.APPLE_FERTILIZER, SlimefunItems.APPLE_ORGANIC_FOOD) + .register(plugin); - new OrganicFertilizer(categories.misc, SlimefunItems.SWEET_BERRIES_FERTILIZER, SlimefunItems.SWEET_BERRIES_ORGANIC_FOOD) - .register(plugin); + new OrganicFertilizer(categories.misc, SlimefunItems.SWEET_BERRIES_FERTILIZER, SlimefunItems.SWEET_BERRIES_ORGANIC_FOOD) + .register(plugin); - new OrganicFertilizer(categories.misc, SlimefunItems.KELP_FERTILIZER, SlimefunItems.KELP_ORGANIC_FOOD) - .register(plugin); + new OrganicFertilizer(categories.misc, SlimefunItems.KELP_FERTILIZER, SlimefunItems.KELP_ORGANIC_FOOD) + .register(plugin); new OrganicFertilizer(categories.misc, SlimefunItems.COCOA_FERTILIZER, SlimefunItems.COCOA_ORGANIC_FOOD) .register(plugin); - new CropGrowthAccelerator(categories.electricity, SlimefunItems.CROP_GROWTH_ACCELERATOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.BLISTERING_INGOT_3, null, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.PROGRAMMABLE_ANDROID_FARMER, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.ANIMAL_GROWTH_ACCELERATOR, SlimefunItems.ELECTRO_MAGNET}) { + new CropGrowthAccelerator(categories.electricity, SlimefunItems.CROP_GROWTH_ACCELERATOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.BLISTERING_INGOT_3, null, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.PROGRAMMABLE_ANDROID_FARMER, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.ANIMAL_GROWTH_ACCELERATOR, SlimefunItems.ELECTRO_MAGNET}) { - @Override - public int getEnergyConsumption() { - return 25; - } + @Override + public int getEnergyConsumption() { + return 25; + } - @Override - public int getRadius() { - return 3; - } + @Override + public int getRadius() { + return 3; + } - @Override - public int getSpeed() { - return 3; - } + @Override + public int getSpeed() { + return 3; + } - }.register(plugin); + }.register(plugin); - new CropGrowthAccelerator(categories.electricity, SlimefunItems.CROP_GROWTH_ACCELERATOR_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.BLISTERING_INGOT_3, null, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.CROP_GROWTH_ACCELERATOR, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.ADVANCED_CIRCUIT_BOARD, SlimefunItems.ELECTRO_MAGNET}) { + new CropGrowthAccelerator(categories.electricity, SlimefunItems.CROP_GROWTH_ACCELERATOR_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.BLISTERING_INGOT_3, null, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.CROP_GROWTH_ACCELERATOR, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.ADVANCED_CIRCUIT_BOARD, SlimefunItems.ELECTRO_MAGNET}) { - @Override - public int getEnergyConsumption() { - return 30; - } + @Override + public int getEnergyConsumption() { + return 30; + } - @Override - public int getRadius() { - return 4; - } + @Override + public int getRadius() { + return 4; + } - @Override - public int getSpeed() { - return 4; - } + @Override + public int getSpeed() { + return 4; + } - }.register(plugin); + }.register(plugin); - new Freezer(categories.electricity, SlimefunItems.FREEZER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.SILVER_INGOT, null, SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.PACKED_ICE), SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.COOLING_UNIT, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.COOLING_UNIT}) { - - @Override - public int getEnergyConsumption() { - return 9; - } + new Freezer(categories.electricity, SlimefunItems.FREEZER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.SILVER_INGOT, null, SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.PACKED_ICE), SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.COOLING_UNIT, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.COOLING_UNIT}) { + + @Override + public int getEnergyConsumption() { + return 9; + } - @Override - public int getSpeed() { - return 1; - } + @Override + public int getSpeed() { + return 1; + } - }.register(plugin); + }.register(plugin); - new Freezer(categories.electricity, SlimefunItems.FREEZER_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.SILVER_INGOT, null, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.FREEZER, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.COOLING_UNIT, SlimefunItems.ALUMINUM_BRASS_INGOT, SlimefunItems.COOLING_UNIT}) { + new Freezer(categories.electricity, SlimefunItems.FREEZER_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.SILVER_INGOT, null, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.FREEZER, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.COOLING_UNIT, SlimefunItems.ALUMINUM_BRASS_INGOT, SlimefunItems.COOLING_UNIT}) { - @Override - public int getEnergyConsumption() { - return 15; - } + @Override + public int getEnergyConsumption() { + return 15; + } - @Override - public int getSpeed() { - return 2; - } + @Override + public int getSpeed() { + return 2; + } - }.register(plugin); + }.register(plugin); - new CoolantCell(categories.technicalComponents, SlimefunItems.REACTOR_COOLANT_CELL, RecipeType.FREEZER, - new ItemStack[] {new ItemStack(Material.BLUE_ICE), null, null, null, null, null, null, null, null}) - .register(plugin); + new CoolantCell(categories.technicalComponents, SlimefunItems.REACTOR_COOLANT_CELL, RecipeType.FREEZER, + new ItemStack[] {new ItemStack(Material.BLUE_ICE), null, null, null, null, null, null, null, null}) + .register(plugin); - new CoolantCell(categories.technicalComponents, SlimefunItems.NETHER_ICE_COOLANT_CELL, RecipeType.HEATED_PRESSURE_CHAMBER, - new ItemStack[] {SlimefunItems.ENRICHED_NETHER_ICE, null, null, null, null, null, null, null, null}, - new SlimefunItemStack(SlimefunItems.NETHER_ICE_COOLANT_CELL, 4)) - .register(plugin); + new CoolantCell(categories.technicalComponents, SlimefunItems.NETHER_ICE_COOLANT_CELL, RecipeType.HEATED_PRESSURE_CHAMBER, + new ItemStack[] {SlimefunItems.ENRICHED_NETHER_ICE, null, null, null, null, null, null, null, null}, + new SlimefunItemStack(SlimefunItems.NETHER_ICE_COOLANT_CELL, 8)) + .register(plugin); - new RadioactiveItem(categories.resources, Radioactivity.HIGH, SlimefunItems.NEPTUNIUM, RecipeType.NUCLEAR_REACTOR, - new ItemStack[] {SlimefunItems.URANIUM, null, null, null, null, null, null, null, null}) - .register(plugin); + new RadioactiveItem(categories.resources, Radioactivity.HIGH, SlimefunItems.NEPTUNIUM, RecipeType.NUCLEAR_REACTOR, + new ItemStack[] {SlimefunItems.URANIUM, null, null, null, null, null, null, null, null}) + .register(plugin); - new RadioactiveItem(categories.resources, Radioactivity.VERY_HIGH, SlimefunItems.PLUTONIUM, RecipeType.NUCLEAR_REACTOR, - new ItemStack[] {SlimefunItems.NEPTUNIUM, null, null, null, null, null, null, null, null}) - .register(plugin); + new RadioactiveItem(categories.resources, Radioactivity.VERY_HIGH, SlimefunItems.PLUTONIUM, RecipeType.NUCLEAR_REACTOR, + new ItemStack[] {SlimefunItems.NEPTUNIUM, null, null, null, null, null, null, null, null}) + .register(plugin); - new RadioactiveItem(categories.resources, Radioactivity.VERY_HIGH, SlimefunItems.BOOSTED_URANIUM, RecipeType.HEATED_PRESSURE_CHAMBER, - new ItemStack[] {SlimefunItems.PLUTONIUM, SlimefunItems.URANIUM, null, null, null, null, null, null, null}) - .register(plugin); + new RadioactiveItem(categories.resources, Radioactivity.VERY_HIGH, SlimefunItems.BOOSTED_URANIUM, RecipeType.HEATED_PRESSURE_CHAMBER, + new ItemStack[] {SlimefunItems.PLUTONIUM, SlimefunItems.URANIUM, null, null, null, null, null, null, null}) + .register(plugin); - new NuclearReactor(categories.electricity, SlimefunItems.NUCLEAR_REACTOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.CARBONADO_EDGED_CAPACITOR, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.REINFORCED_PLATE, SlimefunItems.COOLING_UNIT, SlimefunItems.REINFORCED_PLATE, SlimefunItems.LEAD_INGOT, SlimefunItems.REINFORCED_PLATE, SlimefunItems.LEAD_INGOT}){ - - @Override - public int getEnergyProduction() { - return 250; - } + new NuclearReactor(categories.electricity, SlimefunItems.NUCLEAR_REACTOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.CARBONADO_EDGED_CAPACITOR, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.REINFORCED_PLATE, SlimefunItems.COOLING_UNIT, SlimefunItems.REINFORCED_PLATE, SlimefunItems.LEAD_INGOT, SlimefunItems.REINFORCED_PLATE, SlimefunItems.LEAD_INGOT}){ + + @Override + public int getEnergyProduction() { + return 250; + } - @Override - public int getCapacity() { - return 16384; - } - - }.register(plugin); + @Override + public int getCapacity() { + return 16384; + } + + }.register(plugin); - new NetherStarReactor(categories.electricity, SlimefunItems.NETHER_STAR_REACTOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.BOOSTED_URANIUM, SlimefunItems.CARBONADO_EDGED_CAPACITOR, SlimefunItems.BOOSTED_URANIUM, SlimefunItems.REINFORCED_PLATE, new ItemStack(Material.NETHER_STAR), SlimefunItems.REINFORCED_PLATE, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.REINFORCED_PLATE, SlimefunItems.CORINTHIAN_BRONZE_INGOT}){ + new NetherStarReactor(categories.electricity, SlimefunItems.NETHER_STAR_REACTOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.BOOSTED_URANIUM, SlimefunItems.CARBONADO_EDGED_CAPACITOR, SlimefunItems.BOOSTED_URANIUM, SlimefunItems.REINFORCED_PLATE, new ItemStack(Material.NETHER_STAR), SlimefunItems.REINFORCED_PLATE, SlimefunItems.CORINTHIAN_BRONZE_INGOT, SlimefunItems.REINFORCED_PLATE, SlimefunItems.CORINTHIAN_BRONZE_INGOT}){ - @Override - public int getEnergyProduction() { - return 512; - } + @Override + public int getEnergyProduction() { + return 512; + } - @Override - public int getCapacity() { - return 32768; - } + @Override + public int getCapacity() { + return 32768; + } - }.register(plugin); + }.register(plugin); - new SlimefunItem(categories.cargo, SlimefunItems.CARGO_MOTOR, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.HARDENED_GLASS, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.HARDENED_GLASS, SlimefunItems.SILVER_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.SILVER_INGOT, SlimefunItems.HARDENED_GLASS, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.HARDENED_GLASS}, - new CustomItem(SlimefunItems.CARGO_MOTOR, 4)) - .register(plugin); + new SlimefunItem(categories.cargo, SlimefunItems.CARGO_MOTOR, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.HARDENED_GLASS, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.HARDENED_GLASS, SlimefunItems.SILVER_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.SILVER_INGOT, SlimefunItems.HARDENED_GLASS, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.HARDENED_GLASS}, + new SlimefunItemStack(SlimefunItems.CARGO_MOTOR, 4)) + .register(plugin); - new CargoManager(categories.cargo, SlimefunItems.CARGO_MANAGER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.HOLOGRAM_PROJECTOR, null, SlimefunItems.REINFORCED_PLATE, SlimefunItems.CARGO_MOTOR, SlimefunItems.REINFORCED_PLATE, SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.ANDROID_MEMORY_CORE, SlimefunItems.ALUMINUM_BRONZE_INGOT}) - .register(plugin); + new CargoManager(categories.cargo, SlimefunItems.CARGO_MANAGER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.HOLOGRAM_PROJECTOR, null, SlimefunItems.REINFORCED_PLATE, SlimefunItems.CARGO_MOTOR, SlimefunItems.REINFORCED_PLATE, SlimefunItems.ALUMINUM_BRONZE_INGOT, SlimefunItems.ANDROID_MEMORY_CORE, SlimefunItems.ALUMINUM_BRONZE_INGOT}) + .register(plugin); - new CargoConnectorNode(categories.cargo, SlimefunItems.CARGO_CONNECTOR_NODE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.BRONZE_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.BRONZE_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.CARGO_MOTOR, SlimefunItems.SILVER_INGOT, SlimefunItems.BRONZE_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.BRONZE_INGOT}, - new CustomItem(SlimefunItems.CARGO_CONNECTOR_NODE, 4)) - .register(plugin); + new CargoConnectorNode(categories.cargo, SlimefunItems.CARGO_CONNECTOR_NODE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.BRONZE_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.BRONZE_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.CARGO_MOTOR, SlimefunItems.SILVER_INGOT, SlimefunItems.BRONZE_INGOT, SlimefunItems.SILVER_INGOT, SlimefunItems.BRONZE_INGOT}, + new SlimefunItemStack(SlimefunItems.CARGO_CONNECTOR_NODE, 4)) + .register(plugin); - new CargoInputNode(categories.cargo, SlimefunItems.CARGO_INPUT_NODE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.HOPPER), null, SlimefunItems.BILLON_INGOT, SlimefunItems.CARGO_CONNECTOR_NODE, SlimefunItems.BILLON_INGOT, null, new ItemStack(Material.HOPPER), null}, - new CustomItem(SlimefunItems.CARGO_INPUT_NODE, 2)) - .register(plugin); + new CargoInputNode(categories.cargo, SlimefunItems.CARGO_INPUT_NODE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.HOPPER), null, SlimefunItems.BILLON_INGOT, SlimefunItems.CARGO_CONNECTOR_NODE, SlimefunItems.BILLON_INGOT, null, new ItemStack(Material.HOPPER), null}, + new SlimefunItemStack(SlimefunItems.CARGO_INPUT_NODE, 2)) + .register(plugin); - new CargoOutputNode(categories.cargo, SlimefunItems.CARGO_OUTPUT_NODE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.HOPPER), null, SlimefunItems.BRASS_INGOT, SlimefunItems.CARGO_CONNECTOR_NODE, SlimefunItems.BRASS_INGOT, null, new ItemStack(Material.HOPPER), null}, - new CustomItem(SlimefunItems.CARGO_OUTPUT_NODE, 2)) - .register(plugin); + new CargoOutputNode(categories.cargo, SlimefunItems.CARGO_OUTPUT_NODE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.HOPPER), null, SlimefunItems.BRASS_INGOT, SlimefunItems.CARGO_CONNECTOR_NODE, SlimefunItems.BRASS_INGOT, null, new ItemStack(Material.HOPPER), null}, + new SlimefunItemStack(SlimefunItems.CARGO_OUTPUT_NODE, 2)) + .register(plugin); - new AdvancedCargoOutputNode(categories.cargo, SlimefunItems.CARGO_OUTPUT_NODE_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.CARGO_MOTOR, null, SlimefunItems.COBALT_INGOT, SlimefunItems.CARGO_OUTPUT_NODE, SlimefunItems.COBALT_INGOT, null, SlimefunItems.CARGO_MOTOR, null}, - new CustomItem(SlimefunItems.CARGO_OUTPUT_NODE_2)) - .register(plugin); + new AdvancedCargoOutputNode(categories.cargo, SlimefunItems.CARGO_OUTPUT_NODE_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.CARGO_MOTOR, null, SlimefunItems.COBALT_INGOT, SlimefunItems.CARGO_OUTPUT_NODE, SlimefunItems.COBALT_INGOT, null, SlimefunItems.CARGO_MOTOR, null}) + .register(plugin); - new AutomatedCraftingChamber(categories.electricity, SlimefunItems.AUTOMATED_CRAFTING_CHAMBER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, new ItemStack(Material.CRAFTING_TABLE), null, SlimefunItems.CARGO_MOTOR, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.CARGO_MOTOR, null, SlimefunItems.ELECTRIC_MOTOR, null}) { + new AutomatedCraftingChamber(categories.electricity, SlimefunItems.AUTOMATED_CRAFTING_CHAMBER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, new ItemStack(Material.CRAFTING_TABLE), null, SlimefunItems.CARGO_MOTOR, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.CARGO_MOTOR, null, SlimefunItems.ELECTRIC_MOTOR, null}) { - @Override - public int getEnergyConsumption() { - return 10; - } + @Override + public int getEnergyConsumption() { + return 10; + } - @Override - public int getCapacity() { - return 256; - } + @Override + public int getCapacity() { + return 256; + } - }.register(plugin); + }.register(plugin); - new ReactorAccessPort(categories.cargo, SlimefunItems.REACTOR_ACCESS_PORT, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.BLISTERING_INGOT_3, null, SlimefunItems.LEAD_INGOT, SlimefunItems.CARGO_MOTOR, SlimefunItems.LEAD_INGOT, null, SlimefunItems.ELECTRIC_MOTOR, null}) - .register(plugin); + new ReactorAccessPort(categories.cargo, SlimefunItems.REACTOR_ACCESS_PORT, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.BLISTERING_INGOT_3, null, SlimefunItems.LEAD_INGOT, SlimefunItems.CARGO_MOTOR, SlimefunItems.LEAD_INGOT, null, SlimefunItems.ELECTRIC_MOTOR, null}) + .register(plugin); - new FluidPump(categories.electricity, SlimefunItems.FLUID_PUMP, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.MEDIUM_CAPACITOR, null, new ItemStack(Material.BUCKET), SlimefunItems.CARGO_MOTOR, new ItemStack(Material.BUCKET), null, SlimefunItems.OIL_PUMP, null}) - .register(plugin); + new FluidPump(categories.electricity, SlimefunItems.FLUID_PUMP, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.MEDIUM_CAPACITOR, null, new ItemStack(Material.BUCKET), SlimefunItems.CARGO_MOTOR, new ItemStack(Material.BUCKET), null, SlimefunItems.OIL_PUMP, null}) + .register(plugin); - new TrashCan(categories.cargo, SlimefunItems.TRASH_CAN, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {null, SlimefunItems.PORTABLE_DUSTBIN, null, SlimefunItems.LEAD_INGOT, SlimefunItems.CARGO_MOTOR, SlimefunItems.LEAD_INGOT, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.ALUMINUM_INGOT}) - .register(plugin); + new TrashCan(categories.cargo, SlimefunItems.TRASH_CAN, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {null, SlimefunItems.PORTABLE_DUSTBIN, null, SlimefunItems.LEAD_INGOT, SlimefunItems.CARGO_MOTOR, SlimefunItems.LEAD_INGOT, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.LEAD_INGOT, SlimefunItems.ALUMINUM_INGOT}) + .register(plugin); - new CarbonPress(categories.electricity, SlimefunItems.CARBON_PRESS, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CARBON, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.CARBON, SlimefunItems.CARBON, SlimefunItems.HEATED_PRESSURE_CHAMBER, SlimefunItems.CARBON, SlimefunItems.HEATING_COIL, SlimefunItems.CARBONADO, SlimefunItems.HEATING_COIL}) { + new CarbonPress(categories.electricity, SlimefunItems.CARBON_PRESS, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CARBON, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.CARBON, SlimefunItems.CARBON, SlimefunItems.HEATED_PRESSURE_CHAMBER, SlimefunItems.CARBON, SlimefunItems.HEATING_COIL, SlimefunItems.CARBONADO, SlimefunItems.HEATING_COIL}) { - @Override - public int getEnergyConsumption() { - return 10; - } + @Override + public int getEnergyConsumption() { + return 10; + } - @Override - public int getCapacity() { - return 256; - } + @Override + public int getCapacity() { + return 256; + } - @Override - public int getSpeed() { - return 1; - } + @Override + public int getSpeed() { + return 1; + } - }.register(plugin); + }.register(plugin); - new CarbonPress(categories.electricity, SlimefunItems.CARBON_PRESS_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CARBONADO, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.CARBONADO, SlimefunItems.CARBON, SlimefunItems.CARBON_PRESS, SlimefunItems.CARBON, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.HEATING_COIL}) { + new CarbonPress(categories.electricity, SlimefunItems.CARBON_PRESS_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CARBONADO, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.CARBONADO, SlimefunItems.CARBON, SlimefunItems.CARBON_PRESS, SlimefunItems.CARBON, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.HEATING_COIL}) { - @Override - public int getEnergyConsumption() { - return 25; - } + @Override + public int getEnergyConsumption() { + return 25; + } - @Override - public int getCapacity() { - return 512; - } + @Override + public int getCapacity() { + return 512; + } - @Override - public int getSpeed() { - return 3; - } + @Override + public int getSpeed() { + return 3; + } - }.register(plugin); + }.register(plugin); - new CarbonPress(categories.electricity, SlimefunItems.CARBON_PRESS_3, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.CARBONADO, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.CARBONADO, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.CARBON_PRESS_2, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.HEATING_COIL}) { + new CarbonPress(categories.electricity, SlimefunItems.CARBON_PRESS_3, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.CARBONADO, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.CARBONADO, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.CARBON_PRESS_2, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.HEATING_COIL}) { - @Override - public int getEnergyConsumption() { - return 90; - } + @Override + public int getEnergyConsumption() { + return 90; + } - @Override - public int getCapacity() { - return 512; - } + @Override + public int getCapacity() { + return 512; + } - @Override - public int getSpeed() { - return 15; - } + @Override + public int getSpeed() { + return 15; + } - }.register(plugin); + }.register(plugin); - new ElectricSmeltery(categories.electricity, SlimefunItems.ELECTRIC_SMELTERY, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {new ItemStack(Material.NETHER_BRICKS), SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.NETHER_BRICKS), SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRIC_INGOT_FACTORY, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.GILDED_IRON}) { + new ElectricSmeltery(categories.electricity, SlimefunItems.ELECTRIC_SMELTERY, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {new ItemStack(Material.NETHER_BRICKS), SlimefunItems.ELECTRIC_MOTOR, new ItemStack(Material.NETHER_BRICKS), SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRIC_INGOT_FACTORY, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.GILDED_IRON}) { - @Override - public int getEnergyConsumption() { - return 10; - } + @Override + public int getEnergyConsumption() { + return 10; + } - @Override - public int getCapacity() { - return 512; - } + @Override + public int getCapacity() { + return 512; + } - @Override - public int getSpeed() { - return 1; - } + @Override + public int getSpeed() { + return 1; + } - }.register(plugin); + }.register(plugin); - new ElectricSmeltery(categories.electricity, SlimefunItems.ELECTRIC_SMELTERY_2, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRIC_SMELTERY, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.GILDED_IRON}) { - - @Override - public int getEnergyConsumption() { - return 20; - } + new ElectricSmeltery(categories.electricity, SlimefunItems.ELECTRIC_SMELTERY_2, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.POWER_CRYSTAL, SlimefunItems.DAMASCUS_STEEL_INGOT, SlimefunItems.HEATING_COIL, SlimefunItems.ELECTRIC_SMELTERY, SlimefunItems.HEATING_COIL, SlimefunItems.GILDED_IRON, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.GILDED_IRON}) { + + @Override + public int getEnergyConsumption() { + return 20; + } - @Override - public int getCapacity() { - return 1024; - } + @Override + public int getCapacity() { + return 1024; + } - @Override - public int getSpeed() { - return 3; - } + @Override + public int getSpeed() { + return 3; + } - }.register(plugin); + }.register(plugin); new IronGolemAssembler(categories.electricity, SlimefunItems.IRON_GOLEM_ASSEMBLER, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] {SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.ADVANCED_CIRCUIT_BOARD, SlimefunItems.BLISTERING_INGOT_3, new ItemStack(Material.IRON_BLOCK), SlimefunItems.ANDROID_MEMORY_CORE, new ItemStack(Material.IRON_BLOCK), SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.CARBONADO_EDGED_CAPACITOR}) .register(plugin); - new WitherAssembler(categories.electricity, SlimefunItems.WITHER_ASSEMBLER, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.BLISTERING_INGOT_3, new ItemStack(Material.NETHER_STAR), SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.ANDROID_MEMORY_CORE, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.CARBONADO_EDGED_CAPACITOR}) - .register(plugin); - - if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { - new TapeMeasure(categories.usefulItems, SlimefunItems.TAPE_MEASURE, RecipeType.ENHANCED_CRAFTING_TABLE, - new ItemStack[] {SlimefunItems.SILICON, new ItemStack(Material.YELLOW_DYE), SlimefunItems.SILICON, new ItemStack(Material.YELLOW_DYE), new ItemStack(Material.STRING), new ItemStack(Material.YELLOW_DYE), SlimefunItems.GILDED_IRON, new ItemStack(Material.YELLOW_DYE), SlimefunItems.SILICON}) - .register(plugin); - } - } - - private static void registerArmorSet(Category category, ItemStack baseComponent, ItemStack[] items, String idSyntax, boolean vanilla, SlimefunAddon addon) { + new WitherAssembler(categories.electricity, SlimefunItems.WITHER_ASSEMBLER, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.BLISTERING_INGOT_3, new ItemStack(Material.NETHER_STAR), SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.ANDROID_MEMORY_CORE, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.CARBONADO_EDGED_CAPACITOR}) + .register(plugin); + + if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { + new TapeMeasure(categories.usefulItems, SlimefunItems.TAPE_MEASURE, RecipeType.ENHANCED_CRAFTING_TABLE, + new ItemStack[] {SlimefunItems.SILICON, new ItemStack(Material.YELLOW_DYE), SlimefunItems.SILICON, new ItemStack(Material.YELLOW_DYE), new ItemStack(Material.STRING), new ItemStack(Material.YELLOW_DYE), SlimefunItems.GILDED_IRON, new ItemStack(Material.YELLOW_DYE), SlimefunItems.SILICON}) + .register(plugin); + } + } + + private static void registerArmorSet(Category category, ItemStack baseComponent, ItemStack[] items, String idSyntax, boolean vanilla, PotionEffect[][] effects, SlimefunAddon addon) { String[] components = new String[] { "_HELMET", "_CHESTPLATE", "_LEGGINGS", "_BOOTS" }; List recipes = new ArrayList<>(); + recipes.add(new ItemStack[] { baseComponent, baseComponent, baseComponent, baseComponent, null, baseComponent, null, null, null }); recipes.add(new ItemStack[] { baseComponent, null, baseComponent, baseComponent, baseComponent, baseComponent, baseComponent, baseComponent, baseComponent }); recipes.add(new ItemStack[] { baseComponent, baseComponent, baseComponent, baseComponent, null, baseComponent, baseComponent, null, baseComponent }); @@ -3256,23 +3243,7 @@ public final class SlimefunItemSetup { if (vanilla) { new VanillaItem(category, items[i], idSyntax + components[i], RecipeType.ARMOR_FORGE, recipes.get(i)).register(addon); } - else { - new SlimefunItem(category, new SlimefunItemStack(idSyntax + components[i], items[i]), RecipeType.ARMOR_FORGE, recipes.get(i)).register(addon); - } - } - } - - private static void registerArmorSet(Category category, ItemStack baseComponent, ItemStack[] items, String idSyntax, PotionEffect[][] effects, SlimefunAddon addon) { - String[] components = new String[] { "_HELMET", "_CHESTPLATE", "_LEGGINGS", "_BOOTS" }; - List recipes = new ArrayList<>(); - - recipes.add(new ItemStack[] { baseComponent, baseComponent, baseComponent, baseComponent, null, baseComponent, null, null, null }); - recipes.add(new ItemStack[] { baseComponent, null, baseComponent, baseComponent, baseComponent, baseComponent, baseComponent, baseComponent, baseComponent }); - recipes.add(new ItemStack[] { baseComponent, baseComponent, baseComponent, baseComponent, null, baseComponent, baseComponent, null, baseComponent }); - recipes.add(new ItemStack[] { null, null, null, baseComponent, null, baseComponent, baseComponent, null, baseComponent }); - - for (int i = 0; i < 4; i++) { - if (i < effects.length && effects[i].length > 0) { + else if (i < effects.length && effects[i].length > 0) { new SlimefunArmorPiece(category, new SlimefunItemStack(idSyntax + components[i], items[i]), RecipeType.ARMOR_FORGE, recipes.get(i), effects[i]).register(addon); } else { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java index e0412b9c2..7d982ba07 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java @@ -35,8 +35,17 @@ import me.mrCookieSlime.Slimefun.api.Slimefun; public class ArmorTask implements Runnable { private final Set radiationEffects; + private final boolean radioactiveFire; + + /** + * This creates a new {@link ArmorTask}. + * + * @param radioactiveFire + * Whether radiation also causes a {@link Player} to burn + */ + public ArmorTask(boolean radioactiveFire) { + this.radioactiveFire = radioactiveFire; - public ArmorTask() { Set effects = new HashSet<>(); effects.add(new PotionEffect(PotionEffectType.WITHER, 400, 2)); effects.add(new PotionEffect(PotionEffectType.BLINDNESS, 400, 3)); @@ -47,6 +56,16 @@ public class ArmorTask implements Runnable { radiationEffects = Collections.unmodifiableSet(effects); } + /** + * This returns a {@link Set} of {@link PotionEffect PotionEffects} which get applied to + * a {@link Player} when they are exposed to deadly radiation. + * + * @return The {@link Set} of {@link PotionEffect PotionEffects} applied upon radioactive contact + */ + public Set getRadiationEffects() { + return radiationEffects; + } + @Override public void run() { for (Player p : Bukkit.getOnlinePlayers()) { @@ -144,7 +163,11 @@ public class ArmorTask implements Runnable { Slimefun.runSync(() -> { p.addPotionEffects(radiationEffects); - p.setFireTicks(400); + + // if radiative fire is enabled + if (radioactiveFire) { + p.setFireTicks(400); + } }); return true; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java index d80bc6e1c..f90b0a937 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java @@ -52,7 +52,7 @@ public class TickerTask implements Runnable { Iterator> removals = deletionQueue.entrySet().iterator(); while (removals.hasNext()) { Map.Entry entry = removals.next(); - BlockStorage._integrated_removeBlockInfo(entry.getKey(), entry.getValue()); + BlockStorage.deleteLocationInfoUnsafely(entry.getKey(), entry.getValue()); removals.remove(); } @@ -81,7 +81,7 @@ public class TickerTask implements Runnable { Iterator> moves = movingQueue.entrySet().iterator(); while (moves.hasNext()) { Map.Entry entry = moves.next(); - BlockStorage._integrated_moveLocationInfo(entry.getKey(), entry.getValue()); + BlockStorage.moveLocationInfoUnsafely(entry.getKey(), entry.getValue()); moves.remove(); } @@ -154,7 +154,7 @@ public class TickerTask implements Runnable { Slimefun.getLogger().log(Level.SEVERE, " "); bugs.remove(position); - BlockStorage._integrated_removeBlockInfo(l, true); + BlockStorage.deleteLocationInfoUnsafely(l, true); Bukkit.getScheduler().scheduleSyncDelayedTask(SlimefunPlugin.instance(), () -> l.getBlock().setType(Material.AIR)); } else { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/HeadTexture.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/HeadTexture.java index d8aecf27e..028d7e092 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/HeadTexture.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/HeadTexture.java @@ -96,7 +96,12 @@ public enum HeadTexture { NETHER_STAR_REACTOR("a11ed1d1b25b624665ecdddc3d3a5dff0b9f35e3de77a12f516e60fe8501cc8d"), UNKNOWN("46ba63344f49dd1c4f5488e926bf3d9e2b29916a6c50d610bb40a5273dc8c82"), MISSING_TEXTURE("e9eb9da26cf2d3341397a7f4913ba3d37d1ad10eae30ab25fa39ceb84bc"), - MINECRAFT_CHUNK("8449b9318e33158e64a46ab0de121c3d40000e3332c1574932b3c849d8fa0dc2"); + MINECRAFT_CHUNK("8449b9318e33158e64a46ab0de121c3d40000e3332c1574932b3c849d8fa0dc2"), + CHEST_TERMINAL("7a44ff3a5f49c69cab676bad8d98a063fa78cfa61916fdef3e267557fec18283"), + CARGO_ARROW_LEFT("f2599bd986659b8ce2c4988525c94e19ddd39fad08a38284a197f1b70675acc"), + CARGO_ARROW_RIGHT("c2f910c47da042e4aa28af6cc81cf48ac6caf37dab35f88db993accb9dfe516"), + ADD_NEW_LANGUAGE("3edd20be93520949e6ce789dc4f43efaeb28c717ee6bfcbbe02780142f716"), + IRON_GOLEM("89091d79ea0f59ef7ef94d7bba6e5f17f2f7d4572c44f90f76c4819a714"); private final String texture; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/LoreBuilder.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/LoreBuilder.java index 49d3ff06d..5ee60be57 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/LoreBuilder.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/LoreBuilder.java @@ -1,9 +1,24 @@ package io.github.thebusybiscuit.slimefun4.utils; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; + import io.github.thebusybiscuit.slimefun4.core.attributes.MachineTier; import io.github.thebusybiscuit.slimefun4.core.attributes.MachineType; import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactivity; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +/** + * This utility class provides a few handy methods and constants to build the lore of any + * {@link SlimefunItemStack}. It is mostly used directly inside the class {@link SlimefunItems}. + * + * @author TheBusyBiscuit + * + * @see SlimefunItems + * + */ public final class LoreBuilder { public static final String HAZMAT_SUIT_REQUIRED = "&8\u21E8 &4Hazmat Suit required!"; @@ -12,6 +27,8 @@ public final class LoreBuilder { public static final String RIGHT_CLICK_TO_OPEN = "&eRight Click&7 to open"; public static final String CROUCH_TO_USE = "&eCrouch&7 to use"; + private static final DecimalFormat hungerFormat = new DecimalFormat("#.0", DecimalFormatSymbols.getInstance(Locale.ROOT)); + private LoreBuilder() {} public static String radioactive(Radioactivity radioactivity) { @@ -46,4 +63,8 @@ public final class LoreBuilder { return "&8\u21E8 &7Material: &b" + material; } + public static String hunger(double value) { + return "&7&oRestores &b&o" + hungerFormat.format(value) + " &7&oHunger"; + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java index e73acbb3c..b1250a9c8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java @@ -212,14 +212,16 @@ public final class SlimefunUtils { } // Performance optimization - ItemStackWrapper wrapper = new ItemStackWrapper(item); + if (!(item instanceof SlimefunItemStack)) { + item = new ItemStackWrapper(item); + } for (ItemStack stack : inventory.getStorageContents()) { if (stack == null || stack.getType() == Material.AIR) { continue; } - if (isItemSimilar(stack, wrapper, checkLore)) { + if (isItemSimilar(stack, item, checkLore, false)) { return true; } } @@ -241,7 +243,6 @@ public final class SlimefunUtils { return ((SlimefunItemStack) item).getItemId().equals(((SlimefunItemStack) sfitem).getItemId()); } - boolean sfItemHasMeta = sfitem.hasItemMeta(); if (item.hasItemMeta()) { ItemMeta itemMeta = item.getItemMeta(); @@ -255,13 +256,12 @@ public final class SlimefunUtils { ImmutableItemMeta meta = ((SlimefunItemStack) sfitem).getImmutableMeta(); return equalsItemMeta(itemMeta, meta, checkLore); } - - if (sfItemHasMeta) { + else if (sfitem.hasItemMeta()) { return equalsItemMeta(itemMeta, sfitem.getItemMeta(), checkLore); } } else { - return !sfItemHasMeta; + return !sfitem.hasItemMeta(); } return false; @@ -270,57 +270,43 @@ public final class SlimefunUtils { private static boolean equalsItemMeta(ItemMeta itemMeta, ImmutableItemMeta meta, boolean checkLore) { Optional displayName = meta.getDisplayName(); - if (itemMeta.hasDisplayName() && displayName.isPresent()) { - if (itemMeta.getDisplayName().equals(displayName.get())) { - Optional> itemLore = meta.getLore(); - - if (checkLore) { - if (itemMeta.hasLore() && itemLore.isPresent()) { - return equalsLore(itemMeta.getLore(), itemLore.get()); - } - else return !itemMeta.hasLore() && !itemLore.isPresent(); - } - else return true; - } - else return false; + if (itemMeta.hasDisplayName() != displayName.isPresent()) { + return false; } - else if (!itemMeta.hasDisplayName() && !displayName.isPresent()) { + else if (itemMeta.hasDisplayName() && displayName.isPresent() && !itemMeta.getDisplayName().equals(displayName.get())) { + return false; + } + else if (!checkLore) { + return true; + } + else { Optional> itemLore = meta.getLore(); - if (checkLore) { - if (itemMeta.hasLore() && itemLore.isPresent()) { - return equalsLore(itemMeta.getLore(), itemLore.get()); - } - else return !itemMeta.hasLore() && !itemLore.isPresent(); + if (itemMeta.hasLore() && itemLore.isPresent()) { + return equalsLore(itemMeta.getLore(), itemLore.get()); + } + else { + return !itemMeta.hasLore() && !itemLore.isPresent(); } - else return true; } - else return false; } private static boolean equalsItemMeta(ItemMeta itemMeta, ItemMeta sfitemMeta, boolean checkLore) { - if (itemMeta.hasDisplayName() && sfitemMeta.hasDisplayName()) { - if (itemMeta.getDisplayName().equals(sfitemMeta.getDisplayName())) { - if (checkLore) { - if (itemMeta.hasLore() && sfitemMeta.hasLore()) { - return equalsLore(itemMeta.getLore(), sfitemMeta.getLore()); - } - else return !itemMeta.hasLore() && !sfitemMeta.hasLore(); - } - else return true; - } - else return false; + if (itemMeta.hasDisplayName() != sfitemMeta.hasDisplayName()) { + return false; } - else if (!itemMeta.hasDisplayName() && !sfitemMeta.hasDisplayName()) { - if (checkLore) { - if (itemMeta.hasLore() && sfitemMeta.hasLore()) { - return equalsLore(itemMeta.getLore(), sfitemMeta.getLore()); - } - else return !itemMeta.hasLore() && !sfitemMeta.hasLore(); - } - else return true; + else if (itemMeta.hasDisplayName() && sfitemMeta.hasDisplayName() && !itemMeta.getDisplayName().equals(sfitemMeta.getDisplayName())) { + return false; + } + else if (!checkLore) { + return true; + } + else if (itemMeta.hasLore() && sfitemMeta.hasLore()) { + return equalsLore(itemMeta.getLore(), sfitemMeta.getLore()); + } + else { + return !itemMeta.hasLore() && !sfitemMeta.hasLore(); } - else return false; } private static boolean equalsLore(List lore, List lore2) { diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Lists/RecipeType.java b/src/main/java/me/mrCookieSlime/Slimefun/Lists/RecipeType.java index fab7fceed..8b62a1692 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Lists/RecipeType.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Lists/RecipeType.java @@ -19,6 +19,7 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.recipes.MinecraftRecipe; +import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; @@ -47,6 +48,7 @@ public class RecipeType implements Keyed { }); public static final RecipeType MOB_DROP = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "mob_drop"), new CustomItem(Material.IRON_SWORD, "&bMob Drop"), RecipeType::registerMobDrop, "", "&rKill the specified Mob to obtain this Item"); + public static final RecipeType BARTER_DROP = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "barter_drop"), new CustomItem(Material.GOLD_INGOT, "&bBarter Drop"), RecipeType::registerBarterDrop, "&aBarter with piglins for a chance", "&ato obtain this item"); public static final RecipeType HEATED_PRESSURE_CHAMBER = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "heated_pressure_chamber"), SlimefunItems.HEATED_PRESSURE_CHAMBER); public static final RecipeType FOOD_FABRICATOR = new RecipeType(new NamespacedKey(SlimefunPlugin.instance(), "food_fabricator"), SlimefunItems.FOOD_FABRICATOR); @@ -141,6 +143,12 @@ public class RecipeType implements Keyed { return key; } + private static void registerBarterDrop(ItemStack[] recipe, ItemStack output) { + if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) { + SlimefunPlugin.getRegistry().getBarteringDrops().add(output); + } + } + private static void registerMobDrop(ItemStack[] recipe, ItemStack output) { String mob = ChatColor.stripColor(recipe[4].getItemMeta().getDisplayName()).toUpperCase(Locale.ROOT).replace(' ', '_'); EntityType entity = EntityType.valueOf(mob); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Lists/SlimefunItems.java b/src/main/java/me/mrCookieSlime/Slimefun/Lists/SlimefunItems.java index 4b8d21ea3..826452ce1 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Lists/SlimefunItems.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Lists/SlimefunItems.java @@ -155,10 +155,10 @@ public final class SlimefunItems { public static final SlimefunItemStack GILDED_IRON_CHESTPLATE = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GILDED_IRON_CHESTPLATE; public static final SlimefunItemStack GILDED_IRON_LEGGINGS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GILDED_IRON_LEGGINGS; public static final SlimefunItemStack GILDED_IRON_BOOTS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GILDED_IRON_BOOTS; - public static final SlimefunItemStack GOLD_HELMET = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLD_HELMET; - public static final SlimefunItemStack GOLD_CHESTPLATE = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLD_CHESTPLATE; - public static final SlimefunItemStack GOLD_LEGGINGS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLD_LEGGINGS; - public static final SlimefunItemStack GOLD_BOOTS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLD_BOOTS; + public static final SlimefunItemStack GOLD_HELMET = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLDEN_HELMET_12K; + public static final SlimefunItemStack GOLD_CHESTPLATE = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLDEN_CHESTPLATE_12K; + public static final SlimefunItemStack GOLD_LEGGINGS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLDEN_LEGGINGS_12K; + public static final SlimefunItemStack GOLD_BOOTS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLDEN_BOOTS_12K; public static final SlimefunItemStack SLIME_HELMET_STEEL = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.SLIME_HELMET_STEEL; public static final SlimefunItemStack SLIME_CHESTPLATE_STEEL = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.SLIME_CHESTPLATE_STEEL; public static final SlimefunItemStack SLIME_LEGGINGS_STEEL = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.SLIME_LEGGINGS_STEEL; diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunBlockHandler.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunBlockHandler.java index 3eae993b7..d69c6eb65 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunBlockHandler.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunBlockHandler.java @@ -4,6 +4,7 @@ import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.Event; +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; @@ -15,7 +16,8 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; * {@code SlimefunItem.registerBlockHandler(String, SlimefunBlockHandler); } * * @author TheBusyBiscuit - * + * + * */ @FunctionalInterface public interface SlimefunBlockHandler { @@ -24,6 +26,8 @@ public interface SlimefunBlockHandler { * This method gets called when the {@link Block} is placed. * Use this method to initialize block data. * + * @deprecated Use a {@link BlockPlaceHandler} instead + * * @param p * The {@link Player} who placed it * @param b @@ -31,8 +35,9 @@ public interface SlimefunBlockHandler { * @param item * The {@link SlimefunItem} that will be stored inside the {@link Block} */ + @Deprecated default void onPlace(Player p, Block b, SlimefunItem item) { - // This method can optionally be implemented by classes implementing it. + // This has been deprecated } /** diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java index aebb38afd..8282df268 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java @@ -28,7 +28,6 @@ import io.github.thebusybiscuit.slimefun4.api.exceptions.WrongItemStackException import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemState; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; -import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider; import io.github.thebusybiscuit.slimefun4.core.attributes.Placeable; import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive; import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable; @@ -45,7 +44,6 @@ import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; -import me.mrCookieSlime.Slimefun.Objects.handlers.GeneratorTicker; import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; @@ -74,7 +72,6 @@ public class SlimefunItem implements Placeable { private boolean ticking = false; private BlockTicker blockTicker; - protected GeneratorTicker generatorTicker; /** * This creates a new {@link SlimefunItem} from the given arguments. @@ -226,7 +223,7 @@ public class SlimefunItem implements Placeable { @SuppressWarnings("unchecked") public Optional> getItemSetting(String key, Class c) { for (ItemSetting setting : itemSettings) { - if (setting.getKey().equals(key) && c.isInstance(setting.getDefaultValue())) { + if (setting.getKey().equals(key) && setting.isType(c)) { return Optional.of((ItemSetting) setting); } } @@ -320,15 +317,6 @@ public class SlimefunItem implements Placeable { return blockTicker; } - /** - * @deprecated The interface {@link EnergyNetProvider} should be implemented instead - * @return A {@link GeneratorTicker} - */ - @Deprecated - public GeneratorTicker getEnergyTicker() { - return generatorTicker; - } - /** * This method registers this {@link SlimefunItem}. * Always call this method after your {@link SlimefunItem} has been initialized. @@ -661,9 +649,6 @@ public class SlimefunItem implements Placeable { SlimefunPlugin.getRegistry().getTickerBlocks().add(getID()); blockTicker = (BlockTicker) handler; } - else if (handler instanceof GeneratorTicker) { - generatorTicker = (GeneratorTicker) handler; - } } } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java index 3a0cd7fd5..7d135c987 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java @@ -52,19 +52,8 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock, BlockMenu inv = BlockStorage.getInventory(b); if (inv != null) { - for (int slot : getInputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - - for (int slot : getOutputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } + inv.dropItems(b.getLocation(), getInputSlots()); + inv.dropItems(b.getLocation(), getOutputSlots()); } progress.remove(b); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AGenerator.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AGenerator.java index 874fe3c4a..2a94bce84 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AGenerator.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AGenerator.java @@ -69,18 +69,8 @@ public abstract class AGenerator extends AbstractEnergyProvider { BlockMenu inv = BlockStorage.getInventory(b); if (inv != null) { - for (int slot : getInputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } - for (int slot : getOutputSlots()) { - if (inv.getItemInSlot(slot) != null) { - b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot)); - inv.replaceExistingItem(slot, null); - } - } + inv.dropItems(b.getLocation(), getInputSlots()); + inv.dropItems(b.getLocation(), getOutputSlots()); } progress.remove(b.getLocation()); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/handlers/GeneratorTicker.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/handlers/GeneratorTicker.java deleted file mode 100644 index a941888bf..000000000 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/handlers/GeneratorTicker.java +++ /dev/null @@ -1,44 +0,0 @@ -package me.mrCookieSlime.Slimefun.Objects.handlers; - -import java.util.Optional; - -import org.bukkit.Location; - -import io.github.thebusybiscuit.slimefun4.api.exceptions.IncompatibleItemHandlerException; -import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; -import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider; -import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; -import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; -import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; - -/** - * @deprecated Please implement the {@link EnergyNetProvider} interface instead. - * - */ -@Deprecated -public abstract class GeneratorTicker implements ItemHandler { - - public abstract double generateEnergy(Location l, SlimefunItem item, Config data); - - public abstract boolean explode(Location l); - - @Override - public Optional validate(SlimefunItem item) { - if (item instanceof NotPlaceable || !item.getItem().getType().isBlock()) { - return Optional.of(new IncompatibleItemHandlerException("Only blocks that are not marked as 'NotPlaceable' can have a BlockTicker.", item, this)); - } - - if (item instanceof EnergyNetComponent && ((EnergyNetComponent) item).getEnergyComponentType() == EnergyNetComponentType.GENERATOR) { - return Optional.empty(); - } - - return Optional.of(new IncompatibleItemHandlerException("Only items that implement 'EnergyNetComponent' with the type 'GENERATOR' can have a GeneratorTicker.", item, this)); - } - - @Override - public Class getIdentifier() { - return GeneratorTicker.class; - } - -} diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockInfoConfig.java b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockInfoConfig.java index d3e4f14f3..5b525a1f2 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockInfoConfig.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockInfoConfig.java @@ -87,10 +87,6 @@ public class BlockInfoConfig extends Config { return data.keySet(); } - private UnsupportedOperationException invalidType(String path) { - return new UnsupportedOperationException("Can't get \"" + path + "\" because BlockInfoConfig only supports String values"); - } - @Override public int getInt(String path) { throw invalidType(path); @@ -121,6 +117,10 @@ public class BlockInfoConfig extends Config { throw invalidType(path); } + private UnsupportedOperationException invalidType(String path) { + return new UnsupportedOperationException("Can't get \"" + path + "\" because BlockInfoConfig only supports String values"); + } + @Override public File getFile() { throw new UnsupportedOperationException(); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java index c8900f942..b261a0b37 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java @@ -16,7 +16,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.bukkit.Bukkit; -import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.Block; @@ -151,40 +150,8 @@ public class BlockStorage { FileConfiguration cfg = YamlConfiguration.loadConfiguration(file); for (String key : cfg.getKeys(false)) { - Location l = deserializeLocation(key); - String chunkString = locationToChunkString(l); - - try { - totalBlocks++; - String json = cfg.getString(key); - Config blockInfo = parseBlockInfo(l, json); - - if (blockInfo != null && blockInfo.contains("id")) { - if (storage.containsKey(l)) { - // It should not be possible to have two blocks on the same location. Ignore the - // new entry if a block is already present and print an error to the console. - - Slimefun.getLogger().log(Level.INFO, "Ignoring duplicate block @ {0}, {1}, {2}", new Object[] { l.getBlockX(), l.getBlockY(), l.getBlockZ() }); - Slimefun.getLogger().log(Level.INFO, "New: {0} | Old: {1}", new Object[] { key, serializeBlockInfo(storage.get(l)) }); - continue; - } - - storage.put(l, blockInfo); - - if (SlimefunPlugin.getRegistry().getTickerBlocks().contains(file.getName().replace(".sfb", ""))) { - Set locations = SlimefunPlugin.getRegistry().getActiveTickers().getOrDefault(chunkString, new HashSet<>()); - locations.add(l); - SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations); - - if (!SlimefunPlugin.getRegistry().getActiveChunks().contains(chunkString)) { - SlimefunPlugin.getRegistry().getActiveChunks().add(chunkString); - } - } - } - } - catch (Exception x) { - Slimefun.getLogger().log(Level.WARNING, x, () -> "Failed to load " + file.getName() + '(' + key + ") for Slimefun " + SlimefunPlugin.getVersion()); - } + loadBlock(file, cfg, key); + totalBlocks++; } done++; @@ -202,6 +169,48 @@ public class BlockStorage { } } + private void loadBlock(File file, FileConfiguration cfg, String key) { + Location l = deserializeLocation(key); + + if (l == null) { + // That location was malformed, we will skip this one + return; + } + + try { + String chunkString = locationToChunkString(l); + String json = cfg.getString(key); + Config blockInfo = parseBlockInfo(l, json); + + if (blockInfo != null && blockInfo.contains("id")) { + if (storage.containsKey(l)) { + // It should not be possible to have two blocks on the same location. Ignore the + // new entry if a block is already present and print an error to the console. + if (SlimefunPlugin.getRegistry().logDuplicateBlockEntries()) { + Slimefun.getLogger().log(Level.INFO, "Ignoring duplicate block @ {0}, {1}, {2} ({3} -> {4})", new Object[] { l.getBlockX(), l.getBlockY(), l.getBlockZ(), blockInfo.getString("id"), storage.get(l).getString("id") }); + } + + return; + } + + storage.put(l, blockInfo); + + if (SlimefunPlugin.getRegistry().getTickerBlocks().contains(file.getName().replace(".sfb", ""))) { + Set locations = SlimefunPlugin.getRegistry().getActiveTickers().getOrDefault(chunkString, new HashSet<>()); + locations.add(l); + SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations); + + if (!SlimefunPlugin.getRegistry().getActiveChunks().contains(chunkString)) { + SlimefunPlugin.getRegistry().getActiveChunks().add(chunkString); + } + } + } + } + catch (Exception x) { + Slimefun.getLogger().log(Level.WARNING, x, () -> "Failed to load " + file.getName() + '(' + key + ") for Slimefun " + SlimefunPlugin.getVersion()); + } + } + private void loadChunks() { File chunks = new File(PATH_CHUNKS + "chunks.sfc"); @@ -211,7 +220,8 @@ public class BlockStorage { for (String key : cfg.getKeys(false)) { try { if (world.getName().equals(PatternUtils.SEMICOLON.split(key)[0])) { - SlimefunPlugin.getRegistry().getChunks().put(key, new BlockInfoConfig(parseJSON(cfg.getString(key)))); + BlockInfoConfig data = new BlockInfoConfig(parseJSON(cfg.getString(key))); + SlimefunPlugin.getRegistry().getChunks().put(key, data); } } catch (Exception x) { @@ -261,7 +271,7 @@ public class BlockStorage { } public void computeChanges() { - changes = blocksCache.size() + chunkChanges; + changes = blocksCache.size(); Map inventories2 = new HashMap<>(inventories); for (Map.Entry entry : inventories2.entrySet()) { @@ -278,21 +288,14 @@ public class BlockStorage { return changes; } - public void save(boolean remove) { - save(true, remove); - } - - public void save(boolean computeChanges, boolean remove) { - if (computeChanges) { - computeChanges(); - } + public void save() { + computeChanges(); if (changes == 0) { return; } - Slimefun.getLogger().log(Level.INFO, "Saving Blocks for World \"{0}\" ({1} Change(s) queued)", new Object[] { world.getName(), changes }); - + Slimefun.getLogger().log(Level.INFO, "Saving block data for world \"{0}\" ({1} change(s) queued)", new Object[] { world.getName(), changes }); Map cache = new HashMap<>(blocksCache); for (Map.Entry entry : cache.entrySet()) { @@ -324,41 +327,39 @@ public class BlockStorage { } } - Map inventories2 = new HashMap<>(inventories); - - for (Map.Entry entry : inventories2.entrySet()) { + Map unsavedInventories = new HashMap<>(inventories); + for (Map.Entry entry : unsavedInventories.entrySet()) { entry.getValue().save(entry.getKey()); } - Map universalInventories2 = new HashMap<>(SlimefunPlugin.getRegistry().getUniversalInventories()); - - for (Map.Entry entry : universalInventories2.entrySet()) { + Map unsavedUniversalInventories = new HashMap<>(SlimefunPlugin.getRegistry().getUniversalInventories()); + for (Map.Entry entry : unsavedUniversalInventories.entrySet()) { entry.getValue().save(); } - if (chunkChanges > 0) { - saveChunks(remove); - } - changes = 0; - chunkChanges = 0; } - private void saveChunks(boolean remove) { - File chunks = new File(PATH_CHUNKS + "chunks.sfc"); - Config cfg = new Config(PATH_CHUNKS + "chunks.temp"); + public void saveAndRemove() { + save(); + SlimefunPlugin.getRegistry().getWorlds().remove(world.getName()); + } - for (Map.Entry entry : SlimefunPlugin.getRegistry().getChunks().entrySet()) { - // Saving empty chunk data is pointless - if (!entry.getValue().getKeys().isEmpty()) { - cfg.setValue(entry.getKey(), entry.getValue().toJSON()); + public static void saveChunks() { + if (chunkChanges > 0) { + File chunks = new File(PATH_CHUNKS + "chunks.sfc"); + Config cfg = new Config(PATH_CHUNKS + "chunks.temp"); + + for (Map.Entry entry : SlimefunPlugin.getRegistry().getChunks().entrySet()) { + // Saving empty chunk data is pointless + if (!entry.getValue().getKeys().isEmpty()) { + cfg.setValue(entry.getKey(), entry.getValue().toJSON()); + } } - } - cfg.save(chunks); + cfg.save(chunks); - if (remove) { - SlimefunPlugin.getRegistry().getWorlds().remove(world.getName()); + chunkChanges = 0; } } @@ -381,6 +382,7 @@ public class BlockStorage { * * @param block * the block to retrieve the ItemStack from + * * @return the SlimefunItem's ItemStack corresponding to the block if it has one, otherwise null * * @since 4.0 @@ -424,6 +426,7 @@ public class BlockStorage { map.put(entry.getKey(), entry.getValue().getAsString()); } } + return map; } @@ -530,12 +533,14 @@ public class BlockStorage { } else if (!storage.hasInventory(l)) { File file = new File(PATH_INVENTORIES + serializeLocation(l) + ".sfi"); + BlockMenuPreset preset = BlockMenuPreset.getPreset(id); if (file.exists()) { - storage.inventories.put(l, new BlockMenu(BlockMenuPreset.getPreset(id), l, new io.github.thebusybiscuit.cscorelib2.config.Config(file))); + BlockMenu inventory = new BlockMenu(preset, l, new io.github.thebusybiscuit.cscorelib2.config.Config(file)); + storage.inventories.put(l, inventory); } else { - storage.loadInventory(l, BlockMenuPreset.getPreset(id)); + storage.loadInventory(l, preset); } } } @@ -573,7 +578,16 @@ public class BlockStorage { SlimefunPlugin.getTickerTask().queueDelete(l, destroy); } - public static void _integrated_removeBlockInfo(Location l, boolean destroy) { + /** + * Do not call this method!. + * This method is used for internal purposes only. + * + * @param l + * The {@link Location} + * @param destroy + * Whether to completely destroy the block data + */ + public static void deleteLocationInfoUnsafely(Location l, boolean destroy) { BlockStorage storage = getStorage(l.getWorld()); if (hasBlockInfo(l)) { @@ -614,7 +628,16 @@ public class BlockStorage { SlimefunPlugin.getTickerTask().queueMove(from, to); } - public static void _integrated_moveLocationInfo(Location from, Location to) { + /** + * Do not call this method!. + * This method is used for internal purposes only. + * + * @param from + * The origin {@link Location} + * @param to + * The destination {@link Location} + */ + public static void moveLocationInfoUnsafely(Location from, Location to) { if (!hasBlockInfo(from)) { return; } @@ -732,15 +755,11 @@ public class BlockStorage { } public static Set getTickingChunks() { - return new HashSet<>(SlimefunPlugin.getRegistry().getActiveChunks()); - } - - public static Set getTickingLocations(Chunk chunk) { - return getTickingLocations(chunk.toString()); + return SlimefunPlugin.getRegistry().getActiveChunks(); } public static Set getTickingLocations(String chunk) { - return new HashSet<>(SlimefunPlugin.getRegistry().getActiveTickers().get(chunk)); + return SlimefunPlugin.getRegistry().getActiveTickers().getOrDefault(chunk, new HashSet<>()); } public BlockMenu loadInventory(Location l, BlockMenuPreset preset) { @@ -769,7 +788,8 @@ public class BlockStorage { } public void loadUniversalInventory(BlockMenuPreset preset) { - SlimefunPlugin.getRegistry().getUniversalInventories().put(preset.getID(), new UniversalBlockMenu(preset)); + UniversalBlockMenu inventory = new UniversalBlockMenu(preset); + SlimefunPlugin.getRegistry().getUniversalInventories().put(preset.getID(), inventory); } public void clearInventory(Location l) { diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java b/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java index 22c1ebd9a..96df69a95 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java @@ -231,7 +231,7 @@ public class SlimefunItemStack extends CustomItem { throw new WrongItemStackException(id + " is not mutable."); } } - + public void lock() { locked = true; } @@ -250,6 +250,15 @@ public class SlimefunItemStack extends CustomItem { return Optional.ofNullable(texture); } + public String getDisplayName() { + if (immutableMeta == null) { + // Just to be extra safe + return null; + } + + return immutableMeta.getDisplayName().orElse(null); + } + private static ItemStack getSkull(String id, String texture) { if (SlimefunPlugin.getMinecraftVersion() == MinecraftVersion.UNIT_TEST) { return new ItemStack(Material.PLAYER_HEAD); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenu.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenu.java index 8ba89e051..5a93f61c0 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenu.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenu.java @@ -7,6 +7,7 @@ import java.util.logging.Level; import org.bukkit.Location; import org.bukkit.block.Block; +import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.config.Config; import me.mrCookieSlime.Slimefun.api.Slimefun; @@ -80,13 +81,32 @@ public class BlockMenu extends DirtyChestMenu { } public Block getBlock() { - return this.location.getBlock(); + return location.getBlock(); } public Location getLocation() { return location; } + /** + * This method drops the contents of this {@link BlockMenu} on the ground at the given + * {@link Location}. + * + * @param l + * Where to drop these items + * @param slots + * The slots of items that should be dropped + */ + public void dropItems(Location l, int... slots) { + for (int slot : slots) { + ItemStack item = getItemInSlot(slot); + if (item != null) { + l.getWorld().dropItemNaturally(l, item); + replaceExistingItem(slot, null); + } + } + } + public void delete(Location l) { File file = new File("data-storage/Slimefun/stored-inventories/" + serializeLocation(l) + ".sfi"); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index eca44c177..35b9a48da 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -3,7 +3,7 @@ options: # These builds are much more tested and are far less likely to have any issues. # Note: When running a stable build auto-updates ONLY update to other stable builds! Perfect eh? # You can download the latest stable build here: https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/ - + auto-update: true backwards-compatibility: true chat-prefix: '&a&lSlimefun 4&7> ' @@ -16,12 +16,14 @@ options: legacy-ore-grinder: true language: en enable-translations: true - + log-duplicate-block-entries: true + burn-players-when-radioactive: true + guide: default-view-book: false show-vanilla-recipes: true receive-on-first-join: true - + researches: free-in-creative-mode: true enable-fireworks: true diff --git a/src/main/resources/languages/categories_en.yml b/src/main/resources/languages/categories_en.yml index 5b660c4c0..091a89b7e 100644 --- a/src/main/resources/languages/categories_en.yml +++ b/src/main/resources/languages/categories_en.yml @@ -22,4 +22,4 @@ slimefun: valentines_day: 'Valentine''s Day (14th February)' easter: 'Easter (April)' birthday: 'TheBusyBiscuit''s birthday (26th October)' - halloween: 'Halloween (31st October)' \ No newline at end of file + halloween: 'Halloween (31st October)' diff --git a/src/main/resources/languages/categories_it.yml b/src/main/resources/languages/categories_it.yml index 3bd8af1ad..5cf7858ad 100644 --- a/src/main/resources/languages/categories_it.yml +++ b/src/main/resources/languages/categories_it.yml @@ -1,25 +1,26 @@ --- slimefun: - basic_machines: Macchine Base - birthday: Compleanno di TheBusyBiscuit (26 ottobre) - cargo: Gestione Cargo - christmas: Natale (dicembre) - easter: Pasqua (aprile) - electricity: Energia ed Elettricità - ender_talismans: Talismani dell'End (Livello II) - food: Cibo - gps: Macchine a GPS - halloween: Halloween (31 ottobre) - items: Oggetti Utili - magical_gadgets: Gadget Magici - magical_items: Oggetti Magici - misc: Oggetti Misti - resources: Risorse - talismans: Talismani (Livello I) - tech_misc: Componenti Tecnici - technical_gadgets: Gadget Tecnici - tools: Utensili - valentines_day: San Valentino (14 febbraio) weapons: Armi + tools: Utensili + items: Oggetti Utili + food: Cibo + basic_machines: Macchinari Base + electricity: Energia ed Elettricità + gps: Macchine basate sul GPS armor: Armature + magical_items: Oggetti Magici + magical_gadgets: Gadget Magici + misc: Oggetti Vari + technical_gadgets: Gadget Tecnologici + resources: Risorse + cargo: Gestione Cargo + tech_misc: Componenti Tecnologici magical_armor: Armature Magiche + talismans: Talismani (Livello I) + ender_talismans: Talismani dell'End (Livello II) + christmas: Natale (dicembre) + valentines_day: San Valentino (14 febbraio) + easter: Pasqua (aprile) + birthday: Compleanno di TheBusyBiscuit (26 ottobre) + halloween: Halloween (31 ottobre) + androids: Androidi Programmabili diff --git a/src/main/resources/languages/messages_de.yml b/src/main/resources/languages/messages_de.yml index 592183a08..7027ecd20 100644 --- a/src/main/resources/languages/messages_de.yml +++ b/src/main/resources/languages/messages_de.yml @@ -1,66 +1,19 @@ --- -android: - scripts: - already-uploaded: "&4Dieses Skript wurde bereits hochgeladen." - editor: Skripteditor - enter-name: - - - - "&eBitte gebe einen Namen für dein Skript ins Chatfenster ein" - instructions: - ATTACK_ANIMALS: "&4Angreifen &c(Nur Tiere)" - ATTACK_ANIMALS_ADULT: "&4Angreifen &c(Nur ausgewachsene Tiere)" - ATTACK_MOBS: "&4Angreifen &c(Nur Monster)" - ATTACK_MOBS_ANIMALS: "&4Angreifen &c(Monster & Tiere)" - CATCH_FISH: "&bAngeln" - CHOP_TREE: "&cBaum fällen und nachpflanzen" - DIG_DOWN: "&bGrabe nach unten" - DIG_FORWARD: "&bGrabe vorwärts" - DIG_UP: "&bGrabe nach oben" - FARM_DOWN: "&bErnten und Nachpflanzen &7(Unterer Block)" - FARM_EXOTIC_DOWN: "&bErnten und Nachpflanzen (Fortgeschritten und unterer Block)" - FARM_EXOTIC_FORWARD: "&bErnten und Nachpflanzen (Fortgeschritten)" - FARM_FORWARD: "&bErnten und Nachpflanzen" - GO_DOWN: "&7Gehe nach unten" - GO_FORWARD: "&7Gehe vorwärts" - GO_UP: "&7Gehe nach oben" - INTERFACE_FUEL: "&cTreibstoff aus dem vorliegenden Interface nehmen" - INTERFACE_ITEMS: "&9Items ins vorliegende Interface bewegen" - MOVE_AND_DIG_DOWN: "&bGehe & Grabe nach unten" - MOVE_AND_DIG_FORWARD: "&bGehe & Grabe vorwärts" - MOVE_AND_DIG_UP: "&bGehe & Grabe nach oben" - REPEAT: "&9Neubeginn des Skripts" - START: "&2Start des Skripts" - TURN_LEFT: "&7Drehung nach links" - TURN_RIGHT: "&7Drehung nach rechts" - WAIT: "&eWarte 0.5 Sekunden" - rating: - already: "&4Du hast dieses Skript bereits bewertet!" - own: "&4Du kannst nicht dein eigenes Skript bewerten!" - uploaded: - - "&bLade dein Skript hoch..." - - "&aDein Skript wurde erfolgreich hochgeladen!" - started: "&7Dein Android hat sein Skript fortgesetzt" - stopped: "&7Dein Android hat sein Skript pausiert" -anvil: - not-working: "&4Items von Slimefun können nicht in einem Amboss verwendet werden!" -backpack: - already-open: "&cDieser Rucksack wird derzeit von jemand anderem benutzt!" - no-stack: "&cRucksäcke dürfen nicht gestapelt werden" commands: + help: Zeigt diesen Infotext an cheat: Ermöglicht das Cheaten von Items give: Gibt jemandem ein bestimmtes Item guide: Gibt dir das Slimefun-Handbuch - help: Zeigt diesen Infotext an + timings: Zeigt einige Informationen über die Performance + teleporter: Erlaubt es dir Wegpunkte anderer Spieler anzusehen + versions: Eine Liste aller installierter Addons + search: Durchsucht dein Slimefun-Handbuch nach einem Begriff open_guide: Öffnet das Slimefun-Handbuch + stats: Zeigt einige Statistiken über einen Spieler research: description: Verändert den Erfahrungsgrad eines Spielers reset: "&cDu hast soeben %player%'s Erfahrungsgrad zurückgesetzt" reset-target: "&cDein Erfahrungsgrad wurde zurückgesetzt" - search: Durchsucht dein Slimefun-Handbuch nach einem Begriff - stats: Zeigt einige Statistiken über einen Spieler - teleporter: Erlaubt es dir Wegpunkte anderer Spieler anzusehen - timings: Zeigt einige Informationen über die Performance - versions: Eine Liste aller installierter Addons backpack: description: Gibt eine Kopie eines existierenden Rucksacks invalid-id: "&4Die id muss eine nicht-negative ganze Zahl sein!" @@ -68,184 +21,133 @@ commands: backpack-does-not-exist: "&4Der angegebene Rucksack konnte nicht gefunden werden!" restored-backpack-given: "&aDein Rucksack wurde erfolgreich wiederhergestellt und deinem Inventar hinzugefügt!" -gps: - deathpoint: "&4Todespunkt &7%date%" - geo: - scan-required: "&4GEO-Scan benötigt! &cScanne diesen Chunk mit einem GEO-Scanner!" - insufficient-complexity: - - "&4Unzureichende Komplexität deines GPS-Netzwerkes! Folgende Komplexität wird - benötigt: &c%complexity%" - - "&4a) Vielleicht hast du gar kein GPS-Netzwerk" - - "&4b) Oder dein GPS-Netzwerk ist nicht komplex genug" - waypoint: - added: "&aEin neuer Wegpunkt wurde hinzugefügt" - max: "&4Du hast die maximale Anzahl an Wegpunkten erreicht" - new: "&eBitte gebe ins Chatfenser einen Namen für deinen Wegpunkt ein. &7(Farbcodes - werden unterstützt!)" guide: - back: - guide: Gehe zurück zum Slimefun-Handbuch - settings: Gehe zurück zu den Einstellungen - title: Zurück + search: + message: "&bWonach möchtest du suchen?" + name: "&7Suche..." + tooltip: "&bKlicke um die Suche zu starten" + inventory: 'Suche nach: %item%' + lore: + - "&bWonach möchtest du suchen?" + - "&7Gib den Begriff, nach dem du suchen willst, in das Chatfenster ein" cheat: no-multiblocks: "&4Multiblöcke müssen gebaut werden! Du kannst dir diese nicht geben." - credits: - commit: Beitrag - commits: Beiträge - profile-link: Klick um mich auf GitHub zu sehen - roles: - developer: "&6Entwickler" - resourcepack: "&cRessourcenpaket-Designer" - translator: "&9Übersetzer" - wiki: "&3Wiki-Editor" languages: + updated: "&aFolgende Sprache wurde ausgewählt: &b%lang%" + translations: + name: "&aFehlt etwas?" + lore: Klicke um eine Übersetzung hinzuzufügen select: Klicke hier um diese Sprache auszuwählen select-default: Klicke hier um die Standardsprache auszuwählen selected-language: 'Aktuell ausgewählt:' - translations: - lore: Klicke um eine Übersetzung hinzuzufügen - name: "&aFehlt etwas?" - updated: "&aFolgende Sprache wurde ausgewählt: &b%lang%" + change: Klicke um die Sprache zu ändern + description: + - "&7Hier kannst du deine Spracheinstellungen" + - "&7verwalten. Derzeit umfasst dies" + - "&7jedoch nur bestimmte Nachrichten," + - "&7Items können noch nicht übersetzt werden." + title: + main: Slimefun-Handbuch + settings: Einstellungen & Infos + languages: Wähle deine bevorzugte Sprache + credits: 'Slimefun4: Mitwirkende' + wiki: Slimefun4-Wiki + addons: Addons für Slimefun4 + bugs: Fehlermeldungen + source: Quellcode + versions: Installierte Versionen + credits: + commit: Beitrag + commits: Beiträge + roles: + developer: "&6Entwickler" + wiki: "&3Wiki-Editor" + resourcepack: "&cRessourcenpaket-Designer" + translator: "&9Übersetzer" + profile-link: Klick um mich auf GitHub zu sehen + open: Klicke um Mitwirkende zu sehen + description: + - "&7Slimefun ist ein Open-Source Projekt" + - "&7und wird von einer riesigen Community entwickelt." + - "&7Über &e%contributors% &7Personen haben bereits" + - "&7an Slimefun mitgewirkt." + pages: + previous: Vorherige Seite + next: Nächste Seite + tooltips: + open-category: Klicke zum Öffnen + versions-notice: Dies ist sehr wichtig bei Fehlermeldungen! + wiki: Besuche das offizielle Slimefun-Wiki + recipes: + machine: Rezepte dieser Maschine + miner: Ressourcen, die mit dieser Maschine gewonnen werden können + generator: Mögliche Treibstoffquellen + gold-pan: Ressourcen, die hiermit gewonnen werden können + back: + title: Zurück + guide: Gehe zurück zum Slimefun-Handbuch + settings: Gehe zurück zu den Einstellungen locked: GESPERRT locked-category: - Um diese Kategorie freizuschalten, - müssen zuerst sämtliche Items der - folgenden Kategorien freigeschaltet werden - pages: - next: Nächste Seite - previous: Vorherige Seite - search: - inventory: 'Suche nach: %item%' - lore: - - "&bWonach möchtest du suchen?" - - "&7Gib den Begriff, nach dem du suchen willst, in das Chatfenster ein" - message: "&bWonach möchtest du suchen?" - name: "&7Suche..." - tooltip: "&bKlicke um die Suche zu starten" - title: - addons: Addons für Slimefun4 - bugs: Fehlermeldungen - credits: 'Slimefun4: Mitwirkende' - languages: Wähle deine bevorzugte Sprache - main: Slimefun-Handbuch - settings: Einstellungen & Infos - source: Quellcode - wiki: Slimefun4-Wiki - tooltips: - open-category: Klicke zum Öffnen - recipes: - generator: Mögliche Treibstoffquellen - gold-pan: Ressourcen, die hiermit gewonnen werden können - machine: Rezepte dieser Maschine - miner: Ressourcen, die mit dieser Maschine gewonnen werden können - versions-notice: Dies ist sehr wichtig bei Fehlermeldungen! - wiki: Besuche das offizielle Slimefun-Wiki -inventory: - no-access: "&4Du kannst nicht auf diesen Block zugreifen" -languages: - af: Afrikaans - ar: Arabisch - be: Belarusisch - bg: Bulgarisch - cs: Tschechisch - da: Dänisch - de: Deutsch - default: Server-Standard - el: Griechisch - en: Englisch - es: Spanisch - fa: Persisch - fi: Finnisch - fr: Französisch - he: Hebräisch - hr: Kroatisch - hu: Ungarisch - id: Indonesisch - it: Italienisch - ja: Japanisch - ko: Koreanisch - lv: Lettisch - mk: Mazedonisch - ms: Malaiisch - nl: Niederländisch - 'no': Norwegisch - pl: Polnisch - pt: Portugiesisch (Portugal) - pt-BR: Portugiesisch (Brasilien) - ro: Rumänisch - ru: Russisch - sk: Slowakisch - sr: Serbisch - sv: Schwedisch - th: Thailändisch - tr: Türkisch - uk: Ukrainisch - vi: Vietnamesisch - zh-CN: Chinesisch (China) - zh-TW: Chinesisch (Taiwan) -machines: - ANCIENT_ALTAR: - not-enough-pedestals: "&4Es fehlen einige Sockel des Altars &c(%pedestals% / 8)" - unknown-catalyst: "&4Unbekannter Katalysator!" - unknown-recipe: "&4Unbekanntes Rezept!" - ANCIENT_PEDESTAL: - obstructed: "&4Der Sockel wurde blockiert! &cBitte entferne den Block über jedem - jedem Sockel!" - CARGO_NODES: - must-be-placed: "&4Dieser Block muss an die Seite einer Maschine oder Kiste platziert - werden!" - ELEVATOR: - click-to-teleport: "&eKlicke hier &7um zu dieser Etage zu teleportieren:" - current-floor: "&eDeine aktuelle Etage:" - enter-name: "&7Bitte gebe ins Chatfenser einen Namen für diese Etage ein. &r(Farbcodes - werden unterstützt!)" - named: '&2Diese Etage wurde erfolgreich &r"%floor%&r" &2genannt' - no-destinations: "&4Es konnten keine weiteren Etagen gefunden werden" - pick-a-floor: "&3- Wähle eine Etage -" - full-inventory: "&eDieses Inventar ist bereits voll!" - GPS_CONTROL_PANEL: - title: GPS - Kontrolltafel - transmitters: Satelliten-Übersicht - waypoints: Wegpunkte-Übersicht - HOLOGRAM_PROJECTOR: - enter-text: "&7Bitte gebe ins Chatfenser einen Text für dieses Hologram ein. &r(Farbcodes - werden unterstützt!)" - inventory-title: Hologrammeditor - ignition-chamber-no-flint: "&cAlle Feuerzeuge wurden aufgebraucht!" - in-use: "&cDiese Maschine wird derzeit von einem anderen Spieler verwendet." - pattern-not-found: "&eEs tut mir leid, aber ich konnte kein passendes Rezept finden." - TELEPORTER: - cancelled: "&4Teleportation abgebrochen!" - gui: - time: Voraussichtliche Dauer - title: Deine Wegpunkte - tooltip: Klicke zum teleportieren - invulnerability: "&b&lDu bist nun für 30 Sekunden unverwundbar!" - teleported: "&3Erfolgreich teleportiert!" - teleporting: "&3Du wirst teleportiert..." - unknown-material: "&eEs tut mir leid, aber ich erkenne das Item in meinem Werfer - nicht, probier ein anderes Item aus." - wrong-item: "&eEs tut mir leid, aber ich erkenne das Item in deiner Hand nicht, - probier ein anderes Item aus." - INDUSTRIAL_MINER: - no-fuel: "&cDein Industrial Miner hat keinen Treibstoff mehr! Platziere den benötigten - Treibstoff in die Kiste." - piston-facing: "&cEinIndustrial Miner erfordert Kolben, die nach oben zeigen!" - piston-space: "&cDie Blöcke über den Kolben müssen leer bleiben!" - destroyed: "&cDein Industrial Miner scheint zerstört worden zu sein." - already-running: "&cDieser Industrial Miner wird bereits verwendet!" - full-chest: "&cDie Kiste deines Industrial Miner ist vollgelaufen!" - no-permission: "&4Du scheinst nicht die benötigten Rechte zu haben, um in diesem - Gebiet einen Industrial Miner zu verwenden." - finished: "&eDein Industrial Miner ist fertig! Es wurde(n) insgesamt %ores% Erz(e) - gefunden!" + work-in-progress: Dieses Feature befindet sich noch in der Testphase! messages: - cannot-place: "&cDu kannst hier keine Blöcke platzieren!" - diet-cookie: "&eDu beginnst dich sehr leicht zu fühlen..." + not-researched: "&4Du hast diesen Gegenstand noch nicht freigeschaltet!" + not-enough-xp: "&4Du hast nicht genügend Erfahrungspunkte, um dies freizuschalten" + unlocked: '&bDu hast folgenden Erfahrungsgrad gewonnen: &7"%research%"' + only-players: "&4Dieser Befehl ist nur für Spieler" + unknown-player: "&4Unbekannter Spieler: &c%player%" + no-permission: "&4Du hast nicht die benötigten Rechte hierfür" + usage: "&4Korrekte Schreibweise: &c%usage%" + not-online: "&4%player% &cist derzeit nicht online!" + not-valid-item: "&4%item% &cist kein gültiges Item!" + not-valid-amount: "&4%amount% &cist keine gültige Anzahl! Sie muss höher als 0 sein!" + given-item: '&bDir wurde &a%amount% &7mal "%item%&7" gegeben' + give-item: '&bDu hast %player% &a%amount% &7"%item%&7" gegeben' + not-valid-research: "&4%research% &cist kein gültiger Erfahrungsgrad!" + give-research: '&bDu hast %player% den Erfahrungsgrad &7"%research%&7" vergeben' + hungry: "&cDu bist zu hungrig, um dies zu tun!" disabled-in-world: "&4&lDieses Item wurde in dieser Welt deaktiviert!" disabled-item: "&4&lDieses Item wurde von einem Server-Administrator deaktiviert!" + no-tome-yourself: "&cDu kannst dieses Item nicht an dir selbst anwenden..." + multimeter: "&bGespeicherte Energie: &3%stored% &b/ &3%capacity%" + talisman: + anvil: "&a&oDein Talisman hat dein Werkzeug vor dem Zerfall gerettet" + miner: "&a&oDein Talisman hat soeben die Drops verdoppelt" + hunter: "&a&oDein Talisman hat soeben die Drops verdoppelt" + lava: "&a&oDein Talisman hat dich vor dem Verbrennen gerettet" + water: "&a&oDein Talisman hat dich vor dem Ertrinken gerettet" + angel: "&a&oDein Talisman hat dich davor bewahrt Fallschaden zu erleiden" + fire: "&a&oDein Talisman hat dich vor dem Verbrennen gerettet" + magician: "&a&oDein Talisman hat dir eine zusätzliche Verzauberung verliehen" + traveller: "&a&oDein Talisman hat dir einen Geschwindigkeitsboost gegeben" + warrior: "&a&oDein Talisman hat dir einen temporären Stärkebonus gegeben" + knight: "&a&oDein Talisman hat dir 5 Sekunden Regeneration gegeben" + whirlwind: "&a&oDein Talisman hat soeben ein Projektil reflektiert" + wizard: "&a&oDein Talisman hat dein Glück-Level erhöht aber möglicherweise das + Level einer anderen Verzauberung vermindert" + soulbound-rune: + fail: "&cDu kannst nicht mehrere Items auf einmal an deine Seele binden" + success: "&aDu hast dieses Item erfolgreich an deine Seele gebunden! Solltest + du sterben, wirst du es nun behalten." + research: + start: "&7Mysteriöse Worte flüstert man dir in dein Ohr!" + progress: "&7Du beginnst über &b%research% &7nachzudenken &e(%progress%)" fire-extinguish: "&7Das Feuer wurde erfolgreich gelöscht" + cannot-place: "&cDu kannst hier keine Blöcke platzieren!" + no-pvp: "&cDu kannst andere Spieler hier nicht verletzen!" + radiation: "&4Du wurdest radioaktiver Strahlung ausgesetzt! &cZiehe einen vollständigen + Hazmat Suit an oder werde das radioaktive Item schnleunigst los!" + opening-guide: "&bÖffne dein Handbuch, dies kann eventuell ein paar Sekunden dauern..." + opening-backpack: "&bÖffne deinen Rucksack, dies kann eventuell ein paar Sekunden + dauern..." + no-iron-golem-heal: "&cDas ist kein Eisenbarren. Du kannst dieses Item nicht verwenden + um Eisengolems zu reparieren!" + link-prompt: "&eKlicke hier:" + diet-cookie: "&eDu beginnst dich sehr leicht zu fühlen..." fortune-cookie: - "&7Hilfe, ich bin in einer Glückskeks-Fabrik gefangen!" - "&7Morgen könntest du sterben... durch einen Creeper" @@ -259,56 +161,193 @@ messages: - "&742. Die Antwort ist 42." - "&7Ein Walshy am Tag, hält die Sorgen fern. (Insiderwitz)" - "&7Grabe niemals direkt nach unten!" - give-item: '&bDu hast %player% &a%amount% &7"%item%&7" gegeben' - given-item: '&bDir wurde &a%amount% &7mal "%item%&7" gegeben' - give-research: '&bDu hast %player% den Erfahrungsgrad &7"%research%&7" vergeben' - hungry: "&cDu bist zu hungrig, um dies zu tun!" - link-prompt: "&eKlicke hier:" + - "&7Das ist nur ein Kratzer!" + - "&7Always look on the bright side of life!" + - "&7Ist das jetzt ein Keks, Cookie oder ein Biscuit?" + - "&7Jetzt auch zuckerfrei!" + piglin-barter: "&4Du kannst Piglins keine Slimefun-Gegenständen anbieten!" + enchantment-rune: + fail: "&cDieser Gegenstand kann nicht verzaubert werden" + no-enchantment: "&cEs konnten keine gültigen Verzauberungen für diesen Gegenstand + gefunden werden" + success: "&aDieser Gegenstand wurde erfolgreich mit einer zufälligen Verzauberung + aufgebessert!" + tape-measure: + no-anchor: "&cDu musst zuerst einen Ankerpunkt setzen bevor du messen kannst!" + wrong-world: "&cDein Ankerpunkt scheint sich in einer anderen Dimension zu befinden!" + distance: "&7Messung erfolgreich. &eDistanz: %distance%" + anchor-set: "&aErfolgreich den Ankerpunkt gesetzt:&e %anchor%" + multi-tool: + mode-change: "&bDer Modus von deinem Multi-Tool wurde geändert zu: &9%mode%" + not-shears: "&cEinMulti Tool kann nicht als Schere verwendet werden!" mode-change: "&bDer Modus von deinem %device% wurde geändert zu: &9%mode%" - multimeter: "&bGespeicherte Energie: &3%stored% &b/ &3%capacity%" - no-iron-golem-heal: "&cDas ist kein Eisenbarren. Du kannst dieses Item nicht verwenden - um Eisengolems zu reparieren!" - no-permission: "&4Du hast nicht die benötigten Rechte hierfür" - no-pvp: "&cDu kannst andere Spieler hier nicht verletzen!" - not-enough-xp: "&4Du hast nicht genügend Erfahrungspunkte, um dies freizuschalten" - no-tome-yourself: "&cDu kannst dieses Item nicht an dir selbst anwenden..." - not-online: "&4%player% &cist derzeit nicht online!" - not-researched: "&4Du hast diesen Gegenstand noch nicht freigeschaltet!" - not-valid-amount: "&4%amount% &cist keine gültige Anzahl! Sie muss höher als 0 sein!" - not-valid-item: "&4%item% &cist kein gültiges Item!" - not-valid-research: "&4%research% &cist kein gültiger Erfahrungsgrad!" - only-players: "&4Dieser Befehl ist nur für Spieler" - opening-backpack: "&bÖffne deinen Rucksack, dies kann eventuell ein paar Sekunden - dauern..." - opening-guide: "&bÖffne dein Handbuch, dies kann eventuell ein paar Sekunden dauern..." - radiation: "&4Du wurdest radioaktiver Strahlung ausgesetzt! &cZiehe einen vollständigen - Hazmat Suit an oder werde das radioaktive Item schnleunigst los!" - research: - progress: "&7Du beginnst über &b%research% &7nachzudenken &e(%progress%)" - start: "&7Mysteriöse Worte flüstert man dir in dein Ohr!" - soulbound-rune: - fail: "&cDu kannst nicht mehrere Items auf einmal an deine Seele binden" - success: "&aDu hast dieses Item erfolgreich an deine Seele gebunden! Solltest - du sterben, wirst du es nun behalten." - talisman: - angel: "&a&oDein Talisman hat dich davor bewahrt Fallschaden zu erleiden" - anvil: "&a&oDein Talisman hat dein Werkzeug vor dem Zerfall gerettet" - fire: "&a&oDein Talisman hat dich vor dem Verbrennen gerettet" - hunter: "&a&oDein Talisman hat soeben die Drops verdoppelt" - knight: "&a&oDein Talisman hat dir 5 Sekunden Regeneration gegeben" - lava: "&a&oDein Talisman hat dich vor dem Verbrennen gerettet" - magician: "&a&oDein Talisman hat dir eine zusätzliche Verzauberung verliehen" - miner: "&a&oDein Talisman hat soeben die Drops verdoppelt" - traveller: "&a&oDein Talisman hat dir einen Geschwindigkeitsboost gegeben" - warrior: "&a&oDein Talisman hat dir einen temporären Stärkebonus gegeben" - water: "&a&oDein Talisman hat dich vor dem Ertrinken gerettet" - whirlwind: "&a&oDein Talisman hat soeben ein Projektil reflektiert" - wizard: "&a&oDein Talisman hat dein Glück-Level erhöht aber möglicherweise das - Level einer anderen Verzauberung vermindert" - unknown-player: "&4Unbekannter Spieler: &c%player%" - unlocked: '&bDu hast folgenden Erfahrungsgrad gewonnen: &7"%research%"' - usage: "&4Korrekte Schreibweise: &c%usage%" -miner: - no-ores: "&eIch konnte leider keine Erze in der Nähe finden!" +machines: + pattern-not-found: "&eEs tut mir leid, aber ich konnte kein passendes Rezept finden." + unknown-material: "&eEs tut mir leid, aber ich erkenne das Item in meinem Werfer + nicht, probier ein anderes Item aus." + wrong-item: "&eEs tut mir leid, aber ich erkenne das Item in deiner Hand nicht, + probier ein anderes Item aus." + full-inventory: "&eDieses Inventar ist bereits voll!" + in-use: "&cDiese Maschine wird derzeit von einem anderen Spieler verwendet." + ignition-chamber-no-flint: "&cAlle Feuerzeuge wurden aufgebraucht!" + ANCIENT_ALTAR: + not-enough-pedestals: "&4Es fehlen einige Sockel des Altars &c(%pedestals% / 8)" + unknown-catalyst: "&4Unbekannter Katalysator!" + unknown-recipe: "&4Unbekanntes Rezept!" + ANCIENT_PEDESTAL: + obstructed: "&4Der Sockel wurde blockiert! &cBitte entferne den Block über jedem + jedem Sockel!" + HOLOGRAM_PROJECTOR: + enter-text: "&7Bitte gebe ins Chatfenser einen Text für dieses Hologram ein. &r(Farbcodes + werden unterstützt!)" + inventory-title: Hologrammeditor + ELEVATOR: + no-destinations: "&4Es konnten keine weiteren Etagen gefunden werden" + pick-a-floor: "&3- Wähle eine Etage -" + current-floor: "&eDeine aktuelle Etage:" + click-to-teleport: "&eKlicke hier &7um zu dieser Etage zu teleportieren:" + enter-name: "&7Bitte gebe ins Chatfenser einen Namen für diese Etage ein. &r(Farbcodes + werden unterstützt!)" + named: '&2Diese Etage wurde erfolgreich &r"%floor%&r" &2genannt' + TELEPORTER: + teleporting: "&3Du wirst teleportiert..." + teleported: "&3Erfolgreich teleportiert!" + cancelled: "&4Teleportation abgebrochen!" + invulnerability: "&b&lDu bist nun für 30 Sekunden unverwundbar!" + gui: + title: Deine Wegpunkte + tooltip: Klicke zum teleportieren + time: Voraussichtliche Dauer + CARGO_NODES: + must-be-placed: "&4Dieser Block muss an die Seite einer Maschine oder Kiste platziert + werden!" + GPS_CONTROL_PANEL: + title: GPS - Kontrolltafel + transmitters: Satelliten-Übersicht + waypoints: Wegpunkte-Übersicht + INDUSTRIAL_MINER: + no-fuel: "&cDein Industrial Miner hat keinen Treibstoff mehr! Platziere den benötigten + Treibstoff in die Kiste." + piston-facing: "&cEinIndustrial Miner erfordert Kolben, die nach oben zeigen!" + piston-space: "&cDie Blöcke über den Kolben müssen leer bleiben!" + destroyed: "&cDein Industrial Miner scheint zerstört worden zu sein." + already-running: "&cDieser Industrial Miner wird bereits verwendet!" + full-chest: "&cDie Kiste deines Industrial Miner ist vollgelaufen!" + no-permission: "&4Du scheinst nicht die benötigten Rechte zu haben, um in diesem + Gebiet einen Industrial Miner zu verwenden." + finished: "&eDein Industrial Miner ist fertig! Es wurde(n) insgesamt %ores% Erz(e) + gefunden!" +anvil: + not-working: "&4Items von Slimefun können nicht in einem Amboss verwendet werden!" +backpack: + already-open: "&cDieser Rucksack wird derzeit von jemand anderem benutzt!" + no-stack: "&cRucksäcke dürfen nicht gestapelt werden" workbench: not-enhanced: "&4Dieses Item kann nicht in einer normalen Werkbank genutzt werden" +gps: + deathpoint: "&4Todespunkt &7%date%" + waypoint: + new: "&eBitte gebe ins Chatfenser einen Namen für deinen Wegpunkt ein. &7(Farbcodes + werden unterstützt!)" + added: "&aEin neuer Wegpunkt wurde hinzugefügt" + max: "&4Du hast die maximale Anzahl an Wegpunkten erreicht" + duplicate: "&4Es existiert bereits ein Wegpunkt mit folgendem Namen: &f%waypoint%" + insufficient-complexity: + - "&4Unzureichende Komplexität deines GPS-Netzwerkes! Folgende Komplexität wird + benötigt: &c%complexity%" + - "&4a) Vielleicht hast du gar kein GPS-Netzwerk" + - "&4b) Oder dein GPS-Netzwerk ist nicht komplex genug" + geo: + scan-required: "&4GEO-Scan benötigt! &cScanne diesen Chunk mit einem GEO-Scanner!" +inventory: + no-access: "&4Du kannst nicht auf diesen Block zugreifen" +android: + started: "&7Dein Android hat sein Skript fortgesetzt" + stopped: "&7Dein Android hat sein Skript pausiert" + scripts: + already-uploaded: "&4Dieses Skript wurde bereits hochgeladen." + instructions: + START: "&2Start des Skripts" + REPEAT: "&9Neubeginn des Skripts" + WAIT: "&eWarte 0.5 Sekunden" + GO_FORWARD: "&7Gehe vorwärts" + GO_UP: "&7Gehe nach oben" + GO_DOWN: "&7Gehe nach unten" + TURN_LEFT: "&7Drehung nach links" + TURN_RIGHT: "&7Drehung nach rechts" + DIG_UP: "&bGrabe nach oben" + DIG_FORWARD: "&bGrabe vorwärts" + DIG_DOWN: "&bGrabe nach unten" + MOVE_AND_DIG_UP: "&bGehe & Grabe nach oben" + MOVE_AND_DIG_FORWARD: "&bGehe & Grabe vorwärts" + MOVE_AND_DIG_DOWN: "&bGehe & Grabe nach unten" + ATTACK_MOBS_ANIMALS: "&4Angreifen &c(Monster & Tiere)" + ATTACK_MOBS: "&4Angreifen &c(Nur Monster)" + ATTACK_ANIMALS: "&4Angreifen &c(Nur Tiere)" + ATTACK_ANIMALS_ADULT: "&4Angreifen &c(Nur ausgewachsene Tiere)" + CHOP_TREE: "&cBaum fällen und nachpflanzen" + CATCH_FISH: "&bAngeln" + FARM_FORWARD: "&bErnten und Nachpflanzen" + FARM_DOWN: "&bErnten und Nachpflanzen &7(Unterer Block)" + FARM_EXOTIC_FORWARD: "&bErnten und Nachpflanzen (Fortgeschritten)" + FARM_EXOTIC_DOWN: "&bErnten und Nachpflanzen (Fortgeschritten und unterer Block)" + INTERFACE_ITEMS: "&9Items ins vorliegende Interface bewegen" + INTERFACE_FUEL: "&cTreibstoff aus dem vorliegenden Interface nehmen" + enter-name: + - + - "&eBitte gebe einen Namen für dein Skript ins Chatfenster ein" + uploaded: + - "&bLade dein Skript hoch..." + - "&aDein Skript wurde erfolgreich hochgeladen!" + rating: + own: "&4Du kannst nicht dein eigenes Skript bewerten!" + already: "&4Du hast dieses Skript bereits bewertet!" + editor: Skripteditor +languages: + default: Server-Standard + en: Englisch + de: Deutsch + fr: Französisch + it: Italienisch + es: Spanisch + pl: Polnisch + sv: Schwedisch + nl: Niederländisch + cs: Tschechisch + hu: Ungarisch + lv: Lettisch + ru: Russisch + sk: Slowakisch + zh-TW: Chinesisch (Taiwan) + vi: Vietnamesisch + id: Indonesisch + zh-CN: Chinesisch (China) + el: Griechisch + he: Hebräisch + pt: Portugiesisch (Portugal) + pt-BR: Portugiesisch (Brasilien) + ar: Arabisch + af: Afrikaans + da: Dänisch + fi: Finnisch + uk: Ukrainisch + ms: Malaiisch + 'no': Norwegisch + ja: Japanisch + fa: Persisch + th: Thailändisch + ro: Rumänisch + bg: Bulgarisch + ko: Koreanisch + tr: Türkisch + hr: Kroatisch + mk: Mazedonisch + sr: Serbisch + be: Belarusisch + tl: Tagalog +brewing_stand: + not-working: "&4Items von Slimefun können nicht zum Brauen verwendet werden!" +villagers: + no-trading: "&4Items von Slimefun können nicht zum Handeln verwendet werden!" +miner: + no-ores: "&eIch konnte leider keine Erze in der Nähe finden!" diff --git a/src/main/resources/languages/messages_en.yml b/src/main/resources/languages/messages_en.yml index b0f3a213b..f4fac7169 100644 --- a/src/main/resources/languages/messages_en.yml +++ b/src/main/resources/languages/messages_en.yml @@ -24,6 +24,7 @@ commands: guide: locked: 'LOCKED' + work-in-progress: 'This feature is not fully finished yet!' locked-category: - 'To unlock this category you will' @@ -64,6 +65,13 @@ guide: selected-language: 'Currently selected:' select: 'Click to select this language' select-default: 'Click to select the default language' + change: 'Click to select a new language' + + description: + - '&7You now have the option to change' + - '&7the language in which Slimefun' + - '&7will be presented to you. Items' + - '&7cannot be translated for now.' translations: name: '&aIs something missing?' @@ -78,11 +86,19 @@ guide: addons: 'Addons for Slimefun4' bugs: 'Bug Reports' source: 'Source Code' + versions: 'Installed versions' credits: commit: 'Commit' commits: 'Commits' profile-link: 'Click to visit their profile on GitHub' + open: 'Click to see our contributors' + description: + - '&7Slimefun is an open-source project' + - '&7and maintained by a large community of people.' + - '&7Over &e%contributors% &7people have worked on' + - '&7Slimefun throughout all these years.' + roles: developer: '&6Developer' wiki: '&3Wiki Editor' @@ -105,11 +121,15 @@ messages: not-valid-research: '&4%research% &cis not a valid Research!' give-research: '&bYou have given %player% the Research &7"%research%&7"' hungry: '&cYou are too hungry to do that!' - mode-change: '&b%device% mode changed to: &9%mode%' disabled-in-world: '&4&lThis Item has been disabled in this world' disabled-item: '&4&lThis Item has been disabled! How did you even get that?' no-tome-yourself: '&cYou cannot use the &4Tome of Knowledge &con yourself...' multimeter: '&bStored Energy: &3%stored% &b/ &3%capacity%' + piglin-barter: '&4You cannot barter with piglins using Slimefun items' + + multi-tool: + mode-change: '&b%device% mode changed to: &9%mode%' + not-shears: '&cA Multi Tool cannot be used as shears!' talisman: anvil: '&a&oYour Talisman saved your tool from breaking' @@ -231,6 +251,12 @@ machines: anvil: not-working: '&4You cannot use Slimefun Items in an anvil!' +brewing_stand: + not-working: '&4You cannot use Slimefun Items in a brewing stand!' + +villagers: + no-trading: '&4You cannot trade Slimefun Items with Villagers!' + backpack: already-open: '&cSorry, this Backpack is open somewhere else!' no-stack: '&cYou cannot stack Backpacks' @@ -244,6 +270,7 @@ gps: new: '&ePlease type in a name for your new waypoint in the chat. &7(Color Codes supported!)' added: '&aSuccessfully added a new waypoint' max: '&4You have reached the maximum amount of waypoints' + duplicate: '&4You have already created a waypoint named: &f%waypoint%' insufficient-complexity: - '&4Insufficient GPS Network Complexity: &c%complexity%' diff --git a/src/main/resources/languages/messages_es.yml b/src/main/resources/languages/messages_es.yml index d69e40244..eaa8ef06c 100644 --- a/src/main/resources/languages/messages_es.yml +++ b/src/main/resources/languages/messages_es.yml @@ -24,21 +24,27 @@ guide: search: message: "&b¿Qué te gustaría buscar?" name: "&7Busca..." - tooltip: "&bClick para buscar un item" + tooltip: "&bCliquea para buscar un objeto" inventory: 'Buscando: %item%' lore: - "&b¿Qué te gustaría buscar?" - "&7Escribe en el chat el término que quieres buscar." cheat: - no-multiblocks: "&4¡No puedes obtener los Multiblocks, tienes que construirlos!" + no-multiblocks: "&4¡No puedes regalarte los Multiblocks, tienes que construirlos!" languages: updated: "&aTu lenguaje fue cambiado a: &b%lang%" translations: name: "&a¿Falta algo?" - lore: Clic para agregar tu propia traducción. - select: Clic para seleccionar este idioma. - select-default: Clic para seleccionar el idioma predeterminado. + lore: Cliquea para agregar tu propia traducción. + select: Cliquea para seleccionar este idioma. + select-default: Cliquea para seleccionar el idioma predeterminado. selected-language: 'Actualmente seleccionado:' + change: Click para seleccionar un nuevo lenguaje + description: + - "&7Ahora tienes la opción de cambiar" + - "&7el idioma en el que Slimefun" + - "&7se le presentará. Los objetos" + - "&7no pueden ser traducidos por ahora." title: main: Guía de Slimefun. settings: Configuración e Información. @@ -48,6 +54,7 @@ guide: addons: Complementos para Slimefun4 bugs: Reportes de Bugs source: Código base + versions: Versiones instaladas credits: commit: Contribución commits: Contribuciones @@ -56,12 +63,18 @@ guide: wiki: "&3Editor de Wiki" resourcepack: "&cArtista de Resourcepack" translator: "&9Traductor" - profile-link: Clic para visitar su perfil en GitHub. + profile-link: Cliquea para visitar su perfil en GitHub. + open: Cliquea para ver nuestros contribuyentes + description: + - "&7Slimefun es un proyecto open-source" + - "&7mantenido por una gran comunidad." + - "&7Mas de &e%contributors% &7personas han trabajado en" + - "&7Slimefun en todos estos años." pages: previous: Página anterior next: Página siguiente tooltips: - open-category: Clic para abrir + open-category: Cliquea para abrir versions-notice: "¡Esto es muy importante cuando se reportan bugs!" wiki: Ve este objeto en la wiki oficial de Slimefun recipes: @@ -78,6 +91,7 @@ guide: - Para desbloquear esta categoría deberás - desbloquear todos los objetos de las - siguientes categorías + work-in-progress: "¡¡¡Esta característica no está completamente terminada todavía!!" messages: not-researched: "&4No tienes conocimiento suficiente para entender esto." not-enough-xp: "&4No tienes suficiente XP para desbloquear esto." @@ -95,7 +109,6 @@ messages: not-valid-research: "&c¡&4%research% &cno es un conocimiento válido!" give-research: '&bLe has dado a %player% la investigación &7"%research%&7"' hungry: "&c¡Tienes demasiada hambre para hacer eso!" - mode-change: 'El modo de &b%device% ha cambiado a: &9%mode%' disabled-in-world: "&4&lEste item ha sido desactivado en el mundo." disabled-item: "&4&l¡Este item ha sido desactivado! ¿Cómo es que lo tienes?" no-tome-yourself: "&cNo puedes usar el &4Tome of Knowledge &cen ti mismo..." @@ -150,6 +163,20 @@ messages: - "&7¡Siempre mira el lado bueno de la vida!" - "&7Esta era un bizcocho y no una galleta" - "&7¡Los signos de neón son lo MEJOR!" + piglin-barter: "&4No puedes trocar con piglins usando objetos de Slimefun" + enchantment-rune: + fail: "&cNo puedes encantar este objeto." + no-enchantment: "&cNo se pudo encontrar un encantamiento aplicable a este objeto." + success: "&aHas aplicado con éxito un encantamiento aleatorio a este objeto." + tape-measure: + no-anchor: "&c¡Necesitas establecer un ancla antes de comenzar a medir!" + wrong-world: "&c¡Parece ser que tu ancla se encuentra en un mundo diferente!" + distance: "&7Medida tomada. &eDistancia: %distance%" + anchor-set: "&aAncla establecida con éxito:&e %anchor%" + multi-tool: + mode-change: "&b%device% modo cambiado a: &9%mode%" + not-shears: "&c¡Una Multi Tool no puede ser usada como tijeras!" + mode-change: 'El modo de &b%device% ha cambiado a: &9%mode%' machines: pattern-not-found: "&eLo siento, no puedo reconocer esta receta. Por favor coloca el objeto en el patrón correcto dentro del dispensador." @@ -186,7 +213,7 @@ machines: invulnerability: "&b&l¡Tienes 30 segundos de invulnerabilidad!" gui: title: Tus waypoints - tooltip: Click para teletransportarte + tooltip: Cliquea para teletransportarte time: Tiempo estimado CARGO_NODES: must-be-placed: "&4¡Tiene que ponerse sobre un cofre o máquina!" @@ -218,6 +245,7 @@ gps: códigos de color!)" added: "&aNuevo waypoint agregado exitosamente." max: "&4Has alcanzado el máximo número de waypoints permitidos." + duplicate: "&4Ya has creado un waypoint llamado: &f%waypoint%" insufficient-complexity: - "&4Complejidad de red GPS insuficiente: &c%complexity%" - "&4a) No tienes una red GPS armada aún." @@ -291,8 +319,6 @@ languages: zh-CN: Chino (China) el: Griego he: Hebreo - pt: Portugués (Portugal) - pt-BR: Portugués (Brasil) ar: Árabe af: Africano da: Danés @@ -304,6 +330,8 @@ languages: fa: Persa th: Tailandés ro: Rumano + pt: Portugués (Portugal) + pt-BR: Portugués (Brasil) bg: Búlgaro ko: Coreano tr: Turco @@ -312,5 +340,9 @@ languages: sr: Serbio be: Bielorruso tl: Tagalog +brewing_stand: + not-working: "&4¡No puedes usar objetos de Slimefun en un soporte para pociones!" +villagers: + no-trading: "&4¡No puedes comerciar objetos de Slimefun con los aldeanos!" miner: no-ores: "&ePerdón, ¡No encuentro ningún mineral cerca!" diff --git a/src/main/resources/languages/messages_hu.yml b/src/main/resources/languages/messages_hu.yml index 568c729c7..17adc36d7 100644 --- a/src/main/resources/languages/messages_hu.yml +++ b/src/main/resources/languages/messages_hu.yml @@ -1,227 +1,137 @@ --- -android: - scripts: - already-uploaded: "&4Ezt a szkriptet már feltöltötték." - editor: Szkript Szerkesztő - enter-name: - - - - "&eKérlek, írd be a szkript nevét" - instructions: - ATTACK_ANIMALS: "&4Támadj &c(Állatok)" - ATTACK_ANIMALS_ADULT: "&4Támadj &c(Állatok &7[Felnőtt]&c)" - ATTACK_MOBS: "&4Támadj &c(Ellenséges Élőlények)" - ATTACK_MOBS_ANIMALS: "&4Támadj &c(Ellenséges Élőlények és Állatok)" - CATCH_FISH: "&bFogj Halat" - CHOP_TREE: "&cVágj és Ültess" - DIG_DOWN: "&bÁss le" - DIG_FORWARD: "&bÁss előre" - DIG_UP: "&bÁss" - FARM_DOWN: "&bSzüretelj és Ültess &7(Blokk alatt)" - FARM_EXOTIC_DOWN: "&bFejlett Szüretelés és Ültetés &7(Blokk alatt)" - FARM_EXOTIC_FORWARD: "&bFejlett Szüretelés és Ültetés" - FARM_FORWARD: "&bSzüretelj és Ültess" - GO_DOWN: "&7Menj lefelé" - GO_FORWARD: "&7Menj előre" - GO_UP: "&7Menj felfelé" - INTERFACE_FUEL: "&cVegyen ki az Üzemanyagot a csatlakozási Felületről" - INTERFACE_ITEMS: "&9Tegye az Eszköztár Tartalmát a csatlakozási Felületbe" - MOVE_AND_DIG_DOWN: "&bMenj és Áss lefelé" - MOVE_AND_DIG_FORWARD: "&bMenj és Áss előre" - MOVE_AND_DIG_UP: "&bMenj és Áss felfelé" - REPEAT: "&9Szkript ismétlése" - START: "&2Szkript indítása" - TURN_LEFT: "&7Fordulj balra" - TURN_RIGHT: "&7Fordulj jobbra" - WAIT: "&eVárjon 0.5s" - rating: - already: "&4Ezt a szkriptet már értékelted!" - own: "&4Nem értékelheted a saját szkriptedet!" - uploaded: - - "&bFeltöltés..." - - "&aA szkript sikeresen feltöltve!" - started: "&7Az Androidod folytatja a szkript futtatását" - stopped: "&7Az Androidod szünetelteti a szkript futtatását" -anvil: - not-working: "&4Nem használhatsz Slimefun tárgyakat az Üllőben!" -backpack: - already-open: "&cSajnáljuk, ez a Hátizsák valahol máshol már nyitva van!" - no-stack: "&cNem lehet halmozni a Táskákat" commands: + help: Megjeleníti ezt a súgóképernyőt cheat: Lehetővé teszi a Tárgyak csalását give: Adj valakinek Slimefun Tárgyakat guide: Adj magadnak egy Slimefun Útmutatót - help: Megjeleníti ezt a súgóképernyőt + timings: Lag-Információ a Szerverről + teleporter: Nézd meg a többi Játékos Útpontjait + versions: Az összes telepített Kiegészítőt listázza + search: Keresés egy kifejezésre az Útmutatóban open_guide: A könyv használata nélkül megnyitja a Slimefun útmutatóját + stats: Néhány statisztikát mutat a Játékosról research: description: A játékosok kutatásainak Feloldása/Visszaállítása reset: "&cVisszaállítottad %player% Ismereteit" reset-target: "&cAz ismereteidet visszaállították" - search: Keresés egy kifejezésre az Útmutatóban - stats: Néhány statisztikát mutat a Játékosról - teleporter: Nézd meg a többi Játékos Útpontjait - timings: Lag-Információ a Szerverről - versions: Az összes telepített Kiegészítőt listázza -gps: - deathpoint: "&4Halálpont &7%date%" - geo: - scan-required: "&4GEO-Vizsgálat szükséges! &cElőbb vizsgáld meg ezt a chunkot - a GEO-Szkennerrel!" - insufficient-complexity: - - "&4Nem megfelelő a GPS Hálózat Komplexitása: &c%complexity%" - - "&4a) Még nem telepítetted a GPS Hálózatot" - - "&4b) A GPS Hálózatod nem eléggé összetett" - waypoint: - added: "&aSikeresen megadtad az útpontot" - max: "&4Elérted a maximális útpontok számát" - new: "&eKérlek, add meg az új útpontot chatben. &7(A Színkódok használhatóak!)" + backpack: + description: Lekéri egy meglévő hátizsák másolatát + invalid-id: "&4Az azonosító nem lehet negatív szám!" + player-never-joined: "&4Nincs ilyen nevű játékos!" + backpack-does-not-exist: "&4A megadott hátizsák nem létezik!" + restored-backpack-given: "&aA hátizsákod visszaállítva és hozzáadva a leltáradhoz!" guide: - back: - guide: Menj vissza a Slimefun Útmutatóba - settings: Menj vissza a Beállítások Panelre - title: Vissza + search: + message: "&bMit szeretnél keresni?" + name: "&7Keresés..." + tooltip: "&bKlikk egy tárgy kereséséhez" + inventory: 'Keresés erre: %item%' + lore: + - "&bMit szeretnél keresni?" + - "&7Gépeld be a keresett kifejezést a chatbe" cheat: no-multiblocks: "&4A Multiblokkban nem tudsz csalni, meg kell építened!" - credits: - commit: Commit - commits: Commits - profile-link: Kattints ide, hogy meglátogasd a profilját a GitHub-on - roles: - developer: "&6Fejlesztő" - resourcepack: "&cForráscsomag Művész" - translator: "&9Fordító" - wiki: "&3Wiki Szerkesztő" languages: + updated: "&aA nyelvet sikeresen átállítottad erre: &b%lang%" + translations: + name: "&aHiányzik valami?" + lore: Kattints a saját fordítás hozzáadásához select: Kattints a nyelv kiválasztásához select-default: Kattints az alapértelmezett nyelv kiválasztásához selected-language: 'Jelenleg kiválasztva:' - translations: - lore: Kattints a saját fordítás hozzáadásához - name: "&aHiányzik valami?" - updated: "&aA nyelvet sikeresen átállítottad erre: &b%lang%" + title: + main: Slimefun Útmutató + settings: Beállítások és Információk + languages: Válaszd ki a kívánt nyelvet + credits: Slimefun4 Közreműködők + wiki: Slimefun4 Wiki + addons: A Slimefun4 kiegészítői + bugs: Hibajelentések + source: Forráskód + credits: + commit: Commit + commits: Commits + roles: + developer: "&6Fejlesztő" + wiki: "&3Wiki Szerkesztő" + resourcepack: "&cForráscsomag Művész" + translator: "&9Fordító" + profile-link: Kattints ide, hogy meglátogasd a profilját a GitHub-on + pages: + previous: Előző oldal + next: Következő oldal + tooltips: + open-category: Kattints a megnyitáshoz + versions-notice: Ezek nagyon fontosak a hibák jelentésekor! + wiki: Tekintsd meg ezt a tárgyat a hivatalos Slimefun Wikin + recipes: + machine: Ebben a Gépben készített receptek + miner: Erőforrások, amelyeket ezzel a Bányásszal szerezhetsz be + generator: Rendelkezésre álló üzemanyagtípusok + gold-pan: Megszerezhető források + back: + title: Vissza + guide: Menj vissza a Slimefun Útmutatóba + settings: Menj vissza a Beállítások Panelre locked: LEZÁRVA locked-category: - Ennek a kategóriának a feloldásához - fel kell oldanod az összes tárgyat a - következő kategóriákból - pages: - next: Következő oldal - previous: Előző oldal - search: - inventory: 'Keresés erre: %item%' - lore: - - "&bMit szeretnél keresni?" - - "&7Gépeld be a keresett kifejezést a chatbe" - message: "&bMit szeretnél keresni?" - name: "&7Keresés..." - tooltip: "&bKlikk egy tárgy kereséséhez" - title: - addons: A Slimefun4 kiegészítői - bugs: Hibajelentések - credits: Slimefun4 Közreműködők - languages: Válaszd ki a kívánt nyelvet - main: Slimefun Útmutató - settings: Beállítások és Információk - source: Forráskód - wiki: Slimefun4 Wiki - tooltips: - open-category: Kattints a megnyitáshoz - recipes: - generator: Rendelkezésre álló üzemanyagtípusok - gold-pan: Megszerezhető források - machine: Ebben a Gépben készített receptek - miner: Erőforrások, amelyeket ezzel a Bányásszal szerezhetsz be - versions-notice: Ezek nagyon fontosak a hibák jelentésekor! - wiki: Tekintsd meg ezt a tárgyat a hivatalos Slimefun Wikin -inventory: - no-access: "&4Nincs hozzáférésed ehhez a blokkhoz" -languages: - af: Afrikánsz - ar: Arab - bg: Bolgár - cs: Cseh - da: Dán - de: Német - default: Szerver-Alapértelmezett - el: Görög - en: Angol - es: Spanyol - fa: Perzsa - fi: Finn - fr: Francia - he: Héber - hu: Magyar - id: Indonéz - it: Olasz - ja: Japán - ko: Koreai - lv: Lett - ms: Maláj - nl: Holland - 'no': Norvég - pl: Lengyel - pt: Portugál (Portugália) - pt-BR: Portugál (Brazília) - ro: Román - ru: Orosz - sk: Szlovák - sv: Svéd - th: Thai - tr: Török - uk: Ukrán - vi: Vietnami - zh-CN: Kínai (Kína) - zh-TW: Kínai (Tajvan) -machines: - ANCIENT_ALTAR: - not-enough-pedestals: "&4Az Oltár körül nincs elég Talapzat, ami szükséges a működéséhez - &c(%pedestals% / 8)" - unknown-catalyst: "&4Ismeretlen Katalizátor! &cEhelyett használd a helyes Receptet!" - unknown-recipe: "&4Ismeretlen Recept! &cEhelyett használd a helyes Receptet!" - ANCIENT_PEDESTAL: - obstructed: "&4A Talapzat el van torlaszolva! &cTávolíts el mindent, ami a talapzat - felett van!" - CARGO_NODES: - must-be-placed: "&4Ládára vagy gépre kell helyezni!" - ELEVATOR: - click-to-teleport: "&eKattints &7erre az emeletre való teleportáláshoz:" - current-floor: "&eEz az emelet, amelyen jelenleg tartózkodik:" - enter-name: "&7Kérlek írd be a kívánt emelet nevet a Chatbe. &r(A Színkódok is - támogatottak!)" - named: "&2Sikeresen elnevezted ezt az emeletet: &r%floor%" - no-destinations: "&4Nem található úticél" - pick-a-floor: "&3- Válassz emeletet -" - full-inventory: "&eSajnálom, tele a tárolóm!" - GPS_CONTROL_PANEL: - title: GPS - Vezérlőpult - transmitters: Transzmitter Áttekintése - waypoints: Útpont Áttekintése - HOLOGRAM_PROJECTOR: - enter-text: "&7Kérlek, írd be a kívánt Hologram Szöveget a Chatbe. &r(A színkódok - is használhatóak!)" - inventory-title: Hologram Szerkesztő - ignition-chamber-no-flint: "&cA Gyújtókamrából hiányzik a Kovakő és Acél." - in-use: "&cEnnek a Blokknak a tárolóját éppen megnyitotta egy másik Játékos." - pattern-not-found: "&eSajnálom, nem ismerem fel ezt a Receptet. Kérlek, helyezd - a Tárgyakat a megfelelő mintában az Adagolóba." - TELEPORTER: - cancelled: "&4Teleportálás megszakítva!" - gui: - time: Becsült idő - title: Az útpontjaid - tooltip: Klikk a teleportáláshoz - invulnerability: "&b&l30 másodperc Sérthetetlenséget kaptál!" - teleported: "&3Teleportálva!" - teleporting: "&3Teleportálás..." - unknown-material: "&eSajnálom, Nem tudtam felismerni a Tárgyat az adagolóban. Kérlek - tegyél bele valamit, amit ismerek." - wrong-item: "&eSajnálom, nem ismerem fel azt a Tárgyat, amire kattintottál velem. - Ellenőrizd a Recepteket, és nézd meg, mely Tárgyakat használhatod." messages: - cannot-place: "&cNem teheted ezt a blokkot oda!" - diet-cookie: "&eNagyon könnyednek érzed magad..." + not-researched: "&4Nincs elég ismereted ennek a megértéséhez" + not-enough-xp: "&4Nincs elég XP-d ennek a feloldásához" + unlocked: '&7"%research%" &bfeloldva' + only-players: "&4Ez a parancs csak a Játékosok számára szól" + unknown-player: "&4Ismeretlen Játékos: &c%player%" + no-permission: "&4Nem rendelkezel a szükséges engedélyekkel ehhez" + usage: "&4Használat: &c%usage%" + not-online: "&4%player% &cnincs online!" + not-valid-item: "&4%item% &cnem megfelelő Tárgy!" + not-valid-amount: "&4%amount% &cnem megfelelő mennyiség : 0-nál nagyobbnak kell + lennie!" + given-item: '&bKaptál &a%amount% &7"%item%&7"&b-t' + give-item: '&bAdtál %player%-nek/nak &a%amount% &7"%item%&7"&b-t' + not-valid-research: "&4%research% &cnem érvényes Kutatás!" + give-research: '&bAdtál %player%-nek/nak &7"%research%&7" &bKutatást' + hungry: "&cTúl éhes vagy ehhez!" + mode-change: "&b%device% mód állítva erre: &9%mode%" disabled-in-world: "&4&lEz a Tárgy tiltva van ebben a világban" disabled-item: "&4&lEz a Tárgy le van tiltva! Egyáltalán hogyan szerezted?" + no-tome-yourself: "&cNem tudod használni a &4Tome of Knowledge &c-t magadon..." + multimeter: "&bTárolt Energia: &3%stored% &b/ &3%capacity%" + talisman: + anvil: "&a&oA Talizmánod megmentette az eszközöd a töréstől" + miner: "&a&oA Talizmánod megduplázta a dobott tárgyakat" + hunter: "&a&oA Talizmánod megduplázta a dobott tárgyakat" + lava: "&a&oA Talizmánod megmentett a halálos égéstől" + water: "&a&oA Talizmánod megmentett a fulladástól" + angel: "&a&oA Talizmánod megmentett a zuhanási sérüléstől" + fire: "&a&oA Talizmánod megmentett a halálra elégéstől" + magician: "&a&oA Talizmánod adott további Fejlesztéseket is" + traveller: "&a&oA Talizmánod Gyors sebességet adott neked" + warrior: "&a&oA Talizmánodtól növelte az Erőd egy kis időre" + knight: "&a&oA Talizmánod adott 5 Másodpercre élet Regenerációt" + whirlwind: "&a&oA Talizmánod visszavert egy Távolsági lövést" + wizard: "&a&oA Talizmánod erősítette a Szerencse Szinjét, de néhány egyéb Fejlesztés + Szint kicsit gyengül" + soulbound-rune: + fail: "&cEgyszerre csak egy tárgyat köthetsz a lelkedhez." + success: "&aSikeresen hozzákötötted ezt a tárgyat a lelkedhez! Megmarad, amikor + meghalsz." + research: + start: "&7Az Ősi Lelkek titokzatos szavakat súgnak a füledbe!" + progress: "&7Elkezdtél kíváncsiskodni a következő kutatásról: &b%research% &e(%progress%)" fire-extinguish: "&7Eloltottad magad!" + cannot-place: "&cNem teheted ezt a blokkot oda!" + no-pvp: "&cA pvp itt nem engedélyezett!" + radiation: "&4Halálos sugárzásnak vagy kitéve! &cSzabadulj meg a radioaktív tárgytól, + vagy viselj Hazmat Suit-ot!" + opening-guide: "&bÚtmutató megnyitása, ez eltarthat pár másodpercig..." + opening-backpack: "&bHátizsák megnyitása, ez eltarthat pár másodpercig..." + no-iron-golem-heal: "&cEz nem egy Vasrúd. Ezt nem használhatod a Vasgólem gyógyítására!" + link-prompt: "&eKattints ide:" + diet-cookie: "&eNagyon könnyednek érzed magad..." fortune-cookie: - "&7Segítség, csapdába estem egy Szerencsesüti Gyárban!" - "&7Holnap meghalsz... egy Creeper által" @@ -235,55 +145,183 @@ messages: - "&742. A válasz 42." - "&7Walshy egy nap távol tartja a bajokat." - "&7Soha ne áss egyenesen!" - give-item: '&bAdtál %player%-nek/nak &a%amount% &7"%item%&7"&b-t' - given-item: '&bKaptál &a%amount% &7"%item%&7"&b-t' - give-research: '&bAdtál %player%-nek/nak &7"%research%&7" &bKutatást' - hungry: "&cTúl éhes vagy ehhez!" - link-prompt: "&eKattints ide:" - mode-change: "&b%device% mód állítva erre: &9%mode%" - multimeter: "&bTárolt Energia: &3%stored% &b/ &3%capacity%" - no-iron-golem-heal: "&cEz nem egy Vasrúd. Ezt nem használhatod a Vasgólem gyógyítására!" - no-permission: "&4Nem rendelkezel a szükséges engedélyekkel ehhez" - no-pvp: "&cA pvp itt nem engedélyezett!" - not-enough-xp: "&4Nincs elég XP-d ennek a feloldásához" - no-tome-yourself: "&cNem tudod használni a &4Tome of Knowledge &c-t magadon..." - not-online: "&4%player% &cnincs online!" - not-researched: "&4Nincs elég ismereted ennek a megértéséhez" - not-valid-amount: "&4%amount% &cnem megfelelő mennyiség : 0-nál nagyobbnak kell - lennie!" - not-valid-item: "&4%item% &cnem megfelelő Tárgy!" - not-valid-research: "&4%research% &cnem érvényes Kutatás!" - only-players: "&4Ez a parancs csak a Játékosok számára szól" - opening-backpack: "&bHátizsák megnyitása, ez eltarthat pár másodpercig..." - opening-guide: "&bÚtmutató megnyitása, ez eltarthat pár másodpercig..." - radiation: "&4Halálos sugárzásnak vagy kitéve! &cSzabadulj meg a radioaktív tárgytól, - vagy viselj Hazmat Suit-ot!" - research: - progress: "&7Elkezdel kíváncsiskodni a kutatásról, neve: &b%research% &e(%progress%)" - start: "&7Az Ősi Lelkek titokzatos szavakat súgnak a füledbe!" - soulbound-rune: - fail: "&cEgyszerre csak egy tárgyat köthetsz a lelkedhez." - success: "&aSikeresen hozzákötötted ezt a tárgyat a lelkedhez! Megmarad, amikor - meghalsz." - talisman: - angel: "&a&oA Talizmánod megmentett a zuhanási sérüléstől" - anvil: "&a&oA Talizmánod megmentette az eszközöd a töréstől" - fire: "&a&oA Talizmánod megmentett a halálra elégéstől" - hunter: "&a&oA Talizmánod megduplázta a dobott tárgyakat" - knight: "&a&oA Talizmánod adott 5 Másodpercre élet Regenerációt" - lava: "&a&oA Talizmánod megmentett a halálos égéstől" - magician: "&a&oA Talizmánod adott további Fejlesztéseket is" - miner: "&a&oA Talizmánod megduplázta a dobott tárgyakat" - traveller: "&a&oA Talizmánod Gyors sebességet adott neked" - warrior: "&a&oA Talizmánodtól növelte az Erőd egy kis időre" - water: "&a&oA Talizmánod megmentett a fulladástól" - whirlwind: "&a&oA Talizmánod visszavert egy Távolsági lövést" - wizard: "&a&oA Talizmánod erősítette a Szerencse Szinjét, de néhány egyéb Fejlesztés - Szint kicsit gyengül" - unknown-player: "&4Ismeretlen Játékos: &c%player%" - unlocked: '&7"%research%" &bfeloldva' - usage: "&4Használat: &c%usage%" -miner: - no-ores: "&eSajnálom, nem találtam semmilyen Ércet a közelben!" + - "&7Ez csak egy friss sebesülés!" + - "&7Mindig nézd az élet jó oldalát!" + - "&7Ez valójában Keksz volt, és nem Süti" + - "&7A neon táblák VILÁGÍTANAK!" + piglin-barter: "&4Slimefun tárgyakat nem cserélhetsz el a Piglinekkel." + enchantment-rune: + fail: "&cNem varázsolhatod el ezt a tárgyat." + no-enchantment: "&cNem található megfelelő varázslat ehhez az tárgyhoz." + success: "&aSikeresen alkalmaztál egy véletlenszerű varázslatot erre a tárgyra." + tape-measure: + no-anchor: "&cBe kell állítanod egy rögzítést, mielőtt megkezdenéd a mérést!" + wrong-world: "&cA rögzítés úgy tűnik egy másik világban van!" + distance: "&7A mérés megtörtént. &eA távolság: %distance%" + anchor-set: "&aA rögzítés sikeresen beállítva:&e %anchor%" +machines: + pattern-not-found: "&eSajnálom, nem ismerem fel ezt a Receptet. Kérlek, helyezd + a Tárgyakat a megfelelő mintában az Adagolóba." + unknown-material: "&eSajnálom, Nem tudtam felismerni a Tárgyat az adagolóban. Kérlek + tegyél bele valamit, amit ismerek." + wrong-item: "&eSajnálom, nem ismerem fel azt a Tárgyat, amire kattintottál velem. + Ellenőrizd a Recepteket, és nézd meg, mely Tárgyakat használhatod." + full-inventory: "&eSajnálom, tele a tárolóm!" + in-use: "&cEnnek a Blokknak a tárolóját éppen megnyitotta egy másik Játékos." + ignition-chamber-no-flint: "&cA Gyújtókamrából hiányzik a Kovakő és Acél." + ANCIENT_ALTAR: + not-enough-pedestals: "&4Az Oltár körül nincs elég Talapzat, ami szükséges a működéséhez + &c(%pedestals% / 8)" + unknown-catalyst: "&4Ismeretlen Katalizátor! &cEhelyett használd a helyes Receptet!" + unknown-recipe: "&4Ismeretlen Recept! &cEhelyett használd a helyes Receptet!" + ANCIENT_PEDESTAL: + obstructed: "&4A Talapzat el van torlaszolva! &cTávolíts el mindent, ami a talapzat + felett van!" + HOLOGRAM_PROJECTOR: + enter-text: "&7Kérlek, írd be a kívánt Hologram Szöveget a Chatbe. &r(A színkódok + is használhatóak!)" + inventory-title: Hologram Szerkesztő + ELEVATOR: + no-destinations: "&4Nem található úticél" + pick-a-floor: "&3- Válassz emeletet -" + current-floor: "&eEz az emelet, amelyen jelenleg tartózkodik:" + click-to-teleport: "&eKattints &7erre az emeletre való teleportáláshoz:" + enter-name: "&7Kérlek írd be a kívánt emelet nevet a Chatbe. &r(A Színkódok is + támogatottak!)" + named: "&2Sikeresen elnevezted ezt az emeletet: &r%floor%" + TELEPORTER: + teleporting: "&3Teleportálás..." + teleported: "&3Teleportálva!" + cancelled: "&4Teleportálás megszakítva!" + invulnerability: "&b&l30 másodperc Sérthetetlenséget kaptál!" + gui: + title: Az útpontjaid + tooltip: Klikk a teleportáláshoz + time: Becsült idő + CARGO_NODES: + must-be-placed: "&4Ládára vagy gépre kell helyezni!" + GPS_CONTROL_PANEL: + title: GPS - Vezérlőpult + transmitters: Transzmitter Áttekintése + waypoints: Útpont Áttekintése + INDUSTRIAL_MINER: + no-fuel: "&cAz Ipari Bányászodnak elfogyott az üzemanyaga! Tedd az üzemanyagot + a fenti ládába." + piston-facing: "&cAz Ipari Bányászodhoz szükségesek dugattyúk, amik felfelé néznek!" + piston-space: "&cA két dugattyú felett egy üres blokknak kell lennie!" + destroyed: "&cÚgy tűnik, hogy az Ipari Bányászod megsemmisült." + already-running: "&cEz az Ipari Bányász már fut!" + full-chest: "&cAz Ipari Bányász ládája tele van!" + no-permission: "&4Úgy tűnik, hogy nincs engedélyed az Ipari Bányász üzemeltetésére + itt!" + finished: Az Ipari Bányászod kész! Összesen %ores% ércet szerzett! +anvil: + not-working: "&4Nem használhatsz Slimefun tárgyakat az Üllőben!" +backpack: + already-open: "&cSajnáljuk, ez a Hátizsák valahol máshol már nyitva van!" + no-stack: "&cNem lehet halmozni a Táskákat" workbench: not-enhanced: "&4Nem használhatsz Slimefun Tárgyakat normális barkácsasztalban" +gps: + deathpoint: "&4Halálpont &7%date%" + waypoint: + new: "&eKérlek, add meg az új útpontot chatben. &7(A Színkódok használhatóak!)" + added: "&aSikeresen megadtad az útpontot" + max: "&4Elérted a maximális útpontok számát" + insufficient-complexity: + - "&4Nem megfelelő a GPS Hálózat Komplexitása: &c%complexity%" + - "&4a) Még nem telepítetted a GPS Hálózatot" + - "&4b) A GPS Hálózatod nem eléggé összetett" + geo: + scan-required: "&4GEO-Vizsgálat szükséges! &cElőbb vizsgáld meg ezt a chunkot + a GEO-Szkennerrel!" +inventory: + no-access: "&4Nincs hozzáférésed ehhez a blokkhoz" +android: + started: "&7Az Androidod folytatja a szkript futtatását" + stopped: "&7Az Androidod szünetelteti a szkript futtatását" + scripts: + already-uploaded: "&4Ezt a szkriptet már feltöltötték." + instructions: + START: "&2Szkript indítása" + REPEAT: "&9Szkript ismétlése" + WAIT: "&eVárjon 0.5s" + GO_FORWARD: "&7Menj előre" + GO_UP: "&7Menj felfelé" + GO_DOWN: "&7Menj lefelé" + TURN_LEFT: "&7Fordulj balra" + TURN_RIGHT: "&7Fordulj jobbra" + DIG_UP: "&bÁss" + DIG_FORWARD: "&bÁss előre" + DIG_DOWN: "&bÁss le" + MOVE_AND_DIG_UP: "&bMenj és Áss felfelé" + MOVE_AND_DIG_FORWARD: "&bMenj és Áss előre" + MOVE_AND_DIG_DOWN: "&bMenj és Áss lefelé" + ATTACK_MOBS_ANIMALS: "&4Támadj &c(Ellenséges Élőlények és Állatok)" + ATTACK_MOBS: "&4Támadj &c(Ellenséges Élőlények)" + ATTACK_ANIMALS: "&4Támadj &c(Állatok)" + ATTACK_ANIMALS_ADULT: "&4Támadj &c(Állatok &7[Felnőtt]&c)" + CHOP_TREE: "&cVágj és Ültess" + CATCH_FISH: "&bFogj Halat" + FARM_FORWARD: "&bSzüretelj és Ültess" + FARM_DOWN: "&bSzüretelj és Ültess &7(Blokk alatt)" + FARM_EXOTIC_FORWARD: "&bFejlett Szüretelés és Ültetés" + FARM_EXOTIC_DOWN: "&bFejlett Szüretelés és Ültetés &7(Blokk alatt)" + INTERFACE_ITEMS: "&9Tegye az Eszköztár Tartalmát a csatlakozási Felületbe" + INTERFACE_FUEL: "&cVegyen ki az Üzemanyagot a csatlakozási Felületről" + enter-name: + - + - "&eKérlek, írd be a szkript nevét" + uploaded: + - "&bFeltöltés..." + - "&aA szkript sikeresen feltöltve!" + rating: + own: "&4Nem értékelheted a saját szkriptedet!" + already: "&4Ezt a szkriptet már értékelted!" + editor: Szkript Szerkesztő +languages: + default: Szerver-Alapértelmezett + en: Angol + de: Német + fr: Francia + it: Olasz + es: Spanyol + pl: Lengyel + sv: Svéd + nl: Holland + cs: Cseh + hu: Magyar + lv: Lett + ru: Orosz + sk: Szlovák + zh-TW: Kínai (Tajvan) + vi: Vietnami + id: Indonéz + zh-CN: Kínai (Kína) + el: Görög + he: Héber + ar: Arab + af: Afrikánsz + da: Dán + fi: Finn + uk: Ukrán + ms: Maláj + 'no': Norvég + ja: Japán + fa: Perzsa + th: Thai + ro: Román + pt: Portugál (Portugália) + pt-BR: Portugál (Brazília) + bg: Bolgár + ko: Koreai + tr: Török + hr: Horvát + mk: Macedóniai + sr: Szerb + be: Belorusz + tl: Tagalog +brewing_stand: + not-working: "&4Nem használhatsz Slimefun tárgyakat a Főzőállványban!" +miner: + no-ores: "&eSajnálom, nem találtam semmilyen Ércet a közelben!" diff --git a/src/main/resources/languages/messages_ja.yml b/src/main/resources/languages/messages_ja.yml index 3daafa147..24877bc5d 100644 --- a/src/main/resources/languages/messages_ja.yml +++ b/src/main/resources/languages/messages_ja.yml @@ -143,6 +143,16 @@ messages: - "&7常に前向きに生きていこう!" - "&7これはビスケットなんかではなくクッキーに違いない" - "&7ネオンサインが眩しい!" + piglin-barter: "&4Slimefunアイテムはピグリンとの物々交換に使用できません" + enchantment-rune: + fail: "&cこのアイテムにはエンチャントできません。" + no-enchantment: "&cこのアイテムに付与できるエンチャントが見つかりません。" + success: "&aこのアイテムに付与できるエンチャントをランダムに付与しました。" + tape-measure: + no-anchor: "&c計測するために、開始点を指定してください!" + wrong-world: "&cアンカーが別のワールドに指定されています!" + distance: "&7測定完了。&e距離: %distance%" + anchor-set: "&aアンカーを指定:&e %anchor%" machines: pattern-not-found: "&eレシピが確認できません、アイテムを正しく配置してください" unknown-material: "&eアイテムを識別できません、レシピ通りに配置してください" @@ -275,6 +285,7 @@ languages: el: ギリシャ語 he: ヘブライ語 pt: ポルトガル語(ポルトガル) + pt-BR: ポルトガル語(ブラジル) ar: アラビア語 af: アフリカーンス語 da: デンマーク語 @@ -286,7 +297,6 @@ languages: fa: ペルシア語 th: タイ語 ro: ルーマニア語 - pt-BR: ポルトガル語(ブラジル) bg: ブルガリア語 ko: 韓国語 tr: トルコ語 @@ -295,5 +305,7 @@ languages: sr: セルビア語 be: ベラルーシ語 tl: タガログ語 +brewing_stand: + not-working: "&4Slimefunのアイテムは醸造台で使えません!" miner: no-ores: "&e周辺には鉱石が見つかりませんでした!" diff --git a/src/main/resources/languages/messages_ko.yml b/src/main/resources/languages/messages_ko.yml new file mode 100644 index 000000000..a160b4358 --- /dev/null +++ b/src/main/resources/languages/messages_ko.yml @@ -0,0 +1,315 @@ +--- +commands: + help: 이 도움말 화면을 표시합니다 + cheat: 당신은 치트 아이템을 허용 + give: 슬라임펀 아이템을 주다. + guide: Slimefun 가이드 책 제공 + timings: 서버에 대한 Lag-Info + teleporter: 다른 플레이어의 웨이포인트 보기 + versions: 설치된 모든 애드온 리스트 + search: 주어진 기간 동안 가이드 검색 + open_guide: 책을 사용하지 않고 슬라임펀 가이드 열기 + stats: 플레이어에 대한 일부 통계 표시 + research: + description: 플레이어에 대한 조사 잠금 해제/재설정 + reset: "&c%player%의 지식을 재설정하셨습니다." + reset-target: "&c지식이 재설정됨" + backpack: + description: 기존 배낭의 사본을 가져옵니다 + invalid-id: "&4ID는 음수가 아닌 숫자 여야합니다!" + player-never-joined: "&4그 이름의 플레이어를 찾을 수 없습니다!" + backpack-does-not-exist: "&4지정된 배낭이 없습니다!" + restored-backpack-given: "&a배낭이 복원되어 인벤토리에 추가되었습니다!" +guide: + search: + message: "&b무엇을 검색하시겠습니까?" + name: "&7검색..." + tooltip: "&b아이템을 검색하려면 클릭하십시오." + inventory: '검색중: %item%' + cheat: + no-multiblocks: "&4여러분은 멀티블록에서 컨닝을 할 수 없습니다. 여러분이 그것들을 만들어야 합니다!" + languages: + updated: "&a언어를 &b%lang%로 설정했습니다." + translations: + name: "&a 뭔가 빠졌습니까?" + lore: '사용자 자신의 변환을 추가하려면 클릭하십시오. + +' + select: 이 언어를 선택하려면 클릭하십시오. + select-default: 기본 언어를 선택하려면 클릭하십시오. + selected-language: '현재 선택된 :' + title: + main: 슬라임펀 가이드 + settings: 설정 & 정보 + languages: 당신이 원하는 언어를 선택하십시오. + credits: 슬라임펀4 기부자들입니다. + wiki: Slimefun4 위키 + addons: Slimefun4의 애드온 + bugs: 버그 리포트 + source: 소스 코드 + credits: + commit: 커밋 + commits: 커밋 + roles: + developer: "&6개발자" + wiki: "&3위키 편집기\n" + resourcepack: "&c리소스 팩 아티스트" + translator: "&9번역가" + profile-link: GitHub에서 해당 프로필을 방문하려면 클릭하십시오. + pages: + previous: 이전 페이지 + next: 다음 페이지 + tooltips: + open-category: '열려면 클릭하십시오. + +' + versions-notice: '이것들은 버그를 보고할 때 매우 중요하다! + +' + wiki: 공식 Slimefun Wiki에서 이 항목보기 + recipes: + machine: 이 기계로 만든 조합법 + miner: 이 마이너로 얻을 수있는 자원 + generator: 사용 가능한 연료 유형 + gold-pan: 얻을 수 있는 리소스 + back: + title: 뒤 + guide: Slimefun 가이드로 돌아 가기 + settings: 설정 패널로 돌아갑니다 + locked: 잠금 + locked-category: + - 이 카테고리의 잠금을 해제하려면 + - 에서 모든 아이템의 잠금을 해제할 필요가 있다. + - 다음 카테고리 +messages: + not-researched: "&4너는 이것을 이해하기에 충분한 지식을 가지고 있지 않다.\n" + not-enough-xp: "&4XP가 부족하여 이 잠금을 해제할 수 없습니다.\n" + unlocked: '&7"%research%"&b의 잠금을 해제했습니다.' + only-players: "&4이 명령은 플레이어 전용입니다." + unknown-player: "&4알 수 없는 플레이어: &c%player%" + no-permission: "&4이 작업에 필요한 권한이 없습니다." + usage: "&4사용량: &c%usage%\n" + not-online: "&4%player% &cis가 온라인 상태가 아닙니다!" + not-valid-item: "&4%item% &cis가 올바른 아이템이 아닙니다!" + not-valid-amount: "&4%amount% &cis 유효한 금액이 아닙니다. 0보다 커야 합니다!" + given-item: '&b당신은 &a%amount% &7"%item%&7"을 받았다.' + give-item: '&b%player% &a%amount% &7"%item%&7"을(를) 제공하셨습니다.' + not-valid-research: "&4%research% &cis가 유효하지 않은 연구!\n" + give-research: '&b%player%에 Research &7"%research%&7"을(를) 제공했습니다. + +' + hungry: "&c당신은 그것을 하기에는 너무 배가 고파요!" + mode-change: "&b%device% 모드가 &9%mode%로 변경되었습니다." + disabled-in-world: "&4&l이 아이템은 이 세상에서 사용할 수 없습니다" + disabled-item: "&4&l이 아이템을 사용할 수 없습니다! 어떻게 그런 걸 얻었어요?" + no-tome-yourself: "&c당신은 &4Tome of Knowledge &con은 직접 사용할 수 없습니다." + multimeter: "&b저장된 에너지: &3%stored% &b/&3% capacity%" + talisman: + anvil: "&a&o당신의 탈리스맨이 당신의 도구가 부셔지는 것을 막아줬습니다." + miner: "&a&o당신의 탈리스맨이 당신의 방울을 두 배로 늘렸어요" + hunter: "&a&o당신의 탈리스맨이 당신의 방울을 두 배로 늘렸어요" + lava: "&a&o당신의 탈리스맨은 당신을 용암에 타죽는 것으로부터 구했습니다." + water: "&a&o당신의 탈리스맨이 당신을 익사로부터 구했어요" + angel: "&a&o당신의 탈리스맨이 당신을 낙상 피해로부터 구했습니다." + fire: "&a&o당신의 탈리스맨은 당신을 불에 타죽는 것으로부터 구했습니다." + magician: "&a&o당신의 탈리스맨이 당신에게 추가 약속을 했습니다." + traveller: "&a&o당신의 탈리스맨이 당신에게 스피드 부스트를 주었습니다." + warrior: "&a&o당신의 탈리스맨은 당신의 힘을 잠시 향상시켰습니다." + knight: "&a&o당신의 탈리스맨은 당신에게 5초의 재생 시간을 주었습니다." + whirlwind: "&a&o당신의 탈리스맨은 발사체를 반사했다.\n" + wizard: "&a&o당신의 탈리스맨은 당신에게 더 나은 행운 레벨을 주었지만, 아마도 몇몇 다른 인첸트 레벨도 낮췄을 것입니다.\n" + soulbound-rune: + fail: "&c한 번에 한 항목만 영혼에 묶을 수 있습니다." + success: "&a이 아이템을 당신의 영혼에 성공적으로 묶었습니다! 당신은 죽을 때 그것을 간직할 것입니다." + research: + start: "&7고대의 정령들은 당신의 귀에 신비한 말을 속삭입니다!" + progress: "&b%research% &e(%progress%)&7에 대해 궁금해하기 시작합니다." + fire-extinguish: "&7당신은 스스로를 소멸시켰습니다." + cannot-place: "&c저 블럭은 그곳에 둘 수 없어요!" + no-pvp: "&c여기선 pvp 할 수 없어요!" + radiation: "&4당신은 치명적인 방사능에 노출되었습니다! &c방사성 물질을 제거하거나 전체 유해 물질 정장을 갖추세요!" + opening-guide: "&b가이드를 여는 데 몇 초 정도 걸릴 수 있습니다." + opening-backpack: "&b배낭을 여는 데 몇 초 정도 걸릴 수 있습니다..." + no-iron-golem-heal: "&c그건 철괴가 아닙니다. 아이언 골렘을 치료하기 위해 이것을 사용할 수는 없습니다!\n" + link-prompt: "&e여기를 클릭:" + diet-cookie: "&e당신은 매우 가벼워지기 시작했어요...\n" + fortune-cookie: + - "&7도와주세요, 저는 행운 쿠키 공장에 갇혔어요!" + - "&7당신은 내일 죽을 거예요... 크리퍼에 의해서요." + - "&7당신 인생의 어느 시점에 나쁜 일이 일어날 거예요!!!" + - "&7다음 주에 당신은 이것이 현실 세계가 아니라는 것을 알게 될 것입니다. 당신은 컴퓨터 게임에 빠져 있습니다." + - "&7이 쿠키는 몇 초 안에 맛있을 거예요." + - '&7마지막으로 듣게 될 말은 "EXTERMINATE!"입니다.!" + +' + - "&7무슨 일을 하든지, 크리퍼를 껴안지 마세요... 나는 그것을 시도해봤어요. 기분은 좋지만, 그럴 만한 가치는 없어요.\n" + - "&742. 정답은 42입니다.\n" + - "&7하루에 월시가 있으면 그 문제를 피할 수 있어요.\n" + - "&7절대 아래로 파고들지 마세요!\n" + - "&7살이지만 살 상처!" + - "&7항상 인생의 밝은면을 바라보세요!" + - "&7이것은 실제로 쿠키가 아닌 비스킷이었습니다." + - "&7네온 사인이 LIT입니다!" + piglin-barter: "&4슬라임 펀 아이템을 사용하여 piglins와 물물 교환을 할 수 없습니다" + enchantment-rune: + fail: "&c이 아이템을 마법 부여 할 수 없습니다." + no-enchantment: "&c이 항목에 해당하는 마법을 찾을 수 없습니다." + success: "&a이 아이템에 무작위로 적용 가능한 마법 부여를 성공적으로 적용했습니다." + tape-measure: + no-anchor: "&c측정을 시작하기 전에 앵커를 설정해야합니다!" + wrong-world: "&c앵커가 다른 세상에있는 것 같습니다." + distance: "&7측정이 완료되었습니다. &e거리 : %distance%" + anchor-set: "&a앵커를 설정했습니다 : &e%anchor%" +machines: + pattern-not-found: "&e죄송합니다. 이 조합법를 인식할 수 없습니다. 디스펜서에 항목을 올바른 패턴으로 배치해 주십시오." + unknown-material: "&e죄송합니다. 디스펜서에 있는 항목을 인식할 수 없습니다. 제가 알고 있는 아이템을 좀 넣어 주세요." + wrong-item: "&e죄송합니다. 오른쪽 클릭하신 항목을 인식할 수 없습니다. 조합법를 확인하고 사용할 수 있는 항목을 확인합니다." + full-inventory: "&e죄송합니다. 재고가 너무 꽉 찼습니다!\n" + in-use: "&c이 블록의 인벤토리는 현재 다른 플레이어에 의해 열립니다." + ignition-chamber-no-flint: "&c점화 챔버에 라이터가 없습니다." + ANCIENT_ALTAR: + not-enough-pedestals: "&4Altar는 필요한 수의 Pedestals &c(%pedestals% / 8)로 둘러싸여 있지 + 않습니다.\n" + unknown-catalyst: "&4알 수 없는 촉매입니다! &c대신 올바른 조합법를 사용하세요!" + unknown-recipe: "&4알 수 없는 조합법입니다! &c대신 올바른 조합법를 사용하세요!" + ANCIENT_PEDESTAL: + obstructed: "&4페달이 막혔어요! 받침대 위에 있는 것은 모두 &c제거&4하세요!\n" + HOLOGRAM_PROJECTOR: + enter-text: "&7원하는 홀로그램 텍스트를 대화 상자에 입력해 주십시오. &r(색상 코드가 지원됨!)" + inventory-title: 홀로그램 편집기 + ELEVATOR: + no-destinations: "&4대상을 찾을 수 없습니다.\n" + pick-a-floor: "&3- 바닥을 고르세요 -\n" + current-floor: "&e현재 사용 중인 층은 다음과 같습니다:" + click-to-teleport: "&e해당 층으로 텔레포트를 하실려면 클릭:" + enter-name: "&7원하는 플로어 이름을 채팅에 입력하십시오. &r(색상 코드가 지원됨!)" + named: "&2이 층의 이름을 성공적으로 지정함: &r%floor%" + TELEPORTER: + teleporting: "&3텔레포팅중..." + teleported: "&3텔레포트!" + cancelled: "&4텔레포트를 취소!" + invulnerability: "&b&l30초간의 불굴의 시간을 주셨습니다!" + gui: + title: 당신의 경유지 + tooltip: 텔레포트 클릭 + time: 예상시간 + CARGO_NODES: + must-be-placed: "&4상자 또는 기계 위에 놓아야 한다!\n" + GPS_CONTROL_PANEL: + title: GPS - 제어판 + transmitters: GPS 개요 + waypoints: 웨이포인트 개요 + INDUSTRIAL_MINER: + no-fuel: "&c귀하의 산업용 채광 장치의 연료가 부족합니다! 연료를 위 상자에 넣으십시오." + piston-facing: "&c귀하의 산업용 채광 장치는 피스톤을 위로 향하게해야합니다!" + piston-space: "&c두 피스톤에는 그 위에 빈 블록이 있어야합니다!" + destroyed: "&c귀하의 산업 채광 장치가 파괴 된 것 같습니다." + already-running: "&c이 산업용 채광 장치는 이미 실행 중입니다!" + full-chest: "&c산업용 채광 장치의 상자가 가득 찼습니다!" + no-permission: "&4여기에서 산업용 채광 장치를 운영 할 권한이없는 것 같습니다!" + finished: "&e산업용 채광 장치가 완료되었습니다! 총 광석 %ores%을 (를) 획득했습니다!" +anvil: + not-working: "&4슬라임펀 아이템은 모루에서 사용할 수 없다!" +backpack: + already-open: "&c죄송합니다. 이 백팩은 다른 곳에 열려 있습니다!" + no-stack: "&c백팩을 쌓을 수 없습니다." +workbench: + not-enhanced: "&4일반 작업대에서는 Slimefun 아이템을 사용할 수 없습니다." +gps: + deathpoint: "&4데스포인트 &7%date%" + waypoint: + new: "&e대화에서 새 waypoint 이름을 입력하십시오. &7(색상 코드 지원!)\n" + added: "&a새로운 waypoint를 성공적으로 추가\n" + max: "&4waypoint의 최대 양에 도달하셨습니다.\n" + insufficient-complexity: + - "&4GPS 네트워크의 복잡성 부족: &c%complexity%" + - "&4a)GPS 네트워크가 아직 설정되지 않음\n" + - "&4b) GPS 네트워크가 충분히 복잡하지 않습니다.\n" + geo: + scan-required: "&4GEO-Scan이 필요합니다! 먼저 GEO-Scanner를 사용하여 이 청크를 스캔하세요!\n" +inventory: + no-access: "&4이 블록에 액세스할 수 없습니다." +android: + started: "&7Android가 스크립트 실행을 재개했습니다.\n" + stopped: "&7Android가 스크립트를 일시 중지했습니다.\n" + scripts: + already-uploaded: "&4이 스크립트는 이미 업로드되었습니다.\n" + instructions: + START: "&2시작 스크립트\n" + REPEAT: "&9반복 스크립트\n" + WAIT: "&e0.5초간 대기\n" + GO_FORWARD: "&7전진하다" + GO_UP: "&7위로 이동\n" + GO_DOWN: "&7아래로 이동\n" + TURN_LEFT: "&7왼쪽으로 돌다\n" + TURN_RIGHT: "&7오른쪽으로 돌다" + DIG_UP: "&b위로 파다" + DIG_FORWARD: "&b앞으로 파다" + DIG_DOWN: "&b아래로 파다" + MOVE_AND_DIG_UP: "&b위쪽으로 이동 & 파기" + MOVE_AND_DIG_FORWARD: "&b앞으로 이동 & 파기" + MOVE_AND_DIG_DOWN: "&b아래로 이동 & 파기" + ATTACK_MOBS_ANIMALS: "&4공격 &c(호스틸 몹 & 동물)\n" + ATTACK_MOBS: "&4공격 &c(호스틸 몹)\n" + ATTACK_ANIMALS: "&4공격 &c(동물)\n" + ATTACK_ANIMALS_ADULT: "&4공격 &c(동물&7[성인]&c)\n" + CHOP_TREE: "&c잘라내기 및 대체제\n" + CATCH_FISH: "&b캐치 피시\n" + FARM_FORWARD: "&b수확 및 대체품목\n" + FARM_DOWN: "&b수확 및 교체 &7(밑면 차단)\n" + FARM_EXOTIC_FORWARD: "&b고급 수집 및 복제품" + FARM_EXOTIC_DOWN: "&b고급 수집 및 복제품 &7(밑면 차단)" + INTERFACE_ITEMS: "&9인벤토리 내용을 대면 인터페이스로 푸시" + INTERFACE_FUEL: "&c대면된 인터페이스에서 연료 꺼내기\n" + enter-name: + - + - "&e스크립트의 이름을 입력하십시오.\n" + uploaded: + - "&b업로드중..." + - "& a 성공적으로 스크립트를 업로드했습니다!" + rating: + own: "& 4 자신의 스크립트를 평가할 수 없습니다!" + already: "& 4이 스크립트에 대한 평가를 이미 남겼습니다!" + editor: 스크립트 편집기 +languages: + default: 서버 기본값 + en: 영어 + de: 독일어 + fr: 프랑스 + it: 이탈리아어 + es: 스페인어 + pl: 폴란드어 + sv: 스웨덴어 + nl: 네덜란드어 + cs: 체코어 + hu: 헝가리어 + lv: 라트비아어 + ru: 러시아어 + sk: 슬로바키아어 + zh-TW: 중국어 (대만) + vi: 베트남어 + id: 인도네시아어 + zh-CN: 중국어 (중국) + el: 그리스 어 + he: 헤브라이어 + ar: 아라비아어 + af: 아프리카 어 + da: 덴마크어 + fi: 핀란드어 + uk: 우크라이나어 + ms: 말레이어 + 'no': 노르웨이어 + ja: 일본어 + fa: 페르시아어 + th: 태국어 + ro: 루마니아어 + pt: 포르투갈어 (포르투갈) + pt-BR: 포르투갈어 (브라질) + bg: 불가리아어 + ko: 한국어 + tr: 터키어 + hr: 크로아티아어 + mk: 마케도니아어 + sr: 세르비아어 + be: 벨로루시어 + tl: 타갈로그어 diff --git a/src/main/resources/languages/messages_ru.yml b/src/main/resources/languages/messages_ru.yml index 4b17e07f9..f1989d92a 100644 --- a/src/main/resources/languages/messages_ru.yml +++ b/src/main/resources/languages/messages_ru.yml @@ -40,6 +40,12 @@ guide: select: Нажмите для выбора этого языка select-default: Нажмите для выбора языка по умолчанию selected-language: 'Сейчас выбрано:' + change: Нажмите для выбора нового языка + description: + - "&7У Вас теперь есть возможность" + - "&7выбрать язык, на котором Slimefun" + - "&7будет отправлять сообщения." + - "&7Предметы пока не могут быть переведены." title: main: Руководство Slimefun settings: Информация и настройки @@ -49,6 +55,7 @@ guide: addons: Дополнения к Slimefun4 bugs: Отчёты об ошибках source: Исходный код + versions: Установленные версии credits: commit: Коммит commits: Коммитов @@ -58,6 +65,12 @@ guide: resourcepack: "&cТекстурщик" translator: "&9Локализатор" profile-link: Нажмите, чтобы посетить GitHub профиль + open: Нажмите для просмотра списка авторов + description: + - "&7Slimefun — проект с открытым исходным кодом," + - "&7и поддерживается большим сообществом хороших людей." + - "&7Свыше &e%contributors% &7людей работали над" + - "&7Slimefun за все эти долгие годы." pages: previous: Предыдущая страница next: Следующая страница @@ -79,6 +92,7 @@ guide: - Для начала Вы должны - разблокировать все предметы - из следующих категорий + work-in-progress: Эта функция ещё не полностью завершена! messages: not-researched: "&4Вам не хватает знаний, чтобы понять это" not-enough-xp: "&4У Вас недостаточно опыта, чтобы исследовать это" @@ -96,7 +110,6 @@ messages: not-valid-research: "&4%research% &cне является допустимым исследованием!" give-research: '&bВы выдали игроку %player% исследование &7"%research%&7"' hungry: "&cВы слишком голодны для этого!" - mode-change: "&b%device% | Режим изменён на: &9%mode%" disabled-in-world: "&4&lДанный предмет отключен в этом мире" disabled-item: "&4&lЭтот предмет был отключен! Где Вы вообще его взяли?" no-tome-yourself: "&cВы не можете использовать &4том обмена знаниями &cна себе…" @@ -151,6 +164,20 @@ messages: - "&7Всегда смотрите на светлую сторону жизни!" - "&7Вы съели странное печенье, до жути напоминающее бисквит" - "&7Неоновые таблички просто ШИК!" + piglin-barter: "&4Вы не можете торговать с пиглинами, используя Slimefun предметы" + enchantment-rune: + fail: "&cВы не можете зачаровать этот предмет." + no-enchantment: "&cНе удалось найти подходящее зачарование для этого предмета." + success: "&aВы успешно применили случайное зачарование к этому предмету." + tape-measure: + no-anchor: "&cВы должны установить якорь, прежде чем начать измерение!" + wrong-world: "&cВаш якорь находится в другом мире!" + distance: "&7Измерение завершено. &eРасстояние: %distance%" + anchor-set: "&aЯкорь успешно установлен:&e %anchor%" + multi-tool: + mode-change: "&bРежим «%device%» изменён на: &9%mode%" + not-shears: "&cМультиинструмент не может быть использован в качестве ножниц!" + mode-change: "&b%device% | Режим изменён на: &9%mode%" machines: pattern-not-found: "&eК сожалению, не удалось распознать этот рецепт. Пожалуйста, разложите предметы в верной последовательности в раздатчик." @@ -220,6 +247,7 @@ gps: цветовые коды!)" added: "&aКонтрольная точка успешно добавлена" max: "&4Вы достигли максимального количества контрольных точек" + duplicate: "&4Вы уже создали контрольную точку с таким названием: &f%waypoint%" insufficient-complexity: - "&4Недостаточная общая сила сигнала GPS сети: &c%complexity%" - "&4а) Ваша GPS сеть пока что не подключена" @@ -292,6 +320,7 @@ languages: zh-CN: Китайский (Китай) el: Греческий he: Иврит + pt-BR: Португальский (Бразилия) ar: Арабский af: Бурский da: Датский @@ -304,7 +333,6 @@ languages: th: Тайский ro: Румынский pt: Португальский (Португалия) - pt-BR: Португальский (Бразилия) bg: Болгарский ko: Корейский tr: Турецкий @@ -313,5 +341,9 @@ languages: sr: Сербский be: Белорусский tl: Тагальский +brewing_stand: + not-working: "&4Вы не можете использовать Slimefun предметы в варочной стойке!" +villagers: + no-trading: "&4Вы не можете торговаться с крестьянами Slimefun предметами!" miner: no-ores: "&eК сожалению, не удалось найти какую-либо руду поблизости!" diff --git a/src/main/resources/languages/messages_tl.yml b/src/main/resources/languages/messages_tl.yml index 644547da4..fa284c8f7 100644 --- a/src/main/resources/languages/messages_tl.yml +++ b/src/main/resources/languages/messages_tl.yml @@ -38,6 +38,12 @@ guide: select: I-click ito upang piliin ang wikang ito. select-default: I-click ito upang piliin ang default na wika. selected-language: 'Kasalukuyang pinili:' + change: Mag-click upang pumili ng bagong wika. + description: + - "&7Meron ka nang pagpipilian upang pumili" + - "&7ng wika kung saan ang Slimefun" + - "&7ay may ipapakita sa iyo. Ang mga" + - "&7items ay bawal pa i-translate sa ngayon." title: main: Slimefun Guide settings: Mga Settings & Impormasyon @@ -77,6 +83,7 @@ guide: - Upang i-unlock ang kategoryang ito, - kailangang i-unlock ang lahat ng mga item mula sa - sumusunod na kategorya. + work-in-progress: Ang feature na ito ay hindi pa tapos! messages: not-researched: "&4Kulang ang iyong Knowledge upang ito'y maintindihan." not-enough-xp: "&4Kulang ang iyong XP upang ito'y ma-unlock." @@ -94,7 +101,6 @@ messages: not-valid-research: "&4%research% &cay hindi valid na Research!" give-research: '&bBinigyan mo si %player% ng Research &7"%research%&7"' hungry: "&cIkaw ay sobrang gutom para gawin ito!" - mode-change: "&b%device% mode ay pinalitan ng: &9%mode%" disabled-in-world: "&4&lDinisable ang Aytem sa world na ito." disabled-item: "&4&lDinisable ang Aytem na ito! Paano mo ito nakuha?" no-tome-yourself: "&cHindi mo magagamit ang &4Tome of Knowledge &cpara sa'yo..." @@ -152,6 +158,24 @@ messages: - "&7Laging tumingin sa maliwanag na bahagi ng buhay!" - "&7Biskwit pala ito at hindi ito siya Kukis." - "&7Ang astig ng mga Neon Signs!" + piglin-barter: "&4Hindi ka maaaring mag-barter sa mga piglins gamit ang mga item + ng Slimefun." + enchantment-rune: + fail: "&cAng aytem na ito ay bawal i-enchant." + no-enchantment: "&cHindi makahanap ng anuman na puwedeng enchantment para sa aytem + na ito." + success: "&aMatagumpay mong na-apply ang isang random na naaangkop na enchantment + sa aytem na ito." + tape-measure: + no-anchor: "&cKailangan mong magtakda ng isang angkla bago ka makapagsimula upang + masukat!" + wrong-world: "&cAng iyong angkla ay tila nasa ibang mundo!" + distance: "&7Measurement taken. &eDistansiya: %distance%" + anchor-set: "&aMatagumpay na na-set ang angla:&e %anchor%" + multi-tool: + mode-change: "&b%device% napalitan ang mode sa: &9%mode%" + not-shears: "&cBawal gamitin ang Multi-Tool bilang shears!" + mode-change: "&b%device% mode ay pinalitan ng: &9%mode%" machines: pattern-not-found: "&ePasensiya na, hindi ko maintindihan ang Recipe na ito. Pakilagay ang mga Aytem sa tamang pattern sa loob ng Dispense." @@ -227,6 +251,7 @@ gps: chat. &7(Supported ang Color Codes!)" added: "&aTagumpay ang pag-add ng bagong waypoint." max: "&4Naabot mo na ang maximum amount ng waypoints." + duplicate: "&4Nakagawa ka na ng isang waypoint na pinangalanan: & f%waypoint%" insufficient-complexity: - "&4Kulang ang GPS Network Complexity: &c%complexity%" - "&4a) Wala ka pang GPS Network setup." @@ -320,3 +345,7 @@ languages: sr: Serbian be: Belarusian tl: Tagalog/Filipino +brewing_stand: + not-working: "&4Hindi ka maaaring gumamit ng mga Item ng Slimefun sa Brewing Stand!" +villagers: + no-trading: "&4Hindi ka maaaring mag-trade ng mga Slimefun Items sa mga villagers!" diff --git a/src/main/resources/languages/messages_tr.yml b/src/main/resources/languages/messages_tr.yml index 3dd4e8ea2..56cf6ba96 100644 --- a/src/main/resources/languages/messages_tr.yml +++ b/src/main/resources/languages/messages_tr.yml @@ -41,6 +41,12 @@ guide: select: Bu dili seçmek için tıklayın select-default: Varsayılan dili seçmek için tıklayın selected-language: 'Şuan seçili:' + change: Yeni bir dil seçmek için tıklayın + description: + - "&7Artık Slimefun içerisinde size" + - "&7sunulacak olan dilinizi" + - "&7değiştirebilirsiniz. Henüz eşyalar" + - "&7çevrilememektedir." title: main: Slimefun Rehberi settings: Ayarlar & Bilgi @@ -50,6 +56,7 @@ guide: addons: Slimefun4 için Eklentiler bugs: Hata Raporları source: Kaynak Kodu + versions: Yüklü sürümler credits: commit: Geliştiirme commits: Geliştirmeler @@ -59,6 +66,12 @@ guide: resourcepack: "&cKaynak Paketi Tasarımcısı" translator: "&9Çevirmen" profile-link: GitHubdaki profillerini ziyaret etmek için tıklayın + open: Bize katkıda bulunanları görmek için tıklayın + description: + - "&7Slimefun açık kaynak kodlu bir projedir" + - "&7ve büyük bir topluluk tarafından geliştirilir." + - "&e%contributors%&7den(dan) fazla kişi yıllar" + - "&7boyunca Slimefun'a katkıda bulundu." pages: previous: Önceki sayfa next: Sonraki sayfa @@ -80,6 +93,7 @@ guide: - Bu kategoriyi açmak için - aşağıdaki kategorilerde bulunan - bütün eşyaları açın + work-in-progress: Bu özellik henüz tamamlanmadı! messages: not-researched: "&4Bunu anlayacak kadar bilgin yok" not-enough-xp: "&4Bunun kilidini açmak için yeterli XP niz yok" @@ -96,7 +110,6 @@ messages: not-valid-research: "&4%research% &cgeçerli bir araştırma değil!" give-research: '&b%player% adlı oyuncu için bir araştırmayı açtın: &7"%research%&7"' hungry: "&cBunu yapmak için çok açsın!" - mode-change: "&b%device% modu değişti: &9%mode%" disabled-in-world: "&4&lBu eşya bu dünyada devre dışı bırakıldı." disabled-item: "&4&lBu eşya devre dışı bırakıldı! Bunu nasıl aldın?" no-tome-yourself: "&4Tome of Knowledge &cı kendin için kullanamazsın..." @@ -149,6 +162,20 @@ messages: - "&7Daima hayatın parlak tarafından bak!" - "&7Bu aslında bir Bisküvi idi, Kurabiye değil." - "&7Neon levhalar ışık yayar!" + piglin-barter: "&4Slimefun eşyalarıyla, piglinlerle ticaret yapamazsın" + enchantment-rune: + fail: "&cYou eşyayı büyüleyemezsin." + no-enchantment: "&cBu eşya için uygun bir büyü bulunamadı." + success: "&aBaşarılı bir şekilde bu eşyaya rastgele bir büyü uyguladınız." + tape-measure: + no-anchor: "&cÖlçüm yapmadan önce bir nokta seçmelisiniz!" + wrong-world: "&cSeçtiğiniz nokta başka bir dünyada gözüküyor!" + distance: "&7Ölçüm yapıldı. &eUzaklık: %distance%" + anchor-set: "&aBaşarılı bir şekilde bir nokta seçildi:&e %anchor%" + multi-tool: + mode-change: "&b%device% modül değiştirildi: &9%mode%" + not-shears: "&cBir Multi Tool makas olarak kullanılamaz!" + mode-change: "&b%device% modu değişti: &9%mode%" machines: pattern-not-found: "&eÜzgünüm, bu tarifi tanıyamadım. Lütfen Eşyaları Dağıtıcıya doğru şekilde yerleştirin." @@ -215,6 +242,7 @@ gps: new: "&eLütfen sohbette yeni yer noktanız için bir ad yazın. &7(Renk Kodları destekleniyor!)" added: "&aYeni bir yer noktası başarıyla eklendi" max: "&4Maksimum yer noktası sayısına ulaştınız" + duplicate: "&4Bu adla zaten bir yer noktası yarattınız: &f%waypoint%" insufficient-complexity: - "&4Yetersiz GPS Ağ Gücü: &c%complexity%" - "&4a) Henüz bir GPS Ağı kurulumunuz yok" @@ -308,5 +336,9 @@ languages: sr: Sırpça be: Belarusça tl: Tagalog +brewing_stand: + not-working: "&4Slimefun eşyalarını simya standında kullanamazsın!" +villagers: + no-trading: "&4Köylülerle Slimefun eşyalarını kullanarak ticaret yapamazsın!" miner: no-ores: "&eÜzgünüm, yakınlarda herhangi bir cevher bulamadım!" diff --git a/src/main/resources/languages/messages_uk.yml b/src/main/resources/languages/messages_uk.yml index 46dda9c0a..cf34438e5 100644 --- a/src/main/resources/languages/messages_uk.yml +++ b/src/main/resources/languages/messages_uk.yml @@ -147,6 +147,7 @@ messages: - "&7Завжди дивіться на світлу сторону життя!" - "&7Цього разу попався бісквіт, а не печиво" - "&7Неонові таблички просто ШИК!" + piglin-barter: "&4Ви не можете торгувати з піґлінами, використовуючи Slimefun предмети" machines: pattern-not-found: "&eНа жаль, не вдалось розпізнати цей рецепт. Будь ласка, розмістіть предмети у правильній послідовності у роздавач." @@ -287,7 +288,6 @@ languages: zh-CN: Китайська (Китай) el: Грецька he: Іврит - pt: Португальська (Португалія) pt-BR: Португальська (Бразилія) ar: Арабська af: Бурська @@ -300,6 +300,7 @@ languages: fa: Перська th: Тайська ro: Румунська + pt: Португальська (Португалія) bg: Болгарська ko: Корейська tr: Турецька diff --git a/src/main/resources/languages/messages_zh-CN.yml b/src/main/resources/languages/messages_zh-CN.yml index 080186a7d..458152fee 100644 --- a/src/main/resources/languages/messages_zh-CN.yml +++ b/src/main/resources/languages/messages_zh-CN.yml @@ -143,6 +143,16 @@ messages: - "&7要总是看着生活中光明的一面!" - "&7这一块其实是饼干而不是曲奇" - "&7霓虹灯亮起来了!" + piglin-barter: "&4你不能使用 Slimefun 的物品和猪灵以物换物" + enchantment-rune: + fail: "&c你不能附魔这个物品." + no-enchantment: "&c无法找到此物品可用的附魔属性." + success: "&a成功为此物品添加了随机的可用附魔属性." + tape-measure: + no-anchor: "&c在开始测量之前请先选定测量起点!" + wrong-world: "&c你设置的起点似乎在另一个世界!" + distance: "&7已测量到距离, &e为: %distance%" + anchor-set: "&a成功在 &e %anchor% &a设置了测量起点" machines: pattern-not-found: "&e抱歉, 你记错合成表了吧. 这不是一个正确的合成配方, 请检查发射器里放置物品的顺序." unknown-material: "&e抱歉, 我无法识别在发射器里的物品. 请按照合成配方放置物品." @@ -203,6 +213,7 @@ gps: new: "&e给你的路径点起个名字吧 &7(支持彩色代码!)" added: "&a成功添加了新的传送点" max: "&4你已到达设置传送点个数的最大上限" + duplicate: "&4你已经创建了一个相同名字的传送点了: &f%waypoint%" insufficient-complexity: - "&4GPS网络复杂度不足: &c%complexity%" - "&4a) 你还没有设置一个 GPS 网络" @@ -274,6 +285,7 @@ languages: zh-CN: 简体中文 (中国) el: 希腊语 he: 希伯来语 + pt: 葡萄牙语 (葡萄牙) ar: 阿拉伯语 af: 南非语 da: 丹麦语 @@ -285,7 +297,6 @@ languages: fa: 波斯语 th: 泰语 ro: 罗马尼亚语 - pt: 葡萄牙语 (葡萄牙) pt-BR: 葡萄牙语 (巴西) bg: 保加利亚语 ko: 韩语 @@ -295,5 +306,9 @@ languages: sr: 塞尔维亚语 be: 白俄罗斯语 tl: 他加禄语 +brewing_stand: + not-working: "&4你不能在酿造台中使用 Slimefun 物品!" +villagers: + no-trading: "&4你不能用 Slimefun 的物品和村民交易!" miner: no-ores: "&e抱歉, 周围找不到矿石了!" diff --git a/src/main/resources/languages/recipes_de.yml b/src/main/resources/languages/recipes_de.yml index 7a97f8ce0..c734d20ff 100644 --- a/src/main/resources/languages/recipes_de.yml +++ b/src/main/resources/languages/recipes_de.yml @@ -1,145 +1,107 @@ --- -minecraft: - blasting: - lore: - - Schmelz dieses Item in einem Schmelzofen, - - um dein Item zu erhalten. - name: Schmelzofen-Rezept - campfire: - lore: - - Schmelz dieses Item über einem Lagerfeuer, - - um dein Item zu erhalten. - name: Lagerfeuer-Rezept - furnace: - lore: - - Schmelz dieses Item in einem Ofen, - - um dein Item zu erhalten. - name: Ofen-Rezept - shaped: - lore: - - Crafte das Item wie gezeigt - - in einer normalen Werkbank. - - Die Form ist hierbei sehr wichtig. - name: Werkbankrezept (Geformt) - shapeless: - lore: - - Crafte das Item wie gezeigt - - in einer normalen Werkbank. - - Dieses Rezept ist formlos. - name: Werkbankrezept (Formlos) - smoking: - lore: - - Schmelz dieses Item in einem Räucherofen, - - um dein Item zu erhalten. - name: Räucherofen-Rezept - stonecutting: - lore: - - Crafte dieses Item wie gezeigt - - mithilfe einer Steinsäge. - name: Steinsägen-Rezept slimefun: - ancient_altar: + multiblock: + name: Multiblock lore: - - Crafte das Item wie gezeigt - - mithilfe des "Ancient Altar". - - Für mehr Infos, schaue beim "Ancient Altar" nach. - name: Ancient Altar - armor_forge: - lore: - - Crafte das Item wie gezeigt - - in einer "Armor Forge". - name: Armor Forge - compressor: - lore: - - Crafte das Item wie gezeigt - - in einem "Compressor". - name: Compressor + - Baue die gezeigte Struktur, wie + - man sie sieht. Sie wird nicht gecraftet. enhanced_crafting_table: + name: Enhanced Crafting Table lore: - Crafte das Item wie gezeigt - im "Enhanced Crafting Table". - Eine normale Werkbank genügt nicht! - name: Enhanced Crafting Table - food_composter: + armor_forge: + name: Armor Forge lore: - Crafte das Item wie gezeigt - - in einem "Food Composter". - name: Food Composter - food_fabricator: - lore: - - Crafte das Item wie gezeigt - - in einem "Food Fabricator". - name: Food Fabricator - freezer: - lore: - - Crafte das Item wie gezeigt - - in einem "Freezer". - name: Freezer - geo_miner: - lore: - - Dieses Item kann mittels eines - - '"GEO Miner" erhalten werden.' - name: GEO Miner - gold_pan: - lore: - - Benutze eine "Gold Pan", um - - dieses Item zu erhalten. - name: Gold Pan + - in einer "Armor Forge". grind_stone: + name: Grind Stone lore: - Crafte das Item wie gezeigt - mit einem "Grind Stone". - name: Grind Stone - heated_pressure_chamber: - lore: - - Crafte das Item wie gezeigt - - mit einer "Heated Pressure Chamber". - name: Heated Pressure Chamber - juicer: - lore: - - Crafte diesen Saft wie gezeigt - - in einem "Juicer" - name: Juicer - magic_workbench: - lore: - - Crafte das Item wie gezeigt - - in einer "Magic Workbench". - name: Magic Workbench - mob_drop: - lore: - - Töte den angebenen Mob - - und er wird das Item fallen lassen - name: Mob-Drop - multiblock: - lore: - - Baue die gezeigte Struktur, wie - - man sie sieht. Sie wird nicht gecraftet. - name: Multiblock - nuclear_reactor: - lore: - - Dieses Item ist ein Nebenprodukt vom - - Betrieb eines "Nuclear Reactor". - name: Nuclear Reactor - ore_crusher: - lore: - - Crafte das Item wie gezeigt - - mit einem "Ore Crusher". - name: Ore Crusher - ore_washer: - lore: - - Crafte das Item wie gezeigt - - mit einem "Ore Washer". - name: Ore Washer - pressure_chamber: - lore: - - Crafte das Item wie gezeigt - - in einer "Pressure Chamber". - name: Pressure Chamber smeltery: + name: Smeltery lore: - Crafte das Item wie gezeigt - in einer "Smeltery". - name: Smeltery + ore_crusher: + name: Ore Crusher + lore: + - Crafte das Item wie gezeigt + - mit einem "Ore Crusher". + mob_drop: + name: Mob-Drop + lore: + - Töte den angebenen Mob + - und er wird das Item fallen lassen + gold_pan: + name: Gold Pan + lore: + - Benutze eine "Gold Pan", um + - dieses Item zu erhalten. + compressor: + name: Compressor + lore: + - Crafte das Item wie gezeigt + - in einem "Compressor". + pressure_chamber: + name: Pressure Chamber + lore: + - Crafte das Item wie gezeigt + - in einer "Pressure Chamber". + ore_washer: + name: Ore Washer + lore: + - Crafte das Item wie gezeigt + - mit einem "Ore Washer". + juicer: + name: Juicer + lore: + - Crafte diesen Saft wie gezeigt + - in einem "Juicer" + magic_workbench: + name: Magic Workbench + lore: + - Crafte das Item wie gezeigt + - in einer "Magic Workbench". + ancient_altar: + name: Ancient Altar + lore: + - Crafte das Item wie gezeigt + - mithilfe des "Ancient Altar". + - Für mehr Infos, schaue beim "Ancient Altar" nach. + heated_pressure_chamber: + name: Heated Pressure Chamber + lore: + - Crafte das Item wie gezeigt + - mit einer "Heated Pressure Chamber". + food_fabricator: + name: Food Fabricator + lore: + - Crafte das Item wie gezeigt + - in einem "Food Fabricator". + food_composter: + name: Food Composter + lore: + - Crafte das Item wie gezeigt + - in einem "Food Composter". + freezer: + name: Freezer + lore: + - Crafte das Item wie gezeigt + - in einem "Freezer". + geo_miner: + name: GEO Miner + lore: + - Dieses Item kann mittels eines + - '"GEO Miner" erhalten werden.' + nuclear_reactor: + name: Nuclear Reactor + lore: + - Dieses Item ist ein Nebenprodukt vom + - Betrieb eines "Nuclear Reactor". oil_pump: name: Oil Pump lore: @@ -156,3 +118,51 @@ slimefun: lore: - Crafte das Item wie gezeigt - in einer "Refinery". + barter_drop: + name: Piglin Tauschhandel + lore: + - Tausche einen Goldbarren mit Piglins, um + - das gewünschte Item zu erhalten +minecraft: + shaped: + name: Werkbankrezept (Geformt) + lore: + - Crafte das Item wie gezeigt + - in einer normalen Werkbank. + - Die Form ist hierbei sehr wichtig. + shapeless: + name: Werkbankrezept (Formlos) + lore: + - Crafte das Item wie gezeigt + - in einer normalen Werkbank. + - Dieses Rezept ist formlos. + furnace: + name: Ofen-Rezept + lore: + - Schmelz dieses Item in einem Ofen, + - um dein Item zu erhalten. + blasting: + name: Schmelzofen-Rezept + lore: + - Schmelz dieses Item in einem Schmelzofen, + - um dein Item zu erhalten. + smoking: + name: Räucherofen-Rezept + lore: + - Schmelz dieses Item in einem Räucherofen, + - um dein Item zu erhalten. + campfire: + name: Lagerfeuer-Rezept + lore: + - Schmelz dieses Item über einem Lagerfeuer, + - um dein Item zu erhalten. + stonecutting: + name: Steinsägen-Rezept + lore: + - Crafte dieses Item wie gezeigt + - mithilfe einer Steinsäge. + smithing: + name: Schmiede Tisch + lore: + - Crafte das Item wie gezeigt + - mithilfe eines Schmiede Tisches diff --git a/src/main/resources/languages/recipes_en.yml b/src/main/resources/languages/recipes_en.yml index 9f82f5b76..fc7045efd 100644 --- a/src/main/resources/languages/recipes_en.yml +++ b/src/main/resources/languages/recipes_en.yml @@ -141,6 +141,12 @@ slimefun: - 'Craft this Item as shown' - 'using a Refinery' + barter_drop: + name: 'Piglin Bartering Drop' + lore: + - 'Barter with Piglins using' + - 'Gold Ingots to obtain this Item' + minecraft: shaped: diff --git a/src/main/resources/languages/recipes_es.yml b/src/main/resources/languages/recipes_es.yml index 8dcb8c432..0bd28656d 100644 --- a/src/main/resources/languages/recipes_es.yml +++ b/src/main/resources/languages/recipes_es.yml @@ -118,6 +118,11 @@ slimefun: lore: - Haz este objeto tal como se muestra - usando una Refinery + barter_drop: + name: Piglin Bartering Drop + lore: + - Troca con Piglins usando + - Lingotes de Oro para obtener este objeto minecraft: shaped: name: Receta de Crafteo con forma diff --git a/src/main/resources/languages/recipes_hu.yml b/src/main/resources/languages/recipes_hu.yml index 1992ade71..899b0e21f 100644 --- a/src/main/resources/languages/recipes_hu.yml +++ b/src/main/resources/languages/recipes_hu.yml @@ -32,7 +32,7 @@ slimefun: - Készítsd el ezt a Tárgyat az ábra alapján - egy Ore Crusher segítségével mob_drop: - name: Mob Drop + name: Élőlény Dobja lore: - Öld meg ezt az Élőlényt, - hogy megszerezd ezt a tárgyat @@ -118,6 +118,11 @@ slimefun: lore: - Készítsd el ezt a Tárgyat az ábra alapján - egy Refinery segítségével + barter_drop: + name: Piglinek Dobják Cserélésnél + lore: + - Cseréld el a Piglenekkel Aranyrudakat, + - hogy megszerezd ezt a tárgyat minecraft: shaped: name: Barkácsrecept Forma diff --git a/src/main/resources/languages/recipes_ru.yml b/src/main/resources/languages/recipes_ru.yml index a888b0340..99781cb13 100644 --- a/src/main/resources/languages/recipes_ru.yml +++ b/src/main/resources/languages/recipes_ru.yml @@ -118,6 +118,11 @@ slimefun: lore: - Создаётся так, как показано, - используя Refinery + barter_drop: + name: Предмет товарообмена с пиглином + lore: + - 'Обменяйтесь с пиглином, используя золотые ' + - слитки, чтобы заполучить этот предмет minecraft: shaped: name: Обычный рецепт diff --git a/src/main/resources/languages/recipes_tl.yml b/src/main/resources/languages/recipes_tl.yml index 4ca058aef..e6c906b16 100644 --- a/src/main/resources/languages/recipes_tl.yml +++ b/src/main/resources/languages/recipes_tl.yml @@ -71,7 +71,7 @@ slimefun: lore: - I-craft ang item na ito tulad ng ipinakita - gamit ang Ancient Altar. - - Hanapin ang Ancient Altar para sa karagdagang Impormasyon. + - Hanapin ang Ancient Altar para sa mga karagdagang Impormasyon. heated_pressure_chamber: name: Heated Pressure Chamber lore: @@ -118,6 +118,11 @@ slimefun: lore: - I-craft ang item na ito tulad ng ipinakita - gamit ang Refinery. + barter_drop: + name: Piglin Bartering Drop + lore: + - Mag-barter kasama ang mga Piglins gamit ang mga + - Gold Ingots upang makuha ang aytem na ito. minecraft: shaped: name: Shaped Crafting Recipe diff --git a/src/main/resources/languages/recipes_tr.yml b/src/main/resources/languages/recipes_tr.yml index 40161e2f5..7cf800ab3 100644 --- a/src/main/resources/languages/recipes_tr.yml +++ b/src/main/resources/languages/recipes_tr.yml @@ -118,6 +118,11 @@ slimefun: lore: - Bu eşyayı Refinery kullanarak - üretin + barter_drop: + name: Piglin Takası İle Elde Edilir + lore: + - Piglinlerle Altın Külçesi takas ederek + - bu eşyayı elde edin minecraft: shaped: name: Biçimli Üretim Tarifi diff --git a/src/main/resources/languages/recipes_zh-CN.yml b/src/main/resources/languages/recipes_zh-CN.yml index c996980ec..14f407f6f 100644 --- a/src/main/resources/languages/recipes_zh-CN.yml +++ b/src/main/resources/languages/recipes_zh-CN.yml @@ -118,6 +118,11 @@ slimefun: lore: - 如合成表所示 - 用炼油机合成 + barter_drop: + name: 猪灵交易掉落 + lore: + - 使用金锭与猪灵交易 + - 可以获得此物品 minecraft: shaped: name: 有序合成 diff --git a/src/main/resources/languages/researches_de.yml b/src/main/resources/languages/researches_de.yml index 84c6acc2d..6129bf308 100644 --- a/src/main/resources/languages/researches_de.yml +++ b/src/main/resources/languages/researches_de.yml @@ -1,236 +1,242 @@ --- slimefun: - 24k_gold_block: Ein Palast aus Gold - advanced_android: Verbesserte Roboter - advanced_butcher_android: Verbesserter Killerroboter - advanced_circuit_board: Fortgeschrittener Schaltkreis - advanced_electric_smeltery: Verbesserter elektrischer Schmelzofen - advanced_farmer_android: Verbesserter Farmroboter - advanced_fisherman_android: Verbesserter Fischerroboter - advanced_output_node: Verbesserte Cargo-Knotenpunkte - alloys: Meister der Legierungen - ancient_altar: Alter Altar - ancient_runes: Antike Runen - android_interfaces: Roboter-Interface - android_memory_core: Roboterkern - angel_talisman: Talisman des Engels - animal_growth_accelerator: Wachstumsboost - anvil_talisman: Talisman des Ambosses - armored_jetboots: Gepanzerte Raketenstiefel - armored_jetpack: Gepanzertes Jetpack + walking_sticks: Gehstöcke + portable_crafter: Eine Werkbank zum Mitnehmen + fortune_cookie: Glückskeks + portable_dustbin: Mobile Mülltonnen + meat_jerky: Dörrfleisch armor_forge: Rüstungsherstellung - auto_anvil: Automatischer Amboss - auto_breeder: Futterautomaten - auto_drier: Ein trockener Tag - auto_enchanting: Automatische Verzauberungen - automated_crafting_chamber: Automatisches Craften - automated_panning_machine: Goldwaschen für Fortgeschrittene - automatic_ignition_chamber: Ein automatisierter Schmelzofen - backpacks: Rucksäcke + glowstone_armor: Glühende Rüstung + lumps: Magische Klumpen + ender_backpack: Ender-Rucksack + ender_armor: Ender-Rüstung + magic_eye_of_ender: Magisches Enderauge + magic_sugar: Magischer Zucker + monster_jerky: Gepökeltes Zombiefleisch + slime_armor: Schleimige Rüstung + sword_of_beheading: Köpfen mit Köpfchen basic_circuit_board: Einfacher Schaltkreis + advanced_circuit_board: Fortgeschrittener Schaltkreis + smeltery: Schmelzofen + steel: Die Ära des Stahls + misc_power_items: Items mit Energie battery: Deine erste Batterie - better_carbon_press: Bessere Karbonpresse - better_crop_growth_accelerator: Noch schnellere Pflanzen - better_electric_crucibles: Verbesserter Schmelztiegel - better_electric_furnace: Verbesserter elektrischer Ofen - better_food_fabricator: Essen vom Fließband - better_freezer: Ein besserer Kühlschrank - better_gps_transmitters: Verbesserte Satelliten - better_heated_pressure_chamber: Unter Druck - better_solar_generators: Verbesserte Solargeneratoren - bio_reactor: Biologisch abbaubar - blade_of_vampires: Vampirklinge - blistering_ingots: Radioaktiv und glühend - block_placer: Automatisch Blöcke platzieren - boosted_uranium: Starkes Uran - boots_of_the_stomper: Stampfende Stiefel - bound_armor: Rüstung zum Behalten - bound_backpack: Ein treuer Rucksack - bound_tools: Werkzeuge zum Behalten - bound_weapons: Waffen zum Behalten - bronze: Bronze - butcher_androids: Killer-Roboter + steel_plate: Stahlplatten + steel_thruster: Ein Triebwerk aus Stahl + parachute: Fallschirm + grappling_hook: Enterhaken + jetpacks: Jetpacks + multitools: Schweizer Taschenmesser + solar_panel_and_helmet: Solarhelm + elemental_staff: Stab der Elemente + grind_stone: Das Zermalmen von Items cactus_armor: Eine Rüstung aus Kaktus - capacitors: Einfache Kondensatoren - carbonado: Schwarze Diamanten - carbonado_furnace: Carbonado-Ofen - carbonado_tools: Werkzeuge aus Carbonado - carbon_press: Karbonpresse - cargo_basics: Cargo 101 - cargo_nodes: Cargo-Knotenpunkte - chainmail_armor: Kettenrüstung - charging_bench: Unter Strom - coal_generator: Kohleindustrie - cobalt_pickaxe: Eine schnelle Spitzhacke - combustion_reactor: Verbrennungsmotor - common_talisman: Gewöhnlicher Talisman - composter: Kompostierung + gold_pan: Goldgräber + magical_book_cover: Magischer Buchbinder + slimefun_metals: Neues Metall + ore_crusher: Doppelte Erze + bronze: Bronze + alloys: Meister der Legierungen compressor_and_carbon: Karbon-Herstellung - cooler: Kühles zum Mitnehmen - copper_wire: Kupferdrähte - crop_growth_accelerator: Beschleunigte Pflanzen - crucible: Schmelztiegel - crushed_ore: Erzpurifikation + gilded_iron_armor: Vergoldete Eisenrüstung + synthetic_diamond: Synthetische Diamanten + pressure_chamber: Druckkammer + synthetic_sapphire: Synthetische Sapphire damascus_steel: Damaststahl damascus_steel_armor: Damaststahlrüstung - diet_cookie: Diätkekse - duct_tape: Panzerband - electric_crucible: Elektrischer Schmelztiegel - electric_furnaces: Elektrische Öfen - electric_ingot_machines: Die Barrenfabrik + reinforced_alloy: Verstärkte Legierung + carbonado: Schwarze Diamanten + magic_workbench: Magische Werkbank + wind_staff: " Bezwinger der Lüfte" + reinforced_armor: Verstärkte Rüstung + ore_washer: Erze waschen + gold_carats: Hochwertiges Gold + silicon: Silikon + fire_staff: Bezwinger der Flammen + smelters_pickaxe: Eine Spitzhacke zum Dahinschmelzen + common_talisman: Gewöhnlicher Talisman + anvil_talisman: Talisman des Ambosses + miner_talisman: Talisman der Mine + hunter_talisman: Talisman des Jägers + lava_talisman: Schwimmen in Lava + water_talisman: Atmen wie ein Fisch + angel_talisman: Talisman des Engels + fire_talisman: Talisman des Feuerwehrmanns + lava_crystal: Feurige Angelegenheit + magician_talisman: Talisman des Magiers + traveller_talisman: Talisman des Wanderers + warrior_talisman: Talisman des Kriegers + knight_talisman: Talisman des Ritters + gilded_iron: Glänzendes Eisen + synthetic_emerald: Falsche Edelsteine + chainmail_armor: Kettenrüstung + whirlwind_talisman: Talisman des Wirbelwindes + wizard_talisman: Talisman des Zauberers + lumber_axe: Holzfällen mit Stil + hazmat_suit: Gefahrenschutz + uranium: Radioaktives Material + crushed_ore: Erzpurifikation + redstone_alloy: Redstone-Legierung + carbonado_tools: Werkzeuge aus Carbonado + first_aid: Erste Hilfe Set + gold_armor: Glitzernde Rüstung + night_vision_googles: Nachtsichtgerät + pickaxe_of_containment: Eine Spitzhacke für Spawner + hercules_pickaxe: Die Kraft von Herkules + table_saw: Tischsäge + slime_steel_armor: Schleimiger Stahl + blade_of_vampires: Vampirklinge + water_staff: Wasserbändiger + 24k_gold_block: Ein Palast aus Gold + composter: Kompostierung + farmer_shoes: Gartenarbeit + explosive_tools: Explosives Werkzeug + automated_panning_machine: Goldwaschen für Fortgeschrittene + boots_of_the_stomper: Stampfende Stiefel + pickaxe_of_the_seeker: Wer suchet, der findet + backpacks: Rucksäcke + woven_backpack: Stoff-Rucksack + crucible: Schmelztiegel + gilded_backpack: Vergoldeter Rucksack + armored_jetpack: Gepanzertes Jetpack + ender_talismans: Ender-Talisman + nickel_and_cobalt: Erzforscher + magnet: Magneten + infused_magnet: Verzauberter Magnet + cobalt_pickaxe: Eine schnelle Spitzhacke + essence_of_afterlife: Die Untoten + bound_backpack: Ein treuer Rucksack + jetboots: Raketenstiefel + armored_jetboots: Gepanzerte Raketenstiefel + seismic_axe: Die Erdbebenaxt + pickaxe_of_vein_mining: Minen im großen Stile + bound_weapons: Waffen zum Behalten + bound_tools: Werkzeuge zum Behalten + bound_armor: Rüstung zum Behalten + juicer: Leckere Säfte + repaired_spawner: Spawner reparieren + enhanced_furnace: Verbesserter Ofen + more_enhanced_furnaces: Noch bessere Öfen + high_tier_enhanced_furnaces: High-End-Öfen + reinforced_furnace: Verstärkter Ofen + carbonado_furnace: Carbonado-Ofen electric_motor: Elektromotoren + block_placer: Automatisch Blöcke platzieren + scroll_of_dimensional_teleposition: Schwindelerregend + special_bows: Robin Hood + tome_of_knowledge_sharing: Erfahrungen teilen + flask_of_knowledge: Erfahrung lagern + hardened_glass: Verstärktes Glas + golden_apple_juice: Ein goldener Zaubertrank + cooler: Kühles zum Mitnehmen + ancient_altar: Alter Altar + wither_proof_obsidian: Anti-Wither Obsidian + ancient_runes: Antike Runen + special_runes: Lila Runen + infernal_bonemeal: Knochenmehl für Warzen + rainbow_blocks: Regenbogen + infused_hopper: Magischer Trichter + wither_proof_glass: Anti-Wither Glas + duct_tape: Panzerband + plastic_sheet: Plastik + android_memory_core: Roboterkern + oil: Schwarzes Gold + fuel: Fossile Brennstoffe + hologram_projector: Hologramme + capacitors: Einfache Kondensatoren + high_tier_capacitors: Verbesserte Kondensatoren + solar_generators: Solarenergie + electric_furnaces: Elektrische Öfen electric_ore_grinding: Zermalmen und Zerquetschen - electric_press: Elektrische Presse - electric_smeltery: Ein besserer Schmelzofen - elemental_staff: Stab der Elemente + heated_pressure_chamber: Beheizte Druckkammer + coal_generator: Kohleindustrie + bio_reactor: Biologisch abbaubar + auto_enchanting: Automatische Verzauberungen + auto_anvil: Automatischer Amboss + multimeter: Messgeräte + gps_setup: GPS-Netzwerke 101 + gps_emergency_transmitter: Ein Wegweiser für alle Fälle + programmable_androids: Programmierbare Roboter + android_interfaces: Roboter-Interface + geo_scanner: GEO-Scanner + combustion_reactor: Verbrennungsmotor + teleporter: Teleportation + teleporter_activation_plates: Beam mich hoch! + better_solar_generators: Verbesserte Solargeneratoren + better_gps_transmitters: Verbesserte Satelliten elevator: Aufzüge - elytra: Gleitflügel + energized_solar_generator: Solarkraft in der Nacht + energized_gps_transmitter: High-End-Satelliten + energy_regulator: Ein Netzwerk unter Strom + butcher_androids: Killer-Roboter + organic_food: Viehfutter + auto_breeder: Futterautomaten + advanced_android: Verbesserte Roboter + advanced_butcher_android: Verbesserter Killerroboter + advanced_fisherman_android: Verbesserter Fischerroboter + animal_growth_accelerator: Wachstumsboost + xp_collector: Erfahrungssammler + organic_fertilizer: Organischer Dünger + crop_growth_accelerator: Beschleunigte Pflanzen + better_crop_growth_accelerator: Noch schnellere Pflanzen + reactor_essentials: Kraftwerke für Jedermann + nuclear_reactor: Kernkraftwerk + freezer: Eiskalt + cargo_basics: Cargo 101 + cargo_nodes: Cargo-Knotenpunkte + electric_ingot_machines: Die Barrenfabrik + high_tier_electric_ingot_machines: Schnelle Barren + automated_crafting_chamber: Automatisches Craften + better_food_fabricator: Essen vom Fließband + reactor_access_port: Automatischer Reaktor + fluid_pump: Pumpe + better_freezer: Ein besserer Kühlschrank + boosted_uranium: Starkes Uran + trash_can: Mülltonne + advanced_output_node: Verbesserte Cargo-Knotenpunkte + carbon_press: Karbonpresse + electric_smeltery: Ein besserer Schmelzofen + better_electric_furnace: Verbesserter elektrischer Ofen + better_carbon_press: Bessere Karbonpresse empowered_android: Hochenergetischer Roboter empowered_butcher_android: Hochenergetischer Killerroboter empowered_fisherman_android: Hochenergetischer Anglerroboter - ender_armor: Ender-Rüstung - ender_backpack: Ender-Rucksack - ender_talismans: Ender-Talisman - energized_gps_transmitter: High-End-Satelliten - energized_solar_generator: Solarkraft in der Nacht - energy_regulator: Ein Netzwerk unter Strom - enhanced_furnace: Verbesserter Ofen - essence_of_afterlife: Die Untoten - explosive_tools: Explosives Werkzeug - farmer_shoes: Gartenarbeit - fire_staff: Bezwinger der Flammen - fire_talisman: Talisman des Feuerwehrmanns - first_aid: Erste Hilfe Set - flask_of_knowledge: Erfahrung lagern - fluid_pump: Pumpe - fortune_cookie: Glückskeks - freezer: Eiskalt - fuel: Fossile Brennstoffe - geo_miner: GEO-Mining - geo_scanner: GEO-Scanner - gilded_backpack: Vergoldeter Rucksack - gilded_iron: Glänzendes Eisen - gilded_iron_armor: Vergoldete Eisenrüstung - glowstone_armor: Glühende Rüstung - gold_armor: Glitzernde Rüstung - gold_carats: Hochwertiges Gold - golden_apple_juice: Ein goldener Zaubertrank - gold_pan: Goldgräber - gps_emergency_transmitter: Ein Wegweiser für alle Fälle - gps_setup: GPS-Netzwerke 101 - grappling_hook: Enterhaken - grind_stone: Das Zermalmen von Items - hardened_glass: Verstärktes Glas - hazmat_suit: Gefahrenschutz - heated_pressure_chamber: Beheizte Druckkammer - hercules_pickaxe: Die Kraft von Herkules - high_tier_capacitors: Verbesserte Kondensatoren high_tier_carbon_press: Ultimative Karbonpresse - high_tier_electric_ingot_machines: Schnelle Barren - high_tier_enhanced_furnaces: High-End-Öfen - hologram_projector: Hologramme - hunter_talisman: Talisman des Jägers - infernal_bonemeal: Knochenmehl für Warzen - infused_hopper: Magischer Trichter - infused_magnet: Verzauberter Magnet - jetboots: Raketenstiefel - jetpacks: Jetpacks - juicer: Leckere Säfte - kelp_cookie: Süßer Seetang - knight_talisman: Talisman des Ritters - lava_crystal: Feurige Angelegenheit + wither_assembler: Ein automatisierter Wither + better_heated_pressure_chamber: Unter Druck + elytra: Gleitflügel + special_elytras: Verzauberte Gleitflügel + electric_crucible: Elektrischer Schmelztiegel + better_electric_crucibles: Verbesserter Schmelztiegel + advanced_electric_smeltery: Verbesserter elektrischer Schmelzofen + advanced_farmer_android: Verbesserter Farmroboter lava_generator: Thermale Energie - lava_talisman: Schwimmen in Lava - lightning_rune: Rune des Blitzes - lumber_axe: Holzfällen mit Stil - lumps: Magische Klumpen - magical_book_cover: Magischer Buchbinder - magic_eye_of_ender: Magisches Enderauge - magician_talisman: Talisman des Magiers - magic_sugar: Magischer Zucker - magic_workbench: Magische Werkbank - magnesium_generator: Energie durch Magnesium - magnet: Magneten - makeshift_smeltery: Improvisierter Schmelzofen - meat_jerky: Dörrfleisch - miner_talisman: Talisman der Mine - misc_power_items: Items mit Energie - monster_jerky: Gepökeltes Zombiefleisch - more_enhanced_furnaces: Noch bessere Öfen - multimeter: Messgeräte - multitools: Schweizer Taschenmesser - nether_gold_pan: Goldwäsche im Nether nether_ice: Eis aus dem Nether nether_star_reactor: Netherstern-Reaktor - nickel_and_cobalt: Erzforscher - night_vision_googles: Nachtsichtgerät - nuclear_reactor: Kernkraftwerk - oil: Schwarzes Gold - ore_crusher: Doppelte Erze - ore_washer: Erze waschen - organic_fertilizer: Organischer Dünger - organic_food: Viehfutter + blistering_ingots: Radioaktiv und glühend + automatic_ignition_chamber: Ein automatisierter Schmelzofen output_chest: Einfache Auffangkiste - parachute: Fallschirm - pickaxe_of_containment: Eine Spitzhacke für Spawner - pickaxe_of_the_seeker: Wer suchet, der findet - pickaxe_of_vein_mining: Minen im großen Stile - plastic_sheet: Plastik - portable_crafter: Eine Werkbank zum Mitnehmen - portable_dustbin: Mobile Mülltonnen - pressure_chamber: Druckkammer - programmable_androids: Programmierbare Roboter + copper_wire: Kupferdrähte radiant_backpack: Strahlender Rucksack - rainbow_blocks: Regenbogen - reactor_access_port: Automatischer Reaktor - reactor_essentials: Kraftwerke für Jedermann - redstone_alloy: Redstone-Legierung - reinforced_alloy: Verstärkte Legierung - reinforced_armor: Verstärkte Rüstung - reinforced_furnace: Verstärkter Ofen - repaired_spawner: Spawner reparieren - scroll_of_dimensional_teleposition: Schwindelerregend - seismic_axe: Die Erdbebenaxt - silicon: Silikon - slime_armor: Schleimige Rüstung - slimefun_metals: Neues Metall - slime_steel_armor: Schleimiger Stahl - smelters_pickaxe: Eine Spitzhacke zum Dahinschmelzen - smeltery: Schmelzofen - solar_generators: Solarenergie - solar_panel_and_helmet: Solarhelm - soulbound_rune: Seelenbindung - special_bows: Robin Hood - special_elytras: Verzauberte Gleitflügel - special_runes: Lila Runen - steel: Die Ära des Stahls - steel_plate: Stahlplatten - steel_thruster: Ein Triebwerk aus Stahl + auto_drier: Ein trockener Tag + diet_cookie: Diätkekse storm_staff: Die Stärke von Thor - sword_of_beheading: Köpfen mit Köpfchen - synthetic_diamond: Synthetische Diamanten - synthetic_emerald: Falsche Edelsteine - synthetic_sapphire: Synthetische Sapphire - table_saw: Tischsäge - teleporter: Teleportation - teleporter_activation_plates: Beam mich hoch! - tome_of_knowledge_sharing: Erfahrungen teilen + soulbound_rune: Seelenbindung + geo_miner: GEO-Mining + lightning_rune: Rune des Blitzes totem_of_undying: Das Totem der Untoten - trash_can: Mülltonne - traveller_talisman: Talisman des Wanderers + charging_bench: Unter Strom + nether_gold_pan: Goldwäsche im Nether + electric_press: Elektrische Presse + magnesium_generator: Energie durch Magnesium + kelp_cookie: Süßer Seetang + makeshift_smeltery: Improvisierter Schmelzofen tree_growth_accelerator: Schnelle Bäume - uranium: Radioaktives Material - walking_sticks: Gehstöcke - warrior_talisman: Talisman des Kriegers - water_staff: Wasserbändiger - water_talisman: Atmen wie ein Fisch - whirlwind_talisman: Talisman des Wirbelwindes - wind_staff: " Bezwinger der Lüfte" - wither_assembler: Ein automatisierter Wither - wither_proof_glass: Anti-Wither Glas - wither_proof_obsidian: Anti-Wither Obsidian - wizard_talisman: Talisman des Zauberers - woven_backpack: Stoff-Rucksack - xp_collector: Erfahrungssammler industrial_miner: Industrielle Erzförderung advanced_industrial_miner: Verbesserter Erzabbau + magical_zombie_pills: De-Zombifikation/Anti-Zombi Medizin + auto_brewer: Automatischer Braustand + enchantment_rune: Primitiver Zauber + lead_clothing: Kleidung aus Blei + tape_measure: Maßband + iron_golem_assembler: Eisengolems vom Fließband diff --git a/src/main/resources/languages/researches_es.yml b/src/main/resources/languages/researches_es.yml index 92a533964..9e3aec5cc 100644 --- a/src/main/resources/languages/researches_es.yml +++ b/src/main/resources/languages/researches_es.yml @@ -236,3 +236,7 @@ slimefun: advanced_industrial_miner: Minería Mejorada magical_zombie_pills: De-Zombificación auto_brewer: Alquimia Industrial + enchantment_rune: Encantamiento Antiguo + lead_clothing: Ropa de Plomo + tape_measure: Cinta Métrica + iron_golem_assembler: Iron Golems Automáticos diff --git a/src/main/resources/languages/researches_hu.yml b/src/main/resources/languages/researches_hu.yml index 6ae319fe9..5cfd07494 100644 --- a/src/main/resources/languages/researches_hu.yml +++ b/src/main/resources/languages/researches_hu.yml @@ -236,3 +236,7 @@ slimefun: advanced_industrial_miner: Jobb Bányászat magical_zombie_pills: Zombi Átváltoztató auto_brewer: Ipari Sörgyár + enchantment_rune: Ősi Varázslat + lead_clothing: Ólom Ruházat + tape_measure: Mérőszalag + iron_golem_assembler: Automatizált Vasgólemek diff --git a/src/main/resources/languages/researches_it.yml b/src/main/resources/languages/researches_it.yml index b1d800cac..7064fd9b8 100644 --- a/src/main/resources/languages/researches_it.yml +++ b/src/main/resources/languages/researches_it.yml @@ -1,22 +1,55 @@ --- slimefun: walking_sticks: Bastone da Passeggio + portable_crafter: Banco da Lavoro portatile + fortune_cookie: Biscotto della Fortuna + portable_dustbin: Cestino Portatile + meat_jerky: Carne Essiccata armor_forge: Creatore di Armature glowstone_armor: Armatura di Luminite + lumps: Verruche e Magia + ender_backpack: Zaino dell'End + ender_armor: Armatura dell'End + magic_eye_of_ender: Occhio Magico dell'End magic_sugar: Zucchero Magico monster_jerky: Grasso di Mostro + slime_armor: Armatura di Slime sword_of_beheading: Spada della Decapitazione + basic_circuit_board: Circuito di Base + advanced_circuit_board: Circuito Avanzato + smeltery: Fonderia + steel: Era dell'Acciaio misc_power_items: Altri componenti importanti battery: La tua prima batteria + steel_plate: Placcatura d'Acciaio steel_thruster: Propulsore d'Acciaio parachute: Paracadute + grappling_hook: Rampino + jetpacks: Jetpack + multitools: Strumenti Multiuso + solar_panel_and_helmet: Energia Solare elemental_staff: Staffe Elementali + grind_stone: Mola + cactus_armor: Armatura di Cactus gold_pan: Pentola d'oro + magical_book_cover: Libro magico + slimefun_metals: Nuovi Metalli ore_crusher: Raddoppio del minerale + bronze: Era del Bronzo + alloys: Leghe Avanzate compressor_and_carbon: Creazione di Carbonio + gilded_iron_armor: Armatura di Ferro Dorato + synthetic_diamond: Diamanti Sintetici pressure_chamber: Camera Pressurizzata + synthetic_sapphire: Zaffiri Sintetici + damascus_steel: Acciaio di Damasco + damascus_steel_armor: Armatura d'Acciaio di Damasco + reinforced_alloy: Lega Rinforzata + carbonado: Diamanti Neri magic_workbench: Banco da Lavoro Magico wind_staff: Staffa del Vento + reinforced_armor: Armatura Rinforzata + ore_washer: Lavaggio di Minerali gold_carats: Oro Puro silicon: Silicon Valley fire_staff: Staffa di Fuoco @@ -34,26 +67,65 @@ slimefun: traveller_talisman: Talismano del Viaggiatore warrior_talisman: Talismano del Guerriero knight_talisman: Talismano del Cavaliere + gilded_iron: Ferro Luccicante synthetic_emerald: Gemma Falsa chainmail_armor: Armatura di Catene whirlwind_talisman: Talismano del Vortice + wizard_talisman: Talismano dello Stregone lumber_axe: Ascia del Boscaiolo + hazmat_suit: Tuta Hazmat uranium: Radioattivo crushed_ore: Purificazione del Minerale redstone_alloy: Lega di Redstone carbonado_tools: Macchine di livello superiore first_aid: Primo soccorso - night_vision_googles: Visori Notturni - portable_crafter: Banco da Lavoro portatile - portable_dustbin: Cestino Portatile - cactus_armor: Armatura di Cactus - magical_book_cover: Libro magico - gilded_iron: Ferro Luccicante gold_armor: Armatura Luccicante + night_vision_googles: Visori Notturni + pickaxe_of_containment: Piccone di Contenimento + hercules_pickaxe: Piccone di Hercules + table_saw: Sega Circolare slime_steel_armor: Armatura d'Acciaio di Slime + blade_of_vampires: Lama dei Vampiri + water_staff: Bacchetta dell'Acqua + 24k_gold_block: Città d'Oro + composter: Compostare la Terra + farmer_shoes: Scarpe da Contadino + explosive_tools: Strumenti Esplosivi + automated_panning_machine: Setaccio Automatizzato + boots_of_the_stomper: Stivali del Calpestatore + pickaxe_of_the_seeker: Piccone del Cercatore + backpacks: Zaini + woven_backpack: Zaino Tessuto + crucible: Crogiuolo + gilded_backpack: Zaino Dorato + armored_jetpack: Jetpack Corazzato + ender_talismans: Talismani dell'End + nickel_and_cobalt: Ancora più minerali + magnet: Metalli Magnetici + infused_magnet: Magneti Infusi + cobalt_pickaxe: Piccone Veloce + essence_of_afterlife: Negromanzia + bound_backpack: Zaino Soulbound + jetboots: Stivali Jet + armored_jetboots: Stivali Jet Corazzati + seismic_axe: Ascia Sismica + pickaxe_of_vein_mining: Piccone per Estrazione di Vene + bound_weapons: Armi Soulbound + bound_tools: Strumenti Soulbound + bound_armor: Armatura Soulbound + juicer: Bevande Deliziose + repaired_spawner: Riparare Spawners + enhanced_furnace: Fornace Potenziata + more_enhanced_furnaces: Fornaci Migliori + high_tier_enhanced_furnaces: Fornace di Alto Livello + reinforced_furnace: Fornace Rinforzata + carbonado_furnace: Fornace profilata con Carbonado + electric_motor: Riscaldamento block_placer: Posizionatore di blocchi scroll_of_dimensional_teleposition: Rovesciare le cose + special_bows: Robin Hood tome_of_knowledge_sharing: Condivisione con gli amici + flask_of_knowledge: Immagazzinamento di XP hardened_glass: Resistere alle Esplosioni golden_apple_juice: Pozione dorata cooler: Bevande portatili @@ -67,11 +139,17 @@ slimefun: wither_proof_glass: Vetro a prova di Wither duct_tape: Nastro Adesivo plastic_sheet: Plastica + android_memory_core: Scheda di Memoria + oil: Petrolio fuel: Carburante hologram_projector: Ologrammi capacitors: Condensatori di livello 1 high_tier_capacitors: Condensatori di livello 2 solar_generators: Impianto di energia solare + electric_furnaces: Fornace Elettrificata + electric_ore_grinding: Schiacciare e macinare + heated_pressure_chamber: Camera Pressurizzata Riscaldata + coal_generator: Generatore a carbone bio_reactor: Bio-Reattore auto_enchanting: Incantamento e Disincantamento Automatici auto_anvil: Incudine Automatica @@ -111,6 +189,7 @@ slimefun: automated_crafting_chamber: Creazione automatizzata better_food_fabricator: Fabbricazione di alimenti aggiornata reactor_access_port: Interazione del reattore + fluid_pump: Pompa better_freezer: Congelatore aggiornato boosted_uranium: Cerchio senza fine trash_can: Spazzatura @@ -132,7 +211,9 @@ slimefun: advanced_electric_smeltery: Fonderia elettrica avanzata advanced_farmer_android: Androidi avanzati - Agricoltore lava_generator: Generatore di lava + nether_ice: " Refrigerante a Ghiaccio del nether" nether_star_reactor: Reattore Stella del Nether + blistering_ingots: Vesciche da Radioattività automatic_ignition_chamber: Camera di accensione automatica output_chest: Cassa di output del macchinario di base copper_wire: Conducibilità ridotta @@ -145,90 +226,17 @@ slimefun: lightning_rune: Runa del Tuono totem_of_undying: Totem dell'immortalità charging_bench: Banco di ricarica + nether_gold_pan: Setaccio del Nether electric_press: Pressa elettrica magnesium_generator: Potenza dal magnesio kelp_cookie: Alghe gustose makeshift_smeltery: Fonderia improvvisata tree_growth_accelerator: Alberi più veloci - fortune_cookie: Biscotto della Fortuna - meat_jerky: Carne Essiccata - lumps: Verruche e Magia - ender_backpack: Zaino dell'End - ender_armor: Armatura dell'End - magic_eye_of_ender: Occhio Magico dell'End - slime_armor: Armatura di Slime - basic_circuit_board: Circuito di Base - advanced_circuit_board: Circuito Avanzato - smeltery: Fonderia - steel: Era dell'Acciaio - steel_plate: Placcatura d'Acciaio - grappling_hook: Rampino - jetpacks: Jetpack - multitools: Strumenti Multiuso - solar_panel_and_helmet: Energia Solare - grind_stone: Mola - slimefun_metals: Nuovi Metalli - bronze: Era del Bronzo - alloys: Leghe Avanzate - gilded_iron_armor: Armatura di Ferro Dorato - synthetic_diamond: Diamanti Sintetici - synthetic_sapphire: Zaffiri Sintetici - damascus_steel: Acciaio di Damasco - damascus_steel_armor: Armatura d'Acciaio di Damasco - reinforced_alloy: Lega Rinforzata - carbonado: Diamanti Neri - reinforced_armor: Armatura Rinforzata - ore_washer: Lavaggio di Minerali - wizard_talisman: Talismano dello Stregone - hazmat_suit: Tuta Hazmat - pickaxe_of_containment: Piccone di Contenimento - hercules_pickaxe: Piccone di Hercules - table_saw: Sega Circolare - blade_of_vampires: Lama dei Vampiri - water_staff: Bacchetta dell'Acqua - 24k_gold_block: Città d'Oro - composter: Compostare la Terra - farmer_shoes: Scarpe da Contadino - explosive_tools: Strumenti Esplosivi - automated_panning_machine: Setaccio Automatizzato - boots_of_the_stomper: Stivali del Calpestatore - pickaxe_of_the_seeker: Piccone del Cercatore - backpacks: Zaini - woven_backpack: Zaino Tessuto - crucible: Crogiuolo - gilded_backpack: Zaino Dorato - armored_jetpack: Jetpack Corazzato - ender_talismans: Talismani dell'End - nickel_and_cobalt: Ancora più minerali - magnet: Metalli Magnetici - infused_magnet: Magneti Infusi - cobalt_pickaxe: Piccone Veloce - essence_of_afterlife: Negromanzia - bound_backpack: Zaino Soulbound - jetboots: Stivali Jet - armored_jetboots: Stivali Jet Corazzati - seismic_axe: Ascia Sismica - pickaxe_of_vein_mining: Piccone per Estrazione di Vene - bound_weapons: Armi Soulbound - bound_tools: Strumenti Soulbound - bound_armor: Armatura Soulbound - juicer: Bevande Deliziose - repaired_spawner: Riparare Spawners - enhanced_furnace: Fornace Potenziata - more_enhanced_furnaces: Fornaci Migliori - high_tier_enhanced_furnaces: Fornace di Alto Livello - reinforced_furnace: Fornace Rinforzata - carbonado_furnace: Fornace profilata con Carbonado - electric_motor: Riscaldamento - flask_of_knowledge: Immagazzinamento di XP - android_memory_core: Scheda di Memoria - oil: Petrolio - electric_furnaces: Fornace Elettrificata - electric_ore_grinding: Schiacciare e macinare - heated_pressure_chamber: Camera Pressurizzata Riscaldata - coal_generator: Generatore a carbone - fluid_pump: Pompa - nether_ice: " Refrigerante a Ghiaccio del nether" - blistering_ingots: Vesciche da Radioattività - nether_gold_pan: Setaccio del Nether - special_bows: Robin Hood + industrial_miner: Scavo industriale + advanced_industrial_miner: Scavo migliorato + magical_zombie_pills: De-Zombificazione + auto_brewer: Distillazione industriale + enchantment_rune: Incantamento antico + lead_clothing: Rivestimento di piombo + tape_measure: metro + iron_golem_assembler: Costruttore di Golem di ferro diff --git a/src/main/resources/languages/researches_ja.yml b/src/main/resources/languages/researches_ja.yml index 83a90b080..b0495fb96 100644 --- a/src/main/resources/languages/researches_ja.yml +++ b/src/main/resources/languages/researches_ja.yml @@ -236,3 +236,7 @@ slimefun: advanced_industrial_miner: よりよい採掘 magical_zombie_pills: ゾンビ化解除 auto_brewer: 工業的醸造 + enchantment_rune: 太古のエンチャント + lead_clothing: 鉛の布 + tape_measure: テープメジャー + iron_golem_assembler: 人造アイアンゴーレム diff --git a/src/main/resources/languages/researches_ko.yml b/src/main/resources/languages/researches_ko.yml index 16aef3b19..65e136aaa 100644 --- a/src/main/resources/languages/researches_ko.yml +++ b/src/main/resources/languages/researches_ko.yml @@ -1,17 +1,8 @@ --- slimefun: walking_sticks: 지팡이 - steel_thruster: 강철 스러스터 - elemental_staff: 원소 지팡이 - cactus_armor: 선인장 갑옷 - fire_staff: 불 지팡이 - fire_talisman: 소방사의 부적 - lumber_axe: 재목 도끼 - water_staff: 물 지팡이 - 24k_gold_block: 금으로 만든 도시 - woven_backpack: 천 가방 - wither_proof_glass: 위더-방어 유리 portable_crafter: 휴대용 조합대 + fortune_cookie: 포춘 쿠키 portable_dustbin: 휴대용 쓰래기통 meat_jerky: 고기 육포 armor_forge: 갑옷 제작 @@ -31,12 +22,16 @@ slimefun: misc_power_items: 중요한 전원 관련 항목 battery: 첫 번째 배터리 steel_plate: 강철 도금 + steel_thruster: 강철 스러스터 parachute: 낙하산 grappling_hook: 갈고리 훅 jetpacks: 제트팩 multitools: 멀티 툴 solar_panel_and_helmet: 태양 광 발전 + elemental_staff: 원소 지팡이 grind_stone: 맷돌 + cactus_armor: 선인장 갑옷 + gold_pan: 금 냄비(Gold Pan) magical_book_cover: 마법책 바인딩 slimefun_metals: 새로운 금속 ore_crusher: 광석 더블링 @@ -45,15 +40,19 @@ slimefun: compressor_and_carbon: 탄소 제작 gilded_iron_armor: 금빛 철갑옷 synthetic_diamond: 인조 다이아몬드 + pressure_chamber: 압력 챔버(Pressure Chamber) synthetic_sapphire: 인조 사파이어 damascus_steel: 다마스쿠스 강 damascus_steel_armor: 다마스쿠스 강 갑옷 reinforced_alloy: 강화 합금 carbonado: 블랙 다이아몬드 + magic_workbench: 마법 조합대(Magic Workbench) wind_staff: 바람 지팡이 reinforced_armor: 강화 갑옷 + ore_washer: 광물 세척기(Ore Washer) gold_carats: 순금 silicon: 실리콘 밸리 + fire_staff: 불 지팡이 smelters_pickaxe: 제련 곡괭이 common_talisman: 부적 anvil_talisman: 모루의 부적 @@ -62,6 +61,7 @@ slimefun: lava_talisman: 용암 걷기 부적 water_talisman: 물 숨결의 부적 angel_talisman: 천사의 부적 + fire_talisman: 소방사의 부적 lava_crystal: 화끈한 상황 magician_talisman: 마술사의 부적 traveller_talisman: 여행자의 부적 @@ -72,6 +72,9 @@ slimefun: chainmail_armor: 사슬 갑옷 whirlwind_talisman: 회오리 바람의 부적 wizard_talisman: 마법사의 부적 + lumber_axe: 재목 도끼 + hazmat_suit: 방호복 + uranium: 방사능 crushed_ore: 광석 정화 redstone_alloy: 레드스톤 합금 carbonado_tools: 최고의 기계 @@ -83,6 +86,8 @@ slimefun: table_saw: 테이블 톱 slime_steel_armor: 칙칙한 강철 갑옷 blade_of_vampires: 뱀파이어의 검 + water_staff: 물 지팡이 + 24k_gold_block: 금으로 만든 도시 composter: 퇴비 흙 farmer_shoes: 농부 신발 explosive_tools: 폭발성 도구 @@ -90,6 +95,7 @@ slimefun: boots_of_the_stomper: 스톰 퍼의 장화 pickaxe_of_the_seeker: 추적자의 곡괭이 backpacks: 가방 + woven_backpack: 천 가방 crucible: 도가니 gilded_backpack: Gilded 가방 armored_jetpack: 기갑 제트팩 @@ -102,13 +108,20 @@ slimefun: bound_backpack: Soulbound 스토리지 jetboots: 제트 부츠 armored_jetboots: 기갑 제트 부츠 + seismic_axe: 지진 도끼 pickaxe_of_vein_mining: 베인마이닝 곡괭이 bound_weapons: 소울 바운드 무기 bound_tools: 소울 바운드 도구 bound_armor: 영혼의 갑옷 juicer: 맛있는 음료 repaired_spawner: 스포너 수리 + enhanced_furnace: 강화된 화로(Enhanced Furnace) + more_enhanced_furnaces: 더 나은 화로(Better Furnaces) + high_tier_enhanced_furnaces: 고 티어 화로(High Tier Furnace) + reinforced_furnace: 강화 화로(Reinforced Furnace) + carbonado_furnace: 카본 엣지 화로(Carbonado Edged Furnace) electric_motor: 가열 + block_placer: 블럭 설치기(Block Placer) scroll_of_dimensional_teleposition: 주변을 돌리다 special_bows: 로빈 후드 tome_of_knowledge_sharing: 친구들과 공유 @@ -123,97 +136,64 @@ slimefun: infernal_bonemeal: 지옥 불 정령 rainbow_blocks: 레인보우 블록 infused_hopper: 주입 호퍼 + wither_proof_glass: 위더-방어 유리 duct_tape: 덕트 테이프 plastic_sheet: 플라스틱 android_memory_core: 메모리 코어 oil: 기름 fuel: 연료 hologram_projector: 홀로그램 - solar_generators: 태양 광 발전소 - electric_ore_grinding: 분쇄 및 연삭 - multimeter: 전력 측정 - gps_setup: 기본 GPS 설정 - gps_emergency_transmitter: GPS 비상 웨이포인트 - android_interfaces: 안드로이드 인터페이스 - geo_scanner: GEO 스캔 - teleporter: 텔레 포터 기본 구성 요소 - teleporter_activation_plates: 텔레포트기 활성화 - better_gps_transmitters: 업그레이드 된 송신기 - elevator: 엘리베이터 - energized_solar_generator: 풀 타임 태양 광 발전 - energized_gps_transmitter: 최상위 송신기 - energy_regulator: 에너지 네트워크 101 - organic_food: 유기농 식품 - auto_breeder: 자동 공급 - organic_fertilizer: 유기 비료 - reactor_essentials: 원자로 기초 - nuclear_reactor: 원자력 발전소 - freezer: Mr 프리즈 - cargo_basics: 화물 기본 - cargo_nodes: 화물 설정 - better_food_fabricator: 업그레이드 된 식품 제조 - reactor_access_port: 원자로 상호 작용 - boosted_uranium: 네버엔딩 서클 - trash_can: 폐물 - advanced_output_node: 고급 출력 노드 - high_tier_carbon_press: 궁극의 탄소 프레스 - wither_assembler: 자동 위더 킬러 - better_heated_pressure_chamber: 업그레이드 된 가열 압력 챔버 - better_electric_crucibles: 뜨거운 도가니 - advanced_electric_smeltery: 고급 전기 제련소 - blistering_ingots: 맹렬한 방사능 - copper_wire: 얇아진 전도성 - radiant_backpack: 빛나는 배낭 - auto_drier: 건조한 날 - diet_cookie: 다이어트 쿠키 - soulbound_rune: 영혼의 룬 - geo_miner: GEO-마이너 - lightning_rune: 번개 룬 - totem_of_undying: 불멸의 토템 - magnesium_generator: 마그네슘의 힘 - kelp_cookie: 맛있는 다시마 - fortune_cookie: 포춘 쿠키 - hazmat_suit: 방호복 - uranium: 방사능 - seismic_axe: 지진 도끼 capacitors: 1티어 건전지 high_tier_capacitors: 2티어 건전지 + solar_generators: 태양 광 발전소 electric_furnaces: 전자 화로 - high_tier_electric_ingot_machines: 초고속 주괴 제작 - elytra: 겉날개 - special_elytras: 특별한 겉날개 - nether_ice: 지옥 얼음 냉각수 - storm_staff: 폭풍의 막대기 - gold_pan: 금 냄비(Gold Pan) - pressure_chamber: 압력 챔버(Pressure Chamber) - magic_workbench: 마법 조합대(Magic Workbench) - ore_washer: 광물 세척기(Ore Washer) - enhanced_furnace: 강화된 화로(Enhanced Furnace) - more_enhanced_furnaces: 더 나은 화로(Better Furnaces) - high_tier_enhanced_furnaces: 고 티어 화로(High Tier Furnace) - reinforced_furnace: 강화 화로(Reinforced Furnace) - carbonado_furnace: 카본 엣지 화로(Carbonado Edged Furnace) - block_placer: 블럭 설치기(Block Placer) + electric_ore_grinding: 분쇄 및 연삭 heated_pressure_chamber: 가열 압력 챔버(Heated Pressure Chamber) coal_generator: 석탄 발전기(Coal Generator) bio_reactor: 바이오 원자로(Bio-Reactor) auto_enchanting: 자동 마법 부여 및 마력 추출(Automatic Enchanting and Disenchanting) auto_anvil: 자동 모루(Automatic Anvil) + multimeter: 전력 측정 + gps_setup: 기본 GPS 설정 + gps_emergency_transmitter: GPS 비상 웨이포인트 programmable_androids: 프로그래밍 가능한 안드로이드(Programmable Androids) + android_interfaces: 안드로이드 인터페이스 + geo_scanner: GEO 스캔 combustion_reactor: 연소 반응기(Combustion Reactor) + teleporter: 텔레 포터 기본 구성 요소 + teleporter_activation_plates: 텔레포트기 활성화 better_solar_generators: 업그레이드 된 태양 광 발전기(Upgraded Solar Generators) + better_gps_transmitters: 업그레이드 된 송신기 + elevator: 엘리베이터 + energized_solar_generator: 풀 타임 태양 광 발전 + energized_gps_transmitter: 최상위 송신기 + energy_regulator: 에너지 네트워크 101 butcher_androids: 정육점 안드로이드(Butcher Androids) + organic_food: 유기농 식품 + auto_breeder: 자동 공급 advanced_android: 고급 안드로이드(Advanced Androids) advanced_butcher_android: 고급 안드로이드-정육점(Advanced Androids - Butcher) advanced_fisherman_android: 고급 안드로이드-어부(Advanced Androids - Fisherman) animal_growth_accelerator: 동물 성장 조작(Animal Growth Manipulation) xp_collector: XP 수집기(XP Collector) + organic_fertilizer: 유기 비료 crop_growth_accelerator: 작물 성장 촉진(Crop Growth Acceleration) better_crop_growth_accelerator: 업그레이드 된 작물 성장 촉진제(Upgraded Crop Growth Accelerator) + reactor_essentials: 원자로 기초 + nuclear_reactor: 원자력 발전소 + freezer: Mr 프리즈 + cargo_basics: 화물 기본 + cargo_nodes: 화물 설정 electric_ingot_machines: 전자 주괴 제작(Electric Ingot Fabrication) + high_tier_electric_ingot_machines: 초고속 주괴 제작 automated_crafting_chamber: 자동화 조합대(Automated Crafting) + better_food_fabricator: 업그레이드 된 식품 제조 + reactor_access_port: 원자로 상호 작용 fluid_pump: 유체 펌프(Fluid Pump) better_freezer: 업그레이드 된 냉동고(Upgraded Freezer) + boosted_uranium: 네버엔딩 서클 + trash_can: 폐물 + advanced_output_node: 고급 출력 노드 carbon_press: 탄소 프레스(Carbon Press) electric_smeltery: 전기 제련소(Electric Smeltery) better_electric_furnace: 업그레이드 된 전기로(Upgraded Electric Furnace) @@ -221,14 +201,42 @@ slimefun: empowered_android: 강화된 안드로이드(Empowered Androids) empowered_butcher_android: 강화된 안드로이드-정육점(Empowered Androids - Butcher) empowered_fisherman_android: 강화된 안드로이드-어부(Empowered Androids - Fisherman) + high_tier_carbon_press: 궁극의 탄소 프레스 + wither_assembler: 자동 위더 킬러 + better_heated_pressure_chamber: 업그레이드 된 가열 압력 챔버 + elytra: 겉날개 + special_elytras: 특별한 겉날개 electric_crucible: 전기 도가니(Electrified Crucible) + better_electric_crucibles: 뜨거운 도가니 + advanced_electric_smeltery: 고급 전기 제련소 advanced_farmer_android: 고급 안드로이드-농부(Advanced Androids - Farmer) lava_generator: 용암 발전기(Lava Generator) + nether_ice: 지옥 얼음 냉각수 nether_star_reactor: 네더의 별 발전기(Nether Star Reator) + blistering_ingots: 맹렬한 방사능 automatic_ignition_chamber: 자동 점화 챔버(Automatic Ignition Chamber) output_chest: 기본 기계 출력 상자(Basic machinery outpost chest) + copper_wire: 얇아진 전도성 + radiant_backpack: 빛나는 배낭 + auto_drier: 건조한 날 + diet_cookie: 다이어트 쿠키 + storm_staff: 폭풍의 막대기 + soulbound_rune: 영혼의 룬 + geo_miner: GEO-마이너 + lightning_rune: 번개 룬 + totem_of_undying: 불멸의 토템 charging_bench: 충전대(Charging Bench) - nether_gold_pan: 네더 골드판(Nether Gold Pan) + nether_gold_pan: 네더 황금판(Nether Gold Pan) electric_press: 전기 프레스(Electric Press) + magnesium_generator: 마그네슘의 힘 + kelp_cookie: 맛있는 다시마 makeshift_smeltery: 즉석 제련 tree_growth_accelerator: 더 빠른 나무 + industrial_miner: 산업용 채광 기술 + advanced_industrial_miner: 더 나은 채광 기술 + magical_zombie_pills: 좀비화 방지 + auto_brewer: 산업용 양조장 + enchantment_rune: 고대 마법 + lead_clothing: 납 의류 + tape_measure: 줄자 + iron_golem_assembler: 자동 철골램 diff --git a/src/main/resources/languages/researches_ru.yml b/src/main/resources/languages/researches_ru.yml index c73215fa2..ee494c173 100644 --- a/src/main/resources/languages/researches_ru.yml +++ b/src/main/resources/languages/researches_ru.yml @@ -236,3 +236,7 @@ slimefun: advanced_industrial_miner: Улучшенная добыча magical_zombie_pills: Дезомбификация auto_brewer: Промышленная пивоварня + enchantment_rune: Древнее зачарование + lead_clothing: Свинцовое обмундирование + tape_measure: Рулетка + iron_golem_assembler: Образователь железных големов diff --git a/src/main/resources/languages/researches_tl.yml b/src/main/resources/languages/researches_tl.yml index b03a65186..a3d68ee89 100644 --- a/src/main/resources/languages/researches_tl.yml +++ b/src/main/resources/languages/researches_tl.yml @@ -236,3 +236,7 @@ slimefun: advanced_industrial_miner: Better Mining magical_zombie_pills: De-Zombification auto_brewer: Industrial Brewery + enchantment_rune: Ancient Enchanting + lead_clothing: Lead Clothing + tape_measure: Tape Measure + iron_golem_assembler: Automated Iron Golems diff --git a/src/main/resources/languages/researches_tr.yml b/src/main/resources/languages/researches_tr.yml index 1c9a52170..a572bb75d 100644 --- a/src/main/resources/languages/researches_tr.yml +++ b/src/main/resources/languages/researches_tr.yml @@ -236,3 +236,7 @@ slimefun: advanced_industrial_miner: Gelişmiş Madencilik magical_zombie_pills: A-Zombifikasyon auto_brewer: Endüstriyel İksircilik + enchantment_rune: Kadim Büyücülük + lead_clothing: Kurşun Kaplama + tape_measure: Mezura + iron_golem_assembler: Otomize Demir Golemler diff --git a/src/main/resources/languages/researches_zh-CN.yml b/src/main/resources/languages/researches_zh-CN.yml index 51d5fa9b5..94fe42637 100644 --- a/src/main/resources/languages/researches_zh-CN.yml +++ b/src/main/resources/languages/researches_zh-CN.yml @@ -236,3 +236,7 @@ slimefun: advanced_industrial_miner: 进阶采矿 magical_zombie_pills: 去僵尸化 auto_brewer: 自动化酿造 + enchantment_rune: 远古附魔法 + lead_clothing: 强化布料 + tape_measure: 卷尺 + iron_golem_assembler: 自动化铁傀儡生产 diff --git a/src/main/resources/languages/researches_zh-TW.yml b/src/main/resources/languages/researches_zh-TW.yml index d4625c9d1..209e0dbbf 100644 --- a/src/main/resources/languages/researches_zh-TW.yml +++ b/src/main/resources/languages/researches_zh-TW.yml @@ -236,3 +236,7 @@ slimefun: advanced_industrial_miner: 工業化採礦 - 改 magical_zombie_pills: 救贖藥丸 auto_brewer: 工業化釀造 + enchantment_rune: 古代附魔 + lead_clothing: 防輻射衣 + tape_measure: 捲尺 + iron_golem_assembler: 鐵巨人召喚機 diff --git a/src/main/resources/languages/resources_en.yml b/src/main/resources/languages/resources_en.yml index c92c438e3..6d880c399 100644 --- a/src/main/resources/languages/resources_en.yml +++ b/src/main/resources/languages/resources_en.yml @@ -22,4 +22,4 @@ resources: lead_ore_chunk: 'Lead Ore Chunk' zinc_ore_chunk: 'Zinc Ore Chunk' nickel_ore_chunk: 'Nickel Ore Chunk' - cobalt_ore_chunk: 'Cobalt Ore Chunk' \ No newline at end of file + cobalt_ore_chunk: 'Cobalt Ore Chunk' diff --git a/src/main/resources/languages/resources_ja.yml b/src/main/resources/languages/resources_ja.yml index adcfce068..fa6c10147 100644 --- a/src/main/resources/languages/resources_ja.yml +++ b/src/main/resources/languages/resources_ja.yml @@ -15,9 +15,9 @@ resources: iron_ore_chunk: 鉄 gold_ore_chunk: 金 copper_ore_chunk: 銅 - tin_ore_chunk: スズ + tin_ore_chunk: 錫 silver_ore_chunk: 銀 - aluminum_ore_chunk: アルミ + aluminum_ore_chunk: アルミニウム lead_ore_chunk: 鉛 zinc_ore_chunk: 亜鉛 nickel_ore_chunk: ニッケル diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index b991fb322..1841a7839 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -58,3 +58,6 @@ permissions: slimefun.inventory.bypass: description: Allows you to open all Slimefun Machines default: op + slimefun.debugging: + description: Allows you to use the debugging tool from Slimefun + default: op diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestBackpackCommand.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestBackpackCommand.java index de4559d66..67eb67e5a 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestBackpackCommand.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestBackpackCommand.java @@ -8,6 +8,7 @@ import org.bukkit.inventory.ItemStack; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -22,7 +23,7 @@ import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; -public class TestBackpackCommand { +class TestBackpackCommand { private static ServerMock server; @@ -52,7 +53,8 @@ public class TestBackpackCommand { } @Test - public void testValidBackpack() throws InterruptedException { + @DisplayName("Test /sf backpack giving a restored backpack") + void testValidBackpack() throws InterruptedException { Player player = server.addPlayer(); player.setOp(true); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -64,8 +66,9 @@ public class TestBackpackCommand { } @ParameterizedTest - @ValueSource(strings = { "ABC", "-100", "123456789" }) - public void testNonExistantBackpacks(String id) throws InterruptedException { + @DisplayName("Test /sf backpack with invalid id parameters") + @ValueSource(strings = { "", " ", "ABC", "-100", "123456789" }) + void testNonExistentBackpacks(String id) throws InterruptedException { Player player = server.addPlayer(); player.setOp(true); TestUtilities.awaitProfile(player); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestDebugFishCommand.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestDebugFishCommand.java index 81360c0d2..a7497a3e7 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestDebugFishCommand.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestDebugFishCommand.java @@ -4,6 +4,7 @@ import org.bukkit.entity.Player; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -13,7 +14,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; -public class TestDebugFishCommand { +class TestDebugFishCommand { private static ServerMock server; @@ -30,7 +31,8 @@ public class TestDebugFishCommand { @ParameterizedTest @ValueSource(booleans = { true, false }) - public void testCommand(boolean op) { + @DisplayName("Test if Debug Fish is given on /sf debug_fish") + void testCommand(boolean op) { Player player = server.addPlayer(); player.setOp(op); server.execute("slimefun", player, "debug_fish").assertSucceeded(); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestGuideCommand.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestGuideCommand.java index 1976f6f2a..663d1e1bc 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestGuideCommand.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestGuideCommand.java @@ -5,6 +5,7 @@ import org.bukkit.inventory.ItemStack; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -15,7 +16,7 @@ import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; -public class TestGuideCommand { +class TestGuideCommand { private static ServerMock server; @@ -31,8 +32,9 @@ public class TestGuideCommand { } @ParameterizedTest + @DisplayName("Test if Slimefun Guide is given on /sf guide") @ValueSource(booleans = { true, false }) - public void testCommand(boolean op) { + void testCommand(boolean op) { Player player = server.addPlayer(); player.setOp(op); server.execute("slimefun", player, "guide").assertSucceeded(); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestBookSlimefunGuide.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestBookSlimefunGuide.java index 6ae0170ac..6d56a54e6 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestBookSlimefunGuide.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestBookSlimefunGuide.java @@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.testing.tests.guide; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -10,7 +11,7 @@ import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide; -public class TestBookSlimefunGuide { +class TestBookSlimefunGuide { @BeforeAll public static void load() { @@ -24,7 +25,8 @@ public class TestBookSlimefunGuide { } @Test - public void testBasicGetters() { + @DisplayName("Test Getters for Chest Slimefun Guide") + void testBasicGetters() { BookSlimefunGuide guide = new BookSlimefunGuide(); Assertions.assertEquals(SlimefunGuideLayout.BOOK, guide.getLayout()); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestChestSlimefunGuide.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestChestSlimefunGuide.java index 260ed9bc1..5880e650f 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestChestSlimefunGuide.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestChestSlimefunGuide.java @@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.testing.tests.guide; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -10,7 +11,7 @@ import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide; -public class TestChestSlimefunGuide { +class TestChestSlimefunGuide { @BeforeAll public static void load() { @@ -24,7 +25,8 @@ public class TestChestSlimefunGuide { } @Test - public void testBasicGetters() { + @DisplayName("Test Getters for Chest Slimefun Guide") + void testBasicGetters() { ChestSlimefunGuide guide = new ChestSlimefunGuide(false); Assertions.assertEquals(SlimefunGuideLayout.CHEST, guide.getLayout()); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/backpacks/TestEnderBackpack.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/backpacks/TestEnderBackpack.java index 5684b59b9..12fab7fa3 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/backpacks/TestEnderBackpack.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/backpacks/TestEnderBackpack.java @@ -6,6 +6,7 @@ import org.bukkit.inventory.ItemStack; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -17,7 +18,7 @@ import io.github.thebusybiscuit.slimefun4.testing.interfaces.SlimefunItemTest; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -public class TestEnderBackpack implements SlimefunItemTest { +class TestEnderBackpack implements SlimefunItemTest { private static ServerMock server; private static SlimefunPlugin plugin; @@ -42,7 +43,8 @@ public class TestEnderBackpack implements SlimefunItemTest { } @Test - public void testRightClickBehaviour() { + @DisplayName("Test Ender Backpack opening Enderchest") + void testRightClickBehaviour() { Player player = server.addPlayer(); EnderBackpack backpack = registerSlimefunItem(plugin, "TEST_ENDER_BACKPACK"); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestDietCookie.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestDietCookie.java index 4bcdb086a..f7e9336e3 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestDietCookie.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestDietCookie.java @@ -7,7 +7,6 @@ import org.bukkit.potion.PotionEffectType; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -45,7 +44,6 @@ public class TestDietCookie implements SlimefunItemTest { } @Test - @Disabled("Potion Effects are currently not fully implemented in MockBukkit") public void testConsumptionBehaviour() { PlayerMock player = server.addPlayer(); DietCookie cookie = registerSlimefunItem(plugin, "TEST_DIET_COOKIE"); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestMonsterJerky.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestMonsterJerky.java index c8752a782..0002be40d 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestMonsterJerky.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestMonsterJerky.java @@ -6,7 +6,6 @@ import org.bukkit.potion.PotionEffectType; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -44,7 +43,6 @@ public class TestMonsterJerky implements SlimefunItemTest { } @Test - @Disabled("Potion Effects are currently not fully implemented in MockBukkit") public void testConsumptionBehaviour() { PlayerMock player = server.addPlayer(); player.addPotionEffect(PotionEffectType.HUNGER.createEffect(20, 2)); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/MockBeeProtectionSuit.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/MockBeeProtectionSuit.java new file mode 100644 index 000000000..43fdc850a --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/MockBeeProtectionSuit.java @@ -0,0 +1,35 @@ +package io.github.thebusybiscuit.slimefun4.testing.tests.listeners; + +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; + +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType; +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectiveArmor; +import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece; +import me.mrCookieSlime.Slimefun.Lists.RecipeType; +import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; + +class MockBeeProtectionSuit extends SlimefunArmorPiece implements ProtectiveArmor { + + public MockBeeProtectionSuit(Category category, SlimefunItemStack item) { + super(category, item, RecipeType.NULL, new ItemStack[9], new PotionEffect[0]); + } + + @Override + public ProtectionType[] getProtectionTypes() { + return new ProtectionType[] { ProtectionType.BEES }; + } + + @Override + public boolean isFullSetRequired() { + return false; + } + + @Override + public NamespacedKey getArmorSetId() { + return new NamespacedKey(getAddon().getJavaPlugin(), "mock_bees"); + } + +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestBeeListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestBeeListener.java new file mode 100644 index 000000000..c154d93a8 --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestBeeListener.java @@ -0,0 +1,75 @@ +package io.github.thebusybiscuit.slimefun4.testing.tests.listeners; + +import org.bukkit.Material; +import org.bukkit.entity.Bee; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.Mockito; + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.ServerMock; +import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.BeeListener; +import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; +import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; + +class TestBeeListener { + + private static ServerMock server; + private static SlimefunPlugin plugin; + private static BeeListener listener; + + @BeforeAll + public static void load() { + server = MockBukkit.mock(); + plugin = MockBukkit.load(SlimefunPlugin.class); + listener = new BeeListener(plugin); + } + + @AfterAll + public static void unload() { + MockBukkit.unmock(); + } + + @ParameterizedTest + @DisplayName("Test Bee damage protection") + @ValueSource(booleans = { true, false }) + void testBeeDamage(boolean hasArmor) throws InterruptedException { + Player player = server.addPlayer(); + PlayerProfile profile = TestUtilities.awaitProfile(player); + + if (hasArmor) { + Category category = TestUtilities.getCategory(plugin, "bee_suit_test"); + SlimefunItemStack chestplate = new SlimefunItemStack("MOCK_BEE_SUIT", Material.LEATHER_CHESTPLATE, "&cBee Suit Prototype"); + MockBeeProtectionSuit armor = new MockBeeProtectionSuit(category, chestplate); + armor.register(plugin); + + player.getInventory().setChestplate(chestplate.clone()); + // Force update the cached armor + profile.getArmor()[1].update(chestplate, armor); + } + + double damage = 7.5; + + Bee bee = Mockito.mock(Bee.class); + EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(bee, player, DamageCause.ENTITY_ATTACK, damage); + listener.onDamage(event); + + if (hasArmor) { + Assertions.assertEquals(0, event.getDamage()); + } + else { + Assertions.assertEquals(damage, event.getDamage()); + } + } + +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestCoolerListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestCoolerListener.java index c594dfb3c..e3dd6b8e7 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestCoolerListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestCoolerListener.java @@ -11,6 +11,7 @@ import org.bukkit.potion.PotionEffectType; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -28,7 +29,7 @@ import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -public class TestCoolerListener { +class TestCoolerListener { private static ServerMock server; private static CoolerListener listener; @@ -59,14 +60,16 @@ public class TestCoolerListener { } @Test - public void testOnlyJuiceAllowance() { + @DisplayName("Test if Coolers only allow juices") + void testOnlyJuiceAllowance() { Assertions.assertFalse(cooler.isItemAllowed(new ItemStack(Material.DIAMOND), null)); Assertions.assertFalse(cooler.isItemAllowed(cooler.getItem(), cooler)); Assertions.assertTrue(cooler.isItemAllowed(juice.getItem(), juice)); } @Test - public void testCoolerUsage() throws InterruptedException { + @DisplayName("Test if Coolers consume Juices when hunger gets low") + void testCoolerUsage() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); PlayerBackpack backpack = profile.createBackpack(cooler.getSize()); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestFireworksListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestFireworksListener.java index 849416af7..bc5f4709d 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestFireworksListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestFireworksListener.java @@ -10,6 +10,7 @@ import org.bukkit.inventory.meta.FireworkMeta; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -19,7 +20,7 @@ import be.seeseemelk.mockbukkit.inventory.meta.FireworkMetaMock; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.listeners.FireworksListener; -public class TestFireworksListener { +class TestFireworksListener { private static ServerMock server; @@ -36,7 +37,8 @@ public class TestFireworksListener { } @Test - public void testFireworkDamage() { + @DisplayName("Test if Fireworks from Research cause no damage") + void testFireworkDamage() { Player player = server.addPlayer(); Firework firework = Mockito.mock(Firework.class); FireworkMeta meta = new FireworkMetaMock(); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestItemPickupListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestItemPickupListener.java new file mode 100644 index 000000000..081f76a84 --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestItemPickupListener.java @@ -0,0 +1,137 @@ +package io.github.thebusybiscuit.slimefun4.testing.tests.listeners; + +import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.bukkit.Material; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.ServerMock; +import be.seeseemelk.mockbukkit.entity.ItemEntityMock; +import be.seeseemelk.mockbukkit.inventory.ChestInventoryMock; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; +import me.mrCookieSlime.CSCoreLibPlugin.cscorelib2.item.CustomItem; + +class TestItemPickupListener { + + private static SlimefunPlugin plugin; + private static ItemPickupListener listener; + private static ServerMock server; + + @BeforeAll + public static void load() { + server = MockBukkit.mock(); + plugin = MockBukkit.load(SlimefunPlugin.class); + listener = new ItemPickupListener(plugin); + } + + @AfterAll + public static void unload() { + MockBukkit.unmock(); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void testNoPickupFlagForEntities(boolean flag) { + Player player = server.addPlayer(); + Item item = new ItemEntityMock(server, UUID.randomUUID(), new ItemStack(Material.COMPASS)); + + if (flag) { + SlimefunUtils.markAsNoPickup(item, "Unit Test"); + } + + EntityPickupItemEvent event = new EntityPickupItemEvent(player, item, 1); + listener.onEntityPickup(event); + + Assertions.assertEquals(flag, event.isCancelled()); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void testNoPickupFlagForInventories(boolean flag) { + Inventory inventory = new ChestInventoryMock(null, 5); + Item item = new ItemEntityMock(server, UUID.randomUUID(), new ItemStack(Material.COMPASS)); + + if (flag) { + SlimefunUtils.markAsNoPickup(item, "Unit Test"); + } + + InventoryPickupItemEvent event = new InventoryPickupItemEvent(inventory, item); + listener.onHopperPickup(event); + + Assertions.assertEquals(flag, event.isCancelled()); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void testAltarProbeForEntities(boolean flag) { + Player player = server.addPlayer(); + ItemStack stack; + + if (flag) { + stack = new CustomItem(Material.DIAMOND, AncientAltarListener.ITEM_PREFIX + System.nanoTime()); + } + else { + stack = new CustomItem(Material.DIAMOND, "&5Just a normal named diamond"); + } + + AtomicBoolean removed = new AtomicBoolean(false); + Item item = new ItemEntityMock(server, UUID.randomUUID(), stack) { + + @Override + public void remove() { + removed.set(true); + } + }; + + EntityPickupItemEvent event = new EntityPickupItemEvent(player, item, 1); + listener.onEntityPickup(event); + + Assertions.assertEquals(flag, event.isCancelled()); + Assertions.assertEquals(flag, removed.get()); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void testAltarProbeForInventories(boolean flag) { + Inventory inventory = new ChestInventoryMock(null, 5); + ItemStack stack; + + if (flag) { + stack = new CustomItem(Material.DIAMOND, AncientAltarListener.ITEM_PREFIX + System.nanoTime()); + } + else { + stack = new CustomItem(Material.DIAMOND, "&5Just a normal named diamond"); + } + + AtomicBoolean removed = new AtomicBoolean(false); + Item item = new ItemEntityMock(server, UUID.randomUUID(), stack) { + + @Override + public void remove() { + removed.set(true); + } + }; + + InventoryPickupItemEvent event = new InventoryPickupItemEvent(inventory, item); + listener.onHopperPickup(event); + + Assertions.assertEquals(flag, event.isCancelled()); + Assertions.assertEquals(flag, removed.get()); + } + +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestPiglinListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestPiglinListener.java new file mode 100644 index 000000000..8feb37334 --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestPiglinListener.java @@ -0,0 +1,111 @@ +package io.github.thebusybiscuit.slimefun4.testing.tests.listeners; + +import java.util.UUID; + +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; +import org.bukkit.entity.Piglin; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.mockito.Mockito; + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.ServerMock; +import be.seeseemelk.mockbukkit.entity.ItemEntityMock; +import io.github.thebusybiscuit.cscorelib2.item.CustomItem; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.PiglinListener; +import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; + +class TestPiglinListener { + + private static SlimefunPlugin plugin; + private static PiglinListener listener; + private static ServerMock server; + + @BeforeAll + public static void load() { + server = MockBukkit.mock(); + plugin = MockBukkit.load(SlimefunPlugin.class); + listener = new PiglinListener(plugin); + } + + @AfterAll + public static void unload() { + MockBukkit.unmock(); + } + + private EntityPickupItemEvent createPickupEvent(ItemStack item) { + Piglin piglin = Mockito.mock(Piglin.class); + Mockito.when(piglin.getType()).thenReturn(EntityType.PIGLIN); + + Item itemEntity = new ItemEntityMock(server, UUID.randomUUID(), item); + + return new EntityPickupItemEvent(piglin, itemEntity, 1); + } + + private PlayerInteractEntityEvent createInteractEvent(EquipmentSlot hand, ItemStack item) { + Player player = server.addPlayer(); + + Piglin piglin = Mockito.mock(Piglin.class); + Mockito.when(piglin.getType()).thenReturn(EntityType.PIGLIN); + Mockito.when(piglin.isValid()).thenReturn(true); + + if (hand == EquipmentSlot.OFF_HAND) { + player.getInventory().setItemInOffHand(item); + } + else { + player.getInventory().setItemInMainHand(item); + } + + return new PlayerInteractEntityEvent(player, piglin, hand); + } + + @Test + void testPiglinPickup() { + EntityPickupItemEvent event = createPickupEvent(new ItemStack(Material.GOLD_INGOT)); + listener.onPickup(event); + Assertions.assertFalse(event.isCancelled()); + } + + @Test + void testPiglinPickupWithSlimefunItem() { + SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "PIGLIN_PICKUP_MOCK", new CustomItem(Material.GOLD_INGOT, "&6Piglin Bait")); + item.register(plugin); + + EntityPickupItemEvent event = createPickupEvent(item.getItem()); + listener.onPickup(event); + Assertions.assertTrue(event.isCancelled()); + } + + @ParameterizedTest + @EnumSource(value = EquipmentSlot.class, names = { "HAND", "OFF_HAND" }) + void testPiglinInteract(EquipmentSlot hand) { + PlayerInteractEntityEvent event = createInteractEvent(hand, new ItemStack(Material.GOLD_INGOT)); + listener.onInteract(event); + Assertions.assertFalse(event.isCancelled()); + } + + @ParameterizedTest + @EnumSource(value = EquipmentSlot.class, names = { "HAND", "OFF_HAND" }) + void testPiglinInteractWithSlimefunItem(EquipmentSlot hand) { + SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "PIGLIN_GIVE_" + hand.name(), new CustomItem(Material.GOLD_INGOT, "&6Piglin Bait")); + item.register(plugin); + + PlayerInteractEntityEvent event = createInteractEvent(hand, item.getItem()); + listener.onInteract(event); + Assertions.assertTrue(event.isCancelled()); + } + +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSlimefunGuideListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSlimefunGuideListener.java new file mode 100644 index 000000000..aadef5254 --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSlimefunGuideListener.java @@ -0,0 +1,71 @@ +package io.github.thebusybiscuit.slimefun4.testing.tests.listeners; + +import java.util.stream.Stream; + +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.ServerMock; +import be.seeseemelk.mockbukkit.entity.PlayerMock; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunGuideListener; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; + +class TestSlimefunGuideListener { + + private static SlimefunPlugin plugin; + private static ServerMock server; + + @BeforeAll + public static void load() { + server = MockBukkit.mock(); + plugin = MockBukkit.load(SlimefunPlugin.class); + } + + @AfterAll + public static void unload() { + MockBukkit.unmock(); + } + + @ParameterizedTest + @MethodSource("cartesianBooleans") + void testFirstJoin(boolean hasPlayedBefore, boolean giveSlimefunGuide) { + SlimefunGuideListener listener = new SlimefunGuideListener(plugin, giveSlimefunGuide); + PlayerMock player = new PlayerMock(server, "CanIHazGuide"); + + if (hasPlayedBefore) { + player.setLastPlayed(System.currentTimeMillis()); + } + + PlayerJoinEvent event = new PlayerJoinEvent(player, "CanIHazGuide has joined and wants sum guide"); + listener.onJoin(event); + + ItemStack guide = SlimefunGuide.getItem(SlimefunGuide.getDefaultLayout()); + Assertions.assertEquals(!hasPlayedBefore && giveSlimefunGuide, hasSlimefunGuide(player, guide)); + } + + private boolean hasSlimefunGuide(Player player, ItemStack guide) { + return SlimefunUtils.isItemSimilar(player.getInventory().getItem(0), guide, true); + } + + /** + * This returns an {@link Arguments} {@link Stream} of boolean combinations. + * It performs a certesian product on two boolean sets. + * + * @return a {@link Stream} of {@link Arguments} + */ + private static Stream cartesianBooleans() { + Stream stream = Stream.of(true, false); + return stream.flatMap(a -> Stream.of(true, false).map(b -> Arguments.of(a, b))); + } + +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSoulboundListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSoulboundListener.java index 9e97bc095..4d2aec92c 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSoulboundListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSoulboundListener.java @@ -59,7 +59,8 @@ public class TestSoulboundListener { player.respawn(); server.getPluginManager().assertEventFired(PlayerRespawnEvent.class, event -> { - return player.getInventory().getItem(6).isSimilar(item) == soulbound; + ItemStack stack = player.getInventory().getItem(6); + return SlimefunUtils.isItemSimilar(stack, item, true) == soulbound; }); } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestVillagerTradingListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestVillagerTradingListener.java new file mode 100644 index 000000000..ebcc2c629 --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestVillagerTradingListener.java @@ -0,0 +1,97 @@ +package io.github.thebusybiscuit.slimefun4.testing.tests.listeners; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.Event.Result; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.inventory.InventoryType.SlotType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.ServerMock; +import io.github.thebusybiscuit.cscorelib2.item.CustomItem; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem; +import io.github.thebusybiscuit.slimefun4.implementation.items.misc.SyntheticEmerald; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.VillagerTradingListener; +import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; +import me.mrCookieSlime.Slimefun.Lists.RecipeType; +import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; + +class TestVillagerTradingListener { + + private static SlimefunPlugin plugin; + private static VillagerTradingListener listener; + private static ServerMock server; + + @BeforeAll + public static void load() { + server = MockBukkit.mock(); + plugin = MockBukkit.load(SlimefunPlugin.class); + listener = new VillagerTradingListener(plugin); + } + + @AfterAll + public static void unload() { + MockBukkit.unmock(); + } + + private InventoryClickEvent mockClickEvent(ItemStack item) { + Player player = server.addPlayer(); + Inventory inv = TestUtilities.mockInventory(InventoryType.MERCHANT); + Mockito.when(inv.getSize()).thenReturn(8); + + InventoryView view = player.openInventory(inv); + view.setCursor(item); + InventoryClickEvent event = new InventoryClickEvent(view, SlotType.CONTAINER, 1, ClickType.LEFT, InventoryAction.PICKUP_ONE); + listener.onPreBrew(event); + return event; + } + + @Test + void testTradingWithoutSlimefunItems() { + InventoryClickEvent event = mockClickEvent(new ItemStack(Material.EMERALD)); + Assertions.assertEquals(Result.ALLOW, event.getResult()); + } + + @Test + void testTradingWithSlimefunItem() { + SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "MOCKED_FAKE_EMERALD", new CustomItem(Material.EMERALD, "&aFake Emerald")); + item.register(plugin); + + InventoryClickEvent event = mockClickEvent(item.getItem()); + Assertions.assertEquals(Result.DENY, event.getResult()); + } + + @Test + void testTradingWithVanillaItem() { + VanillaItem item = TestUtilities.mockVanillaItem(plugin, Material.EMERALD, true); + item.register(plugin); + + InventoryClickEvent event = mockClickEvent(item.getItem()); + Assertions.assertEquals(Result.ALLOW, event.getResult()); + } + + @Test + void testTradingWithSyntheticEmerald() { + Category category = TestUtilities.getCategory(plugin, "shiny_emeralds"); + SlimefunItemStack stack = new SlimefunItemStack("FAKE_EMERALD", Material.EMERALD, "&aTrade me"); + SyntheticEmerald item = new SyntheticEmerald(category, stack, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[9]); + item.register(plugin); + + InventoryClickEvent event = mockClickEvent(item.getItem()); + Assertions.assertEquals(Result.ALLOW, event.getResult()); + } +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/networks/MockNetwork.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/networks/MockNetwork.java new file mode 100644 index 000000000..7fa9e0b61 --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/networks/MockNetwork.java @@ -0,0 +1,42 @@ +package io.github.thebusybiscuit.slimefun4.testing.tests.networks; + +import java.util.Map; + +import org.bukkit.Location; + +import io.github.thebusybiscuit.slimefun4.api.network.Network; +import io.github.thebusybiscuit.slimefun4.api.network.NetworkComponent; +import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager; + +class MockNetwork extends Network { + + private final int range; + private final Map locations; + + protected MockNetwork(NetworkManager manager, Location regulator, int range, Map locations) { + super(manager, regulator); + this.range = range; + this.locations = locations; + } + + @Override + public int getRange() { + return range; + } + + @Override + public NetworkComponent classifyLocation(Location l) { + if (l.equals(regulator)) { + return NetworkComponent.REGULATOR; + } + else { + return locations.get(l); + } + } + + @Override + public void onClassificationChange(Location l, NetworkComponent from, NetworkComponent to) { + // Do nothing + } + +} \ No newline at end of file diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/networks/TestNetworkManager.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/networks/TestNetworkManager.java index 62ede051a..f0d043d46 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/networks/TestNetworkManager.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/networks/TestNetworkManager.java @@ -9,6 +9,7 @@ import org.bukkit.World; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -19,7 +20,7 @@ import io.github.thebusybiscuit.slimefun4.api.network.NetworkComponent; import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager; import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet; -public class TestNetworkManager { +class TestNetworkManager { private static ServerMock server; @@ -34,13 +35,15 @@ public class TestNetworkManager { } @Test - public void testIllegalNetworkSize() { + @DisplayName("Test illegal network size arguments") + void testIllegalNetworkSize() { Assertions.assertThrows(IllegalArgumentException.class, () -> new NetworkManager(-100)); Assertions.assertThrows(IllegalArgumentException.class, () -> new NetworkManager(0)); } @Test - public void testGetMaxNetworkSize() { + @DisplayName("Test maximum network size") + void testGetMaxNetworkSize() { int size = 50; NetworkManager manager = new NetworkManager(size); @@ -48,12 +51,13 @@ public class TestNetworkManager { } @Test - public void testGetNetworkList() { + @DisplayName("Test network list") + void testGetNetworkList() { NetworkManager manager = new NetworkManager(10); World world = server.addSimpleWorld("Simple Network World"); Location loc = new Location(world, 0, 100, 0); - Network network = new DummyNetwork(manager, loc, 10, new HashMap<>()); + Network network = new MockNetwork(manager, loc, 10, new HashMap<>()); Assertions.assertFalse(manager.getNetworkList().contains(network)); manager.registerNetwork(network); @@ -63,60 +67,64 @@ public class TestNetworkManager { } @Test - public void testDirtyRegulatorUnregistersNetwork() { + @DisplayName("Test network re-registration for dirty regulators") + void testDirtyRegulatorUnregistersNetwork() { World world = server.addSimpleWorld("Simple Network World"); Location loc = new Location(world, 0, 100, 0); NetworkManager manager = Mockito.mock(NetworkManager.class); - Network network = new DummyNetwork(manager, loc, 10, new HashMap<>()); + Network network = new MockNetwork(manager, loc, 10, new HashMap<>()); network.markDirty(loc); Mockito.verify(manager).unregisterNetwork(network); } @Test - public void testGetNetworkAtLocation() { + @DisplayName("Test getting a network at a location") + void testGetNetworkAtLocation() { NetworkManager manager = new NetworkManager(10); World world = server.addSimpleWorld("Simple Network World"); Location loc = new Location(world, 0, 100, 0); Location loc2 = new Location(world, 0, 200, 0); - Network network = new DummyNetwork(manager, loc, 10, new HashMap<>()); + Network network = new MockNetwork(manager, loc, 10, new HashMap<>()); - Assertions.assertFalse(manager.getNetworkFromLocation(loc, DummyNetwork.class).isPresent()); + Assertions.assertFalse(manager.getNetworkFromLocation(loc, MockNetwork.class).isPresent()); manager.registerNetwork(network); - Optional optional = manager.getNetworkFromLocation(loc, DummyNetwork.class); + Optional optional = manager.getNetworkFromLocation(loc, MockNetwork.class); Assertions.assertTrue(optional.isPresent()); Assertions.assertEquals(network, optional.get()); - Assertions.assertFalse(manager.getNetworkFromLocation(loc2, DummyNetwork.class).isPresent()); + Assertions.assertFalse(manager.getNetworkFromLocation(loc2, MockNetwork.class).isPresent()); Assertions.assertFalse(manager.getNetworkFromLocation(loc, CargoNet.class).isPresent()); } @Test - public void testGetNetworksAtLocation() { + @DisplayName("Test getting all networks at a location") + void testGetNetworksAtLocation() { NetworkManager manager = new NetworkManager(10); World world = server.addSimpleWorld("Simple Network World"); Location loc = new Location(world, 0, 100, 0); Location loc2 = new Location(world, 0, 200, 0); - Network network = new DummyNetwork(manager, loc, 10, new HashMap<>()); + Network network = new MockNetwork(manager, loc, 10, new HashMap<>()); manager.registerNetwork(network); - Assertions.assertFalse(manager.getNetworksFromLocation(loc2, DummyNetwork.class).contains(network)); + Assertions.assertFalse(manager.getNetworksFromLocation(loc2, MockNetwork.class).contains(network)); Assertions.assertFalse(manager.getNetworksFromLocation(loc, CargoNet.class).contains(network)); - Assertions.assertTrue(manager.getNetworksFromLocation(loc, DummyNetwork.class).contains(network)); + Assertions.assertTrue(manager.getNetworksFromLocation(loc, MockNetwork.class).contains(network)); } @Test - public void testSingleNodeNetwork() { + @DisplayName("Test a single node network") + void testSingleNodeNetwork() { NetworkManager manager = new NetworkManager(1); World world = server.addSimpleWorld("Simple Network World"); Location loc = new Location(world, 0, 100, 0); - Network network = new DummyNetwork(manager, loc, 1, new HashMap<>()); + Network network = new MockNetwork(manager, loc, 1, new HashMap<>()); network.tick(); Assertions.assertEquals(1, network.getSize()); @@ -124,7 +132,8 @@ public class TestNetworkManager { } @Test - public void testCornerConnection() { + @DisplayName("Test networks connecting via corners") + void testCornerConnection() { NetworkManager manager = new NetworkManager(100); World world = server.addSimpleWorld("Simple Network World"); Map map = new HashMap<>(); @@ -137,39 +146,10 @@ public class TestNetworkManager { Location loc3 = new Location(world, 2, 100, 2); map.put(loc3, NetworkComponent.CONNECTOR); - Network network = new DummyNetwork(manager, loc, 3, map); + Network network = new MockNetwork(manager, loc, 3, map); network.tick(); Assertions.assertEquals(3, network.getSize()); } - private class DummyNetwork extends Network { - - private final int range; - private final Map locations; - - protected DummyNetwork(NetworkManager manager, Location regulator, int range, Map locations) { - super(manager, regulator); - this.range = range; - this.locations = locations; - } - - @Override - public int getRange() { - return range; - } - - @Override - public NetworkComponent classifyLocation(Location l) { - if (l.equals(regulator)) return NetworkComponent.REGULATOR; - return locations.get(l); - } - - @Override - public void onClassificationChange(Location l, NetworkComponent from, NetworkComponent to) { - // Do nothing - } - - } - } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/profiles/TestGuideHistory.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/profiles/TestGuideHistory.java index e26a9d275..3ad8087de 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/profiles/TestGuideHistory.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/profiles/TestGuideHistory.java @@ -7,6 +7,7 @@ import org.bukkit.inventory.ItemStack; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -19,7 +20,7 @@ import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -public class TestGuideHistory { +class TestGuideHistory { private static ServerMock server; private static SlimefunPlugin plugin; @@ -36,7 +37,8 @@ public class TestGuideHistory { } @Test - public void testDefaults() throws InterruptedException { + @DisplayName("Test Guide History being empty by default") + void testDefaults() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -47,7 +49,8 @@ public class TestGuideHistory { } @Test - public void testSearchTerm() throws InterruptedException { + @DisplayName("Test adding a search term to the history") + void testSearchTerm() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); GuideHistory history = profile.getGuideHistory(); @@ -60,7 +63,8 @@ public class TestGuideHistory { } @Test - public void testClear() throws InterruptedException { + @DisplayName("Test clearing the Guide History") + void testClear() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); GuideHistory history = profile.getGuideHistory(); @@ -73,7 +77,8 @@ public class TestGuideHistory { } @Test - public void testSlimefunItem() throws InterruptedException { + @DisplayName("Test adding a SlimefunItem to Guide History") + void testSlimefunItem() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); GuideHistory history = profile.getGuideHistory(); @@ -89,7 +94,8 @@ public class TestGuideHistory { } @Test - public void testItem() throws InterruptedException { + @DisplayName("Test adding an ItemStack to Guide History") + void testItem() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); GuideHistory history = profile.getGuideHistory(); @@ -107,7 +113,8 @@ public class TestGuideHistory { } @Test - public void testCategory() throws InterruptedException { + @DisplayName("Test adding a Category to Guide History") + void testCategory() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); GuideHistory history = profile.getGuideHistory(); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/profiles/TestPlayerBackpacks.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/profiles/TestPlayerBackpacks.java index 1cbeef5da..309755a7b 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/profiles/TestPlayerBackpacks.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/profiles/TestPlayerBackpacks.java @@ -8,6 +8,7 @@ import org.bukkit.inventory.ItemStack; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -17,7 +18,7 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; -public class TestPlayerBackpacks { +class TestPlayerBackpacks { private static ServerMock server; @@ -33,7 +34,8 @@ public class TestPlayerBackpacks { } @Test - public void testCreateBackpack() throws InterruptedException { + @DisplayName("Test creating a new Player Backpack") + void testCreateBackpack() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); Assertions.assertFalse(profile.isDirty()); @@ -51,7 +53,8 @@ public class TestPlayerBackpacks { } @Test - public void testChangeSize() throws InterruptedException { + @DisplayName("Test upgrading the backpack size") + void testChangeSize() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); PlayerBackpack backpack = profile.createBackpack(9); @@ -71,7 +74,8 @@ public class TestPlayerBackpacks { } @Test - public void testGetBackpackById() throws InterruptedException { + @DisplayName("Test getting a backpack by its id") + void testGetBackpackById() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); PlayerBackpack backpack = profile.createBackpack(9); @@ -87,7 +91,8 @@ public class TestPlayerBackpacks { } @Test - public void testLoadBackpackFromFile() throws InterruptedException { + @DisplayName("Test loading a backpack from file") + void testLoadBackpackFromFile() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/profiles/TestPlayerProfile.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/profiles/TestPlayerProfile.java index 138e532e2..b600c4eef 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/profiles/TestPlayerProfile.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/profiles/TestPlayerProfile.java @@ -8,6 +8,7 @@ import org.bukkit.entity.Player; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -18,7 +19,7 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; -public class TestPlayerProfile { +class TestPlayerProfile { private static ServerMock server; @@ -34,7 +35,8 @@ public class TestPlayerProfile { } @Test - public void testOfflinePlayer() throws InterruptedException { + @DisplayName("Test Player Profiles for offline Players") + void testOfflinePlayer() throws InterruptedException { OfflinePlayer player = new OfflinePlayerMock("Offline Test Player"); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -54,7 +56,8 @@ public class TestPlayerProfile { } @Test - public void testOnlinePlayer() throws InterruptedException { + @DisplayName("Test Player Profiles for online Players") + void testOnlinePlayer() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -63,7 +66,8 @@ public class TestPlayerProfile { } @Test - public void testIterator() throws InterruptedException { + @DisplayName("Test PlayerProfile iterators") + void testIterator() throws InterruptedException { // Clear out any previous profiles Iterator clear = PlayerProfile.iterator(); while (clear.hasNext()) { @@ -83,7 +87,8 @@ public class TestPlayerProfile { } @Test - public void testAttributes() throws InterruptedException { + @DisplayName("Test PlayerProfile methods") + void testAttributes() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -107,7 +112,8 @@ public class TestPlayerProfile { } @Test - public void testNotExistentProfile() throws InterruptedException { + @DisplayName("Test a non-existent Player Profile") + void testNotExistentProfile() throws InterruptedException { OfflinePlayer player = new OfflinePlayerMock("Offline Test Player 2"); Assertions.assertFalse(PlayerProfile.find(player).isPresent()); @@ -117,12 +123,14 @@ public class TestPlayerProfile { } @Test - public void testNullPlayerGetProfile() { + @DisplayName("Test nullability for Player profiles") + void testNullPlayerGetProfile() { Assertions.assertThrows(IllegalArgumentException.class, () -> PlayerProfile.get(null, p -> {})); } @Test - public void testHashCode() throws InterruptedException { + @DisplayName("Test PlayerProfile#hashCode()") + void testHashCode() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestProfileResearches.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestProfileResearches.java index adee1b32a..e85340602 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestProfileResearches.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestProfileResearches.java @@ -7,6 +7,7 @@ import org.bukkit.entity.Player; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -16,7 +17,7 @@ import io.github.thebusybiscuit.slimefun4.core.researching.Research; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; -public class TestProfileResearches { +class TestProfileResearches { private static ServerMock server; private static SlimefunPlugin plugin; @@ -33,7 +34,8 @@ public class TestProfileResearches { } @Test - public void testSetResearched() throws InterruptedException { + @DisplayName("Test setting a Research as unlocked") + void testSetResearched() throws InterruptedException { SlimefunPlugin.getRegistry().setResearchingEnabled(true); Player player = server.addPlayer(); @@ -53,7 +55,8 @@ public class TestProfileResearches { } @Test - public void testHasUnlocked() throws InterruptedException { + @DisplayName("Test checking if Research is unlocked") + void testHasUnlocked() throws InterruptedException { SlimefunPlugin.getRegistry().setResearchingEnabled(true); Player player = server.addPlayer(); @@ -78,7 +81,8 @@ public class TestProfileResearches { } @Test - public void testGetResearches() throws InterruptedException { + @DisplayName("Test getting all unlocked Researches") + void testGetResearches() throws InterruptedException { SlimefunPlugin.getRegistry().setResearchingEnabled(true); Player player = server.addPlayer(); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchSetup.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchSetup.java index a9c92d8ab..1af5501a1 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchSetup.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchSetup.java @@ -10,6 +10,7 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; @@ -21,7 +22,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup; @TestMethodOrder(value = OrderAnnotation.class) -public class TestResearchSetup { +class TestResearchSetup { @BeforeAll public static void load() { @@ -35,8 +36,9 @@ public class TestResearchSetup { } @Test + @DisplayName("Test if ResearchSetup throws an Exception") @Order(value = 1) - public void testForExceptions() { + void testForExceptions() { // Not really ideal but still important to test. // Research amount is variable, so we can't test for that. // We are really only concerned about any runtime exceptions here. @@ -49,7 +51,8 @@ public class TestResearchSetup { @Test @Order(value = 2) - public void testResearchTranslations() throws IOException { + @DisplayName("Test if Researches have a translation") + void testResearchTranslations() throws IOException { try (BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/languages/researches_en.yml"), StandardCharsets.UTF_8))) { FileConfiguration config = YamlConfiguration.loadConfiguration(reader); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchUnlocking.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchUnlocking.java index 221bac9f8..9f4f88bac 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchUnlocking.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchUnlocking.java @@ -10,6 +10,7 @@ import org.bukkit.entity.Player; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -20,7 +21,7 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.core.researching.Research; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -public class TestResearchUnlocking { +class TestResearchUnlocking { private ServerMock server; private SlimefunPlugin plugin; @@ -51,8 +52,9 @@ public class TestResearchUnlocking { } @ParameterizedTest + @DisplayName("Test Unlocking Researches") @ValueSource(booleans = { true, false }) - public void testUnlock(boolean instant) throws InterruptedException { + void testUnlock(boolean instant) throws InterruptedException { SlimefunPlugin.getRegistry().setResearchingEnabled(true); Player player = server.addPlayer(); Research research = new Research(new NamespacedKey(plugin, "unlock_me"), 1842, "Unlock me", 500); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearches.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearches.java index 6079d67a5..ce3ff70ef 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearches.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearches.java @@ -9,6 +9,7 @@ import org.bukkit.entity.Player; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -19,7 +20,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -public class TestResearches { +class TestResearches { private static ServerMock server; private static SlimefunPlugin plugin; @@ -36,7 +37,8 @@ public class TestResearches { } @Test - public void testResearchGetters() { + @DisplayName("Test Getter methods for Research class") + void testResearchGetters() { NamespacedKey key = new NamespacedKey(plugin, "getter_test"); Research research = new Research(key, 0, "Test", 100); research.register(); @@ -52,7 +54,8 @@ public class TestResearches { } @Test - public void testResearchCost() { + @DisplayName("Test cost of Researches") + void testResearchCost() { NamespacedKey key = new NamespacedKey(plugin, "cost_test"); Research research = new Research(key, 5, "Cost Test", 100); @@ -66,8 +69,9 @@ public class TestResearches { } @Test - public void testResearchRegistration() { - NamespacedKey key = new NamespacedKey(plugin, "testResearch"); + @DisplayName("Test registering a Research") + void testResearchRegistration() { + NamespacedKey key = new NamespacedKey(plugin, "test_research"); Research research = new Research(key, 1, "Test", 100); SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "RESEARCH_TEST", new CustomItem(Material.TORCH, "&bResearch Test")); research.addItems(item, null); @@ -85,8 +89,9 @@ public class TestResearches { } @Test - public void testDisabledResearch() { - NamespacedKey key = new NamespacedKey(plugin, "disabledResearch"); + @DisplayName("Test disabling a Research") + void testDisabledResearch() { + NamespacedKey key = new NamespacedKey(plugin, "disabled_research"); Research research = new Research(key, 2, "Test", 100); SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "RESEARCH_TEST", new CustomItem(Material.TORCH, "&bResearch Test")); research.addItems(item); @@ -100,8 +105,9 @@ public class TestResearches { } @Test - public void testResearchGloballyDisabled() { - NamespacedKey key = new NamespacedKey(plugin, "globallyDisabledResearch"); + @DisplayName("Test disabling Researches server-wide") + void testResearchGloballyDisabled() { + NamespacedKey key = new NamespacedKey(plugin, "globally_disabled_research"); Research research = new Research(key, 3, "Test", 100); SlimefunPlugin.getRegistry().setResearchingEnabled(true); @@ -112,8 +118,9 @@ public class TestResearches { } @Test - public void testAddItems() { - NamespacedKey key = new NamespacedKey(plugin, "addItemsResearch"); + @DisplayName("Test adding items to a Research") + void testAddItems() { + NamespacedKey key = new NamespacedKey(plugin, "add_items_to_research"); Research research = new Research(key, 17, "Test", 100); SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "RESEARCH_ITEMS_TEST", new CustomItem(Material.LAPIS_LAZULI, "&9Adding items is fun")); item.register(plugin); @@ -125,11 +132,11 @@ public class TestResearches { } @Test - public void testPlayerCanUnlockDisabledResearch() { + void testPlayerCanUnlockDisabledResearch() { SlimefunPlugin.getRegistry().setResearchingEnabled(false); Player player = server.addPlayer(); - NamespacedKey key = new NamespacedKey(plugin, "disabledUnlockableResearch"); + NamespacedKey key = new NamespacedKey(plugin, "disabled_unlockable_research"); Research research = new Research(key, 567, "Test", 100); Assertions.assertTrue(research.canUnlock(player)); @@ -138,11 +145,12 @@ public class TestResearches { } @Test - public void testFreeCreativeResearch() { + @DisplayName("Test 'free creative researching' option") + void testFreeCreativeResearch() { SlimefunPlugin.getRegistry().setResearchingEnabled(true); Player player = server.addPlayer(); - NamespacedKey key = new NamespacedKey(plugin, "freeCreativeResearch"); + NamespacedKey key = new NamespacedKey(plugin, "free_creative_research"); Research research = new Research(key, 153, "Test", 100); SlimefunPlugin.getRegistry().setFreeCreativeResearchingEnabled(false); @@ -163,9 +171,10 @@ public class TestResearches { } @Test - public void testUnlockableResearch() { + @DisplayName("Test levels requirement") + void testUnlockableResearch() { Player player = server.addPlayer(); - NamespacedKey key = new NamespacedKey(plugin, "freeCreativeResearch"); + NamespacedKey key = new NamespacedKey(plugin, "unlocking_research"); Research research = new Research(key, 235, "Test", 4); Assertions.assertFalse(research.canUnlock(player)); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TestBlockDataService.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TestBlockDataService.java index cad9afeff..80e24545c 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TestBlockDataService.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TestBlockDataService.java @@ -5,13 +5,14 @@ import org.bukkit.NamespacedKey; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; import io.github.thebusybiscuit.slimefun4.core.services.BlockDataService; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -public class TestBlockDataService { +class TestBlockDataService { private static SlimefunPlugin plugin; @@ -27,13 +28,15 @@ public class TestBlockDataService { } @Test - public void testInitialization() { + @DisplayName("Test creating a BlockDataService") + void testInitialization() { BlockDataService service = new BlockDataService(plugin, "test"); Assertions.assertEquals(new NamespacedKey(plugin, "test"), service.getKey()); } @Test - public void testTileEntities() { + @DisplayName("Test Tile Entity check") + void testTileEntities() { BlockDataService service = new BlockDataService(plugin, "test"); Assertions.assertFalse(service.isTileEntity(null)); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TextCustomTextureService.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TextCustomTextureService.java index 16daca7d5..44801d46f 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TextCustomTextureService.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TextCustomTextureService.java @@ -7,6 +7,7 @@ import org.bukkit.inventory.ItemStack; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -16,7 +17,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -public class TextCustomTextureService { +class TextCustomTextureService { private static SlimefunPlugin plugin; @@ -32,7 +33,8 @@ public class TextCustomTextureService { } @Test - public void testInitialization() { + @DisplayName("Test creating a new Custom Texture Service") + void testInitialization() { Config config = new Config("plugins/temporary"); CustomTextureService service = new CustomTextureService(config); Assertions.assertFalse(service.isActive()); @@ -51,7 +53,8 @@ public class TextCustomTextureService { } @Test - public void testSetTexture() { + @DisplayName("Test applying a custom item model") + void testSetTexture() { Config config = new Config("plugins/temporary"); CustomTextureService service = new CustomTextureService(config); SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "TEXTURE_TEST", new ItemStack(Material.LANTERN)); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/tasks/MockHazmatSuit.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/tasks/MockHazmatSuit.java new file mode 100644 index 000000000..72efc00b3 --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/tasks/MockHazmatSuit.java @@ -0,0 +1,35 @@ +package io.github.thebusybiscuit.slimefun4.testing.tests.tasks; + +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; + +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType; +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectiveArmor; +import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece; +import me.mrCookieSlime.Slimefun.Lists.RecipeType; +import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; + +class MockHazmatSuit extends SlimefunArmorPiece implements ProtectiveArmor { + + public MockHazmatSuit(Category category, SlimefunItemStack item) { + super(category, item, RecipeType.NULL, new ItemStack[9], new PotionEffect[0]); + } + + @Override + public ProtectionType[] getProtectionTypes() { + return new ProtectionType[] { ProtectionType.RADIATION }; + } + + @Override + public boolean isFullSetRequired() { + return false; + } + + @Override + public NamespacedKey getArmorSetId() { + return new NamespacedKey(getAddon().getJavaPlugin(), "mock_hazmat"); + } + +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/tasks/TestArmorTask.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/tasks/TestArmorTask.java new file mode 100644 index 000000000..6985c90c5 --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/tasks/TestArmorTask.java @@ -0,0 +1,104 @@ +package io.github.thebusybiscuit.slimefun4.testing.tests.tasks; + +import java.util.Arrays; +import java.util.Locale; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.ServerMock; +import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactivity; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.items.RadioactiveItem; +import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask; +import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; +import me.mrCookieSlime.Slimefun.Lists.RecipeType; +import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; + +class TestArmorTask { + + private static ServerMock server; + private static SlimefunPlugin plugin; + private static ArmorTask task; + + @BeforeAll + public static void load() { + server = MockBukkit.mock(); + plugin = MockBukkit.load(SlimefunPlugin.class); + task = new ArmorTask(false); + } + + @AfterAll + public static void unload() { + MockBukkit.unmock(); + } + + @Test + @DisplayName("Test Slimefun Armor Effects") + void testSlimefunArmor() throws InterruptedException { + Player player = server.addPlayer(); + TestUtilities.awaitProfile(player); + + // Setting the time to noon, to exclude the Solar Helmet check + player.getWorld().setTime(16000); + + PotionEffect[] effects = { new PotionEffect(PotionEffectType.SPEED, 50, 3), new PotionEffect(PotionEffectType.SATURATION, 128, 12) }; + + SlimefunItemStack helmet = new SlimefunItemStack("HELMET_FLEX", Material.IRON_HELMET, "&bSuper cool Helmet"); + SlimefunArmorPiece armor = new SlimefunArmorPiece(TestUtilities.getCategory(plugin, "armor_test"), helmet, RecipeType.NULL, new ItemStack[9], effects); + armor.register(plugin); + + player.getInventory().setHelmet(helmet.clone()); + player.getInventory().setChestplate(new ItemStack(Material.DIAMOND_CHESTPLATE)); + task.run(); + + // Check if all Potion Effects were applied + Assertions.assertTrue(player.getActivePotionEffects().containsAll(Arrays.asList(effects))); + } + + @ParameterizedTest + @DisplayName("Test Radiation and Hazmat Suits") + @ValueSource(booleans = { true, false }) + void testRadiactivity(boolean hazmat) throws InterruptedException { + Player player = server.addPlayer(); + TestUtilities.awaitProfile(player); + + // Setting the time to noon, to exclude the Solar Helmet check + player.getWorld().setTime(16000); + + Category category = TestUtilities.getCategory(plugin, "hazmat_suit_test"); + SlimefunItemStack item = new SlimefunItemStack("MOCK_URANIUM_" + String.valueOf(hazmat).toUpperCase(Locale.ROOT), Material.EMERALD, "&aHi, I am deadly"); + new RadioactiveItem(category, Radioactivity.VERY_DEADLY, item, RecipeType.NULL, new ItemStack[9]).register(plugin); + + player.getInventory().setItemInMainHand(item.clone()); + player.getInventory().setItemInOffHand(new ItemStack(Material.EMERALD_ORE)); + + if (hazmat) { + SlimefunItemStack chestplate = new SlimefunItemStack("MOCK_HAZMAT_SUIT", Material.LEATHER_CHESTPLATE, "&4Hazmat Prototype"); + MockHazmatSuit armor = new MockHazmatSuit(category, chestplate); + armor.register(plugin); + + player.getInventory().setChestplate(chestplate.clone()); + } + + task.run(); + + // Check if the Player is suffering from radiation + boolean radiation = player.getActivePotionEffects().containsAll(task.getRadiationEffects()); + Assertions.assertEquals(!hazmat, radiation); + } + +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestChatUtils.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestChatUtils.java index 0ff674bea..d99036f0c 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestChatUtils.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestChatUtils.java @@ -7,24 +7,24 @@ import org.junit.jupiter.api.Test; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; -public class TestChatUtils { +class TestChatUtils { @Test - public void testHumanize() { + void testHumanize() { String input = "TEST_STRING_COOL"; String expected = "Test String Cool"; Assertions.assertEquals(expected, ChatUtils.humanize(input)); } @Test - public void testChristmas() { + void testChristmas() { String input = "Tis the season"; String expected = ChatColors.color("&aT&ci&as&c &at&ch&ae&c &as&ce&aa&cs&ao&cn"); Assertions.assertEquals(expected, ChatUtils.christmas(input)); } @Test - public void testColorCodeRemoval() { + void testColorCodeRemoval() { String expected = "Hello world"; Assertions.assertEquals(expected, ChatUtils.removeColorCodes("&4&lHello &6world")); Assertions.assertEquals(expected, ChatUtils.removeColorCodes(ChatColor.GREEN + "Hello " + ChatColor.RED + "world")); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestHeadTextures.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestHeadTextures.java index 7952d410f..c320da673 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestHeadTextures.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestHeadTextures.java @@ -4,14 +4,16 @@ import java.util.HashSet; import java.util.Set; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; -public class TestHeadTextures { +class TestHeadTextures { @Test - public void testForDuplicates() { + @DisplayName("Test if the HeadTexture enum contains any duplicates") + void testForDuplicates() { Set textures = new HashSet<>(); for (HeadTexture head : HeadTexture.values()) { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestItemStackWrapper.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestItemStackWrapper.java index 0e85707a8..e58748a39 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestItemStackWrapper.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestItemStackWrapper.java @@ -1,10 +1,14 @@ package io.github.thebusybiscuit.slimefun4.testing.tests.utils; +import java.util.Arrays; +import java.util.List; + import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -13,7 +17,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; -public class TestItemStackWrapper { +class TestItemStackWrapper { @BeforeAll public static void load() { @@ -27,7 +31,8 @@ public class TestItemStackWrapper { } @Test - public void testEquality() { + @DisplayName("Test if an ItemStackWrappers can be compared properly (With ItemMeta)") + void testEqualityWithItemMeta() { ItemStack item = new CustomItem(Material.LAVA_BUCKET, "&4SuperHot.exe", "", "&6Hello"); ItemStackWrapper wrapper = new ItemStackWrapper(item); @@ -38,7 +43,20 @@ public class TestItemStackWrapper { } @Test - public void testImmutability() { + @DisplayName("Test if an ItemStackWrappers can be compared properly (No ItemMeta)") + void testEqualityWithoutItemMeta() { + ItemStack item = new ItemStack(Material.DIAMOND_AXE); + ItemStackWrapper wrapper = new ItemStackWrapper(item); + + Assertions.assertEquals(item.getType(), wrapper.getType()); + Assertions.assertEquals(item.hasItemMeta(), wrapper.hasItemMeta()); + Assertions.assertEquals(item.getItemMeta(), wrapper.getItemMeta()); + Assertions.assertTrue(SlimefunUtils.isItemSimilar(wrapper, item, true)); + } + + @Test + @DisplayName("Test if an ItemStackWrapper is immutable") + void testImmutability() { ItemStack item = new CustomItem(Material.LAVA_BUCKET, "&4SuperHot.exe", "", "&6Hello"); ItemStackWrapper wrapper = new ItemStackWrapper(item); @@ -51,4 +69,39 @@ public class TestItemStackWrapper { Assertions.assertThrows(UnsupportedOperationException.class, () -> wrapper.equals(wrapper)); } + @Test + @DisplayName("Test wrapping an ItemStack Array") + void testWrapArray() { + ItemStack[] items = { new ItemStack(Material.DIAMOND), null, new ItemStack(Material.EMERALD), new CustomItem(Material.REDSTONE, "&4Firey thing", "with lore :o") }; + ItemStackWrapper[] wrappers = ItemStackWrapper.wrapArray(items); + + Assertions.assertEquals(items.length, wrappers.length); + + for (int i = 0; i < items.length; i++) { + assertWrapped(items[i], wrappers[i]); + } + } + + @Test + @DisplayName("Test wrapping an ItemStack List") + void testWrapList() { + List items = Arrays.asList(new ItemStack(Material.DIAMOND), null, new ItemStack(Material.EMERALD), new CustomItem(Material.REDSTONE, "&4Firey thing", "with lore :o")); + List wrappers = ItemStackWrapper.wrapList(items); + + Assertions.assertEquals(items.size(), wrappers.size()); + + for (int i = 0; i < items.size(); i++) { + assertWrapped(items.get(i), wrappers.get(i)); + } + } + + private void assertWrapped(ItemStack expected, ItemStack actual) { + if (expected == null) { + Assertions.assertNull(actual); + } + else { + Assertions.assertTrue(actual instanceof ItemStackWrapper); + Assertions.assertTrue(SlimefunUtils.isItemSimilar(actual, expected, true)); + } + } } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestWikiResource.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestWikiResource.java index 2b4202be2..2ad9293ce 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestWikiResource.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestWikiResource.java @@ -8,15 +8,17 @@ import java.util.Map; import java.util.regex.Pattern; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import com.google.gson.JsonElement; import com.google.gson.JsonParser; -public class TestWikiResource { +class TestWikiResource { @Test - public void testWikiJson() throws IOException { + @DisplayName("Test wiki.json file format") + void testWikiJson() throws IOException { JsonParser parser = new JsonParser(); Pattern pattern = Pattern.compile("[A-Z_0-9]+");